VPP: Fix Coverity alert on unitialized vpp_kernels
[platform/upstream/libva-intel-driver.git] / src / object_heap.c
1 /*
2  * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  * 
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  * 
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "object_heap.h"
26
27 #include "assert.h"
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31
32 #define ASSERT  assert
33
34 #define LAST_FREE       -1
35 #define ALLOCATED       -2
36
37 /*
38  * Expands the heap
39  * Return 0 on success, -1 on error
40  */
41 static int object_heap_expand( object_heap_p heap )
42 {
43     int i;
44     void *new_heap_index;
45     int next_free;
46     int new_heap_size = heap->heap_size + heap->heap_increment;
47     int bucket_index = new_heap_size / heap->heap_increment - 1;
48
49     if (bucket_index >= heap->num_buckets) {
50         int new_num_buckets = heap->num_buckets + 8;
51         void **new_bucket;
52
53         new_bucket = realloc(heap->bucket, new_num_buckets * sizeof(void *));
54         if (NULL == new_bucket) {
55             return -1;
56         }
57
58         heap->num_buckets = new_num_buckets;
59         heap->bucket = new_bucket;
60     }
61
62     new_heap_index = (void *) malloc( heap->heap_increment * heap->object_size );
63     if ( NULL == new_heap_index )
64     {
65         return -1; /* Out of memory */
66     }
67
68     heap->bucket[bucket_index] = new_heap_index;
69     next_free = heap->next_free;
70     for(i = new_heap_size; i-- > heap->heap_size; )
71     {
72         object_base_p obj = (object_base_p) (new_heap_index + (i - heap->heap_size) * heap->object_size);
73         obj->id = i + heap->id_offset;
74         obj->next_free = next_free;
75         next_free = i;
76     }
77     heap->next_free = next_free;
78     heap->heap_size = new_heap_size;
79     return 0; /* Success */
80 }
81
82 /*
83  * Return 0 on success, -1 on error
84  */
85 int object_heap_init( object_heap_p heap, int object_size, int id_offset)
86 {
87     heap->object_size = object_size;
88     heap->id_offset = id_offset & OBJECT_HEAP_OFFSET_MASK;
89     heap->heap_size = 0;
90     heap->heap_increment = 16;
91     heap->next_free = LAST_FREE;
92     heap->num_buckets = 0;
93     heap->bucket = NULL;
94
95     if (object_heap_expand(heap) == 0) {
96         ASSERT(heap->heap_size);
97         _i965InitMutex(&heap->mutex);
98         return 0;
99     } else {
100         ASSERT(!heap->heap_size);
101         ASSERT(!heap->bucket || !heap->bucket[0]);
102
103         free(heap->bucket);
104
105         return -1;
106     }
107 }
108
109 /*
110  * Allocates an object
111  * Returns the object ID on success, returns -1 on error
112  */
113 int object_heap_allocate( object_heap_p heap )
114 {
115     object_base_p obj;
116     int bucket_index, obj_index;
117
118     _i965LockMutex(&heap->mutex);
119     if ( LAST_FREE == heap->next_free )
120     {
121         if( -1 == object_heap_expand( heap ) )
122         {
123             _i965UnlockMutex(&heap->mutex);
124             return -1; /* Out of memory */
125         }
126     }
127     ASSERT( heap->next_free >= 0 );
128
129     bucket_index = heap->next_free / heap->heap_increment;
130     obj_index = heap->next_free % heap->heap_increment;
131
132     obj = (object_base_p) (heap->bucket[bucket_index] + obj_index * heap->object_size);
133     heap->next_free = obj->next_free;
134     _i965UnlockMutex(&heap->mutex);
135     
136     obj->next_free = ALLOCATED;
137     return obj->id;
138 }
139
140 /*
141  * Lookup an object by object ID
142  * Returns a pointer to the object on success, returns NULL on error
143  */
144 object_base_p object_heap_lookup( object_heap_p heap, int id )
145 {
146     object_base_p obj;
147     int bucket_index, obj_index;
148
149     _i965LockMutex(&heap->mutex);
150     if ( (id < heap->id_offset) || (id > (heap->heap_size+heap->id_offset)) )
151     {
152         _i965UnlockMutex(&heap->mutex);
153         return NULL;
154     }
155     id &= OBJECT_HEAP_ID_MASK;
156     bucket_index = id / heap->heap_increment;
157     obj_index = id % heap->heap_increment;
158     obj = (object_base_p) (heap->bucket[bucket_index] + obj_index * heap->object_size);
159     _i965UnlockMutex(&heap->mutex);
160
161         /* Check if the object has in fact been allocated */
162         if ( obj->next_free != ALLOCATED )
163     {
164         return NULL;
165     }
166     return obj;
167 }
168
169 /*
170  * Iterate over all objects in the heap.
171  * Returns a pointer to the first object on the heap, returns NULL if heap is empty.
172  */
173 object_base_p object_heap_first( object_heap_p heap, object_heap_iterator *iter )
174 {
175     *iter = -1;
176     return object_heap_next( heap, iter );
177 }
178
179 /*
180  * Iterate over all objects in the heap.
181  * Returns a pointer to the next object on the heap, returns NULL if heap is empty.
182  */
183 object_base_p object_heap_next( object_heap_p heap, object_heap_iterator *iter )
184 {
185     object_base_p obj;
186     int i = *iter + 1;
187     int bucket_index, obj_index;
188
189     _i965LockMutex(&heap->mutex);
190     while ( i < heap->heap_size)
191     {
192         bucket_index = i / heap->heap_increment;
193         obj_index = i % heap->heap_increment;
194
195         obj = (object_base_p) (heap->bucket[bucket_index] + obj_index * heap->object_size);
196         if (obj->next_free == ALLOCATED)
197         {
198             _i965UnlockMutex(&heap->mutex);
199             *iter = i;
200             return obj;
201         }
202         i++;
203     }
204     _i965UnlockMutex(&heap->mutex);
205     *iter = i;
206     return NULL;
207 }
208
209
210
211 /*
212  * Frees an object
213  */
214 void object_heap_free( object_heap_p heap, object_base_p obj )
215 {
216     /* Don't complain about NULL pointers */
217     if (NULL != obj)
218     {
219         /* Check if the object has in fact been allocated */
220         ASSERT( obj->next_free == ALLOCATED );
221     
222         _i965LockMutex(&heap->mutex);
223         obj->next_free = heap->next_free;
224         heap->next_free = obj->id & OBJECT_HEAP_ID_MASK;
225         _i965UnlockMutex(&heap->mutex);
226     }
227 }
228
229 /*
230  * Destroys a heap, the heap must be empty.
231  */
232 void object_heap_destroy( object_heap_p heap )
233 {
234     object_base_p obj;
235     int i;
236     int bucket_index, obj_index;
237
238     if (heap->heap_size) {
239         _i965DestroyMutex(&heap->mutex);
240
241         /* Check if heap is empty */
242         for (i = 0; i < heap->heap_size; i++)
243         {
244             /* Check if object is not still allocated */
245             bucket_index = i / heap->heap_increment;
246             obj_index = i % heap->heap_increment;
247             obj = (object_base_p) (heap->bucket[bucket_index] + obj_index * heap->object_size);
248             ASSERT( obj->next_free != ALLOCATED );
249         }
250
251         for (i = 0; i < heap->heap_size / heap->heap_increment; i++) {
252             free(heap->bucket[i]);
253         }
254
255         free(heap->bucket);
256     }
257
258     heap->bucket = NULL;
259     heap->heap_size = 0;
260     heap->next_free = LAST_FREE;
261 }