8 typedef struct vg_pool vg_pool
;
9 typedef struct vg_pool_node vg_pool_node
;
11 /* this goes in your structures */
17 void *buffer
; /* array which holds the real data */
18 u16 count
, head
, tail
;
19 size_t stride
, offset
;
22 static vg_pool_node
*vg_pool_nodeptr ( vg_pool
*pool
, u16 id
);
23 static void *vg_pool_item ( vg_pool
*pool
, u16 id
);
24 static void vg_pool_init ( vg_pool
*pool
);
25 static u16
vg_pool_id ( vg_pool
*pool
, void *item
);
26 static u16
vg_pool_lru ( vg_pool
*pool
);
27 static void vg_pool_watch ( vg_pool
*pool
, u16 id
);
28 static void vg_pool_unwatch ( vg_pool
*pool
, u16 id
);
31 * -------------------------------------------------------------------------- */
33 static vg_pool_node
*vg_pool_nodeptr( vg_pool
*pool
, u16 id
){
34 if( !id
) return NULL
;
36 return pool
->buffer
+ (pool
->stride
*(id
-1)) + pool
->offset
;
40 static void *vg_pool_item( vg_pool
*pool
, u16 id
){
41 if( (id
== 0) || (id
> pool
->count
) )
44 return pool
->buffer
+ pool
->stride
*(size_t)(id
-1);
47 static void vg_pool_init( vg_pool
*pool
){
49 pool
->tail
= pool
->count
;
50 for( u16 ib
=1; ib
<= pool
->count
; ib
++ ){
51 vg_pool_node
*nb
= vg_pool_nodeptr( pool
, ib
);
53 u16 ia
= ib
-1, ic
= ib
+1;
55 nb
->r
= ic
<=pool
->count
? ic
: 0;
60 static u16
vg_pool_id( vg_pool
*pool
, void *item
){
61 return ((item
- pool
->buffer
) / pool
->stride
) + 1;
64 static void vg_pool_unlink( vg_pool
*pool
, u16 id
){
65 vg_pool_node
*node
= vg_pool_nodeptr( pool
, id
);
66 vg_pool_node
*l
= vg_pool_nodeptr( pool
, node
->l
),
67 *r
= vg_pool_nodeptr( pool
, node
->r
);
69 if( pool
->head
== id
) pool
->head
= node
->r
;
70 if( pool
->tail
== id
) pool
->tail
= node
->l
;
72 if( l
) l
->r
= node
->r
;
73 if( r
) r
->l
= node
->l
;
79 static u16
vg_pool_lru( vg_pool
*pool
){
80 u16 head
= pool
->head
;
83 vg_pool_unlink( pool
, head
);
87 static void vg_pool_watch( vg_pool
*pool
, u16 id
){
88 vg_pool_node
*node
= vg_pool_nodeptr( pool
, id
);
90 if( !node
->ref_count
){
91 vg_pool_unlink( pool
, id
);
94 if( node
->ref_count
>= 128 )
95 vg_fatal_error( "pool watch missmatch (limit is 128)\n" );
100 /* if after this no more watches, places back into the volatile list */
101 static void vg_pool_unwatch( vg_pool
*pool
, u16 id
){
102 vg_pool_node
*node
= vg_pool_nodeptr( pool
, id
);
104 if( node
->ref_count
== 0 )
105 vg_fatal_error( "pool unwatch missmatch (no watchers)\n" );
108 if( !node
->ref_count
){
109 vg_pool_node
*head
= vg_pool_nodeptr( pool
, pool
->head
),
110 *tail
= vg_pool_nodeptr( pool
, pool
->tail
);
112 if( tail
) tail
->r
= id
;
113 node
->l
= pool
->tail
;
115 if( !head
) pool
->head
= id
;
119 #endif /* VG_MEM_POOL_H */