Fixed issues reported by Klockwork
[platform/upstream/libva.git] / dummy_drv_video / 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
31 #define ASSERT  assert
32
33 #define LAST_FREE       -1
34 #define ALLOCATED       -2
35
36 /*
37  * Expands the heap
38  * Return 0 on success, -1 on error
39  */
40 static int object_heap_expand( object_heap_p heap )
41 {
42     int i;
43     void *new_heap_index;
44     int next_free;
45     int new_heap_size = heap->heap_size + heap->heap_increment;
46     
47     new_heap_index = (void *) realloc( heap->heap_index, new_heap_size * heap->object_size );
48     if ( NULL == new_heap_index )
49     {
50         return -1; /* Out of memory */
51     }
52     heap->heap_index = new_heap_index;
53     next_free = heap->next_free;
54     for(i = new_heap_size; i-- > heap->heap_size; )
55     {
56         object_base_p obj = (object_base_p) (heap->heap_index + i * heap->object_size);
57         obj->id = i + heap->id_offset;
58         obj->next_free = next_free;
59         next_free = i;
60     }
61     heap->next_free = next_free;
62     heap->heap_size = new_heap_size;
63     return 0; /* Success */
64 }
65
66 /*
67  * Return 0 on success, -1 on error
68  */
69 int object_heap_init( object_heap_p heap, int object_size, int id_offset)
70 {
71     heap->object_size = object_size;
72     heap->id_offset = id_offset & OBJECT_HEAP_OFFSET_MASK;
73     heap->heap_size = 0;
74     heap->heap_increment = 16;
75     heap->heap_index = NULL;
76     heap->next_free = LAST_FREE;
77     return object_heap_expand(heap);
78 }
79
80 /*
81  * Allocates an object
82  * Returns the object ID on success, returns -1 on error
83  */
84 int object_heap_allocate( object_heap_p heap )
85 {
86     object_base_p obj;
87     if ( LAST_FREE == heap->next_free )
88     {
89         if( -1 == object_heap_expand( heap ) )
90         {
91             return -1; /* Out of memory */
92         }
93     }
94     ASSERT( heap->next_free >= 0 );
95     
96     obj = (object_base_p) (heap->heap_index + heap->next_free * heap->object_size);
97     heap->next_free = obj->next_free;
98     obj->next_free = ALLOCATED;
99     return obj->id;
100 }
101
102 /*
103  * Lookup an object by object ID
104  * Returns a pointer to the object on success, returns NULL on error
105  */
106 object_base_p object_heap_lookup( object_heap_p heap, int id )
107 {
108     object_base_p obj;
109     if ( (id < heap->id_offset) || (id > (heap->heap_size+heap->id_offset)) )
110     {
111         return NULL;
112     }
113     id &= OBJECT_HEAP_ID_MASK;
114     obj = (object_base_p) (heap->heap_index + id * heap->object_size);
115
116         /* Check if the object has in fact been allocated */
117         if ( obj->next_free != ALLOCATED )
118     {
119         return NULL;
120     }
121     return obj;
122 }
123
124 /*
125  * Iterate over all objects in the heap.
126  * Returns a pointer to the first object on the heap, returns NULL if heap is empty.
127  */
128 object_base_p object_heap_first( object_heap_p heap, object_heap_iterator *iter )
129 {
130     *iter = -1;
131     return object_heap_next( heap, iter );
132 }
133
134 /*
135  * Iterate over all objects in the heap.
136  * Returns a pointer to the next object on the heap, returns NULL if heap is empty.
137  */
138 object_base_p object_heap_next( object_heap_p heap, object_heap_iterator *iter )
139 {
140     object_base_p obj;
141     int i = *iter + 1;
142     while ( i < heap->heap_size)
143     {
144         obj = (object_base_p) (heap->heap_index + i * heap->object_size);
145         if (obj->next_free == ALLOCATED)
146         {
147             *iter = i;
148             return obj;
149         }
150         i++;
151     }
152     *iter = i;
153     return NULL;
154 }
155
156
157
158 /*
159  * Frees an object
160  */
161 void object_heap_free( object_heap_p heap, object_base_p obj )
162 {
163     /* Don't complain about NULL pointers */
164     if (NULL != obj)
165     {
166         /* Check if the object has in fact been allocated */
167         ASSERT( obj->next_free == ALLOCATED );
168     
169         obj->next_free = heap->next_free;
170         heap->next_free = obj->id & OBJECT_HEAP_ID_MASK;
171     }
172 }
173
174 /*
175  * Destroys a heap, the heap must be empty.
176  */
177 void object_heap_destroy( object_heap_p heap )
178 {
179     object_base_p obj;
180     int i;
181     /* Check if heap is empty */
182     for (i = 0; i < heap->heap_size; i++)
183     {
184         /* Check if object is not still allocated */
185         obj = (object_base_p) (heap->heap_index + i * heap->object_size);
186         ASSERT( obj->next_free != ALLOCATED );
187     }
188     free(heap->heap_index);
189     heap->heap_size = 0;
190     heap->heap_index = NULL;
191     heap->next_free = LAST_FREE;
192 }