bad char
[vg.git] / vg_mem_pool.c
1 #include "vg_platform.h"
2 #include "vg_mem.h"
3 #include "vg_mem_pool.h"
4 #include <stddef.h>
5
6 /* implementation
7 * -------------------------------------------------------------------------- */
8
9 vg_pool_node *vg_pool_nodeptr( vg_pool *pool, u16 id ){
10 if( !id ) return NULL;
11 else {
12 return pool->buffer + (pool->stride*(id-1)) + pool->offset;
13 }
14 }
15
16 void *vg_pool_item( vg_pool *pool, u16 id )
17 {
18 if( (id == 0) || (id > pool->count) )
19 return NULL;
20
21 return pool->buffer + pool->stride*(size_t)(id-1);
22 }
23
24 void vg_pool_init( vg_pool *pool )
25 {
26 pool->head = 1;
27 pool->tail = pool->count;
28 for( u16 ib=1; ib <= pool->count; ib++ ){
29 vg_pool_node *nb = vg_pool_nodeptr( pool, ib );
30
31 u16 ia = ib-1, ic = ib+1;
32 nb->l = ia;
33 nb->r = ic<=pool->count? ic: 0;
34 nb->ref_count = 0;
35 }
36 }
37
38 u16 vg_pool_id( vg_pool *pool, void *item )
39 {
40 return ((item - pool->buffer) / pool->stride) + 1;
41 }
42
43 static void vg_pool_unlink( vg_pool *pool, u16 id )
44 {
45 vg_pool_node *node = vg_pool_nodeptr( pool, id );
46 vg_pool_node *l = vg_pool_nodeptr( pool, node->l ),
47 *r = vg_pool_nodeptr( pool, node->r );
48
49 if( pool->head == id ) pool->head = node->r;
50 if( pool->tail == id ) pool->tail = node->l;
51
52 if( l ) l->r = node->r;
53 if( r ) r->l = node->l;
54
55 node->r = 0;
56 node->l = 0;
57 }
58
59 u16 vg_pool_lru( vg_pool *pool )
60 {
61 u16 head = pool->head;
62 if( !head ) return 0;
63
64 vg_pool_unlink( pool, head );
65 return head;
66 }
67
68 void vg_pool_watch( vg_pool *pool, u16 id )
69 {
70 vg_pool_node *node = vg_pool_nodeptr( pool, id );
71
72 if( !node->ref_count ){
73 vg_pool_unlink( pool, id );
74 }
75
76 if( node->ref_count == 0xffff )
77 vg_fatal_error( "pool watch missmatch (limit is 128)\n" );
78
79 node->ref_count ++;
80 }
81
82 /* if after this no more watches, places back into the volatile list */
83 void vg_pool_unwatch( vg_pool *pool, u16 id )
84 {
85 vg_pool_node *node = vg_pool_nodeptr( pool, id );
86
87 if( node->ref_count == 0 )
88 vg_fatal_error( "pool unwatch missmatch (no watchers)\n" );
89
90 node->ref_count --;
91 if( !node->ref_count ){
92 vg_pool_node *head = vg_pool_nodeptr( pool, pool->head ),
93 *tail = vg_pool_nodeptr( pool, pool->tail );
94
95 if( tail ) tail->r = id;
96 node->l = pool->tail;
97 pool->tail = id;
98 if( !head ) pool->head = id;
99 }
100 }