4 /* pool for loaded addons */
5 #define VG_POOL_NIL 0xffff
7 typedef struct vg_pool vg_pool
;
8 typedef struct vg_pool_node vg_pool_node
;
10 /* this goes in your structures */
16 void *buffer
; /* array which holds the real data */
17 u16 count
, head
, tail
;
18 size_t stride
, offset
;
21 static vg_pool_node
*vg_pool_nodeptr ( vg_pool
*pool
, void *item
);
22 static void *vg_pool_item ( vg_pool
*pool
, u16 index
);
23 static void vg_pool_init ( vg_pool
*pool
);
24 static u16
addon_item_index ( vg_pool
*pool
, void *item
);
25 static void *vg_pool_lru ( vg_pool
*pool
);
26 static void vg_pool_watch ( vg_pool
*pool
, void *item
);
27 static void vg_pool_unwatch ( vg_pool
*pool
, void *item
);
30 * -------------------------------------------------------------------------- */
32 static vg_pool_node
*vg_pool_nodeptr( vg_pool
*pool
, void *item
){
33 if( !item
) return NULL
;
34 else return item
+ pool
->offset
;
37 static void *vg_pool_item( vg_pool
*pool
, u16 index
){
38 if( index
== VG_POOL_NIL
) return NULL
;
39 else return pool
->buffer
+ pool
->stride
*(size_t)index
;
42 static void vg_pool_init( vg_pool
*pool
){
44 pool
->tail
= pool
->count
-1;
45 for( i32 ib
=0; ib
< pool
->count
; ib
++ ){
46 void *vb
= vg_pool_item( pool
, ib
);
47 vg_pool_node
*nb
= vg_pool_nodeptr( pool
, vb
);
49 i32 ia
= ib
-1, ic
= ib
+1;
50 nb
->l
= ia
>=0? ia
: VG_POOL_NIL
,
51 nb
->r
= ic
<pool
->count
? ic
: VG_POOL_NIL
;
56 static u16
addon_item_index( vg_pool
*pool
, void *item
){
57 return (item
- pool
->buffer
) / pool
->stride
;
60 static void *vg_pool_lru( vg_pool
*pool
){
61 u16 head
= pool
->head
;
62 if( head
== VG_POOL_NIL
) return NULL
;
64 void *item
= vg_pool_item( pool
, head
);
65 vg_pool_node
*node
= vg_pool_nodeptr( pool
, item
);
67 if( pool
->head
== pool
->tail
) pool
->tail
= VG_POOL_NIL
;
70 node
->l
= VG_POOL_NIL
;
71 node
->r
= VG_POOL_NIL
;
75 static void vg_pool_watch( vg_pool
*pool
, void *item
){
76 vg_pool_node
*node
= vg_pool_nodeptr( pool
, item
);
78 if( node
->ref_count
>= 128 )
79 vg_fatal_error( "pool watch missmatch (limit is 128)\n" );
84 /* if after this no more watches, places back into the volatile list */
85 static void vg_pool_unwatch( vg_pool
*pool
, void *item
){
86 vg_pool_node
*node
= vg_pool_nodeptr( pool
, item
);
88 if( node
->ref_count
== 0 )
89 vg_fatal_error( "pool unwatch missmatch (no watchers)\n" );
92 if( !node
->ref_count
){
93 void *item_head
= vg_pool_item( pool
, pool
->head
),
94 *item_tail
= vg_pool_item( pool
, pool
->tail
);
95 vg_pool_node
*head
= vg_pool_nodeptr( pool
, item_head
),
96 *tail
= vg_pool_nodeptr( pool
, item_tail
);
98 u16 index
= addon_item_index( pool
, item
);
99 if( tail
) tail
->r
= index
;
100 node
->l
= pool
->tail
;
102 if( !head
) pool
->head
= index
;
106 #endif /* VG_MEM_POOL_H */