6 #include "vg/vg_stdint.h"
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
) return NULL
;
42 else return pool
->buffer
+ pool
->stride
*(size_t)(id
-1);
45 static void vg_pool_init( vg_pool
*pool
){
47 pool
->tail
= pool
->count
;
48 for( u16 ib
=1; ib
<= pool
->count
; ib
++ ){
49 vg_pool_node
*nb
= vg_pool_nodeptr( pool
, ib
);
51 u16 ia
= ib
-1, ic
= ib
+1;
53 nb
->r
= ic
<=pool
->count
? ic
: 0;
58 static u16
vg_pool_id( vg_pool
*pool
, void *item
){
59 return ((item
- pool
->buffer
) / pool
->stride
) + 1;
62 static void vg_pool_unlink( vg_pool
*pool
, u16 id
){
63 vg_pool_node
*node
= vg_pool_nodeptr( pool
, id
);
64 vg_pool_node
*l
= vg_pool_nodeptr( pool
, node
->l
),
65 *r
= vg_pool_nodeptr( pool
, node
->r
);
67 if( pool
->head
== id
) pool
->head
= node
->r
;
68 if( pool
->tail
== id
) pool
->tail
= node
->l
;
70 if( l
) l
->r
= node
->r
;
71 if( r
) r
->l
= node
->l
;
77 static u16
vg_pool_lru( vg_pool
*pool
){
78 u16 head
= pool
->head
;
81 vg_pool_unlink( pool
, head
);
85 static void vg_pool_watch( vg_pool
*pool
, u16 id
){
86 vg_pool_node
*node
= vg_pool_nodeptr( pool
, id
);
88 if( !node
->ref_count
){
89 vg_pool_unlink( pool
, id
);
92 if( node
->ref_count
>= 128 )
93 vg_fatal_error( "pool watch missmatch (limit is 128)\n" );
98 /* if after this no more watches, places back into the volatile list */
99 static void vg_pool_unwatch( vg_pool
*pool
, u16 id
){
100 vg_pool_node
*node
= vg_pool_nodeptr( pool
, id
);
102 if( node
->ref_count
== 0 )
103 vg_fatal_error( "pool unwatch missmatch (no watchers)\n" );
106 if( !node
->ref_count
){
107 vg_pool_node
*head
= vg_pool_nodeptr( pool
, pool
->head
),
108 *tail
= vg_pool_nodeptr( pool
, pool
->tail
);
110 if( tail
) tail
->r
= id
;
111 node
->l
= pool
->tail
;
113 if( !head
) pool
->head
= id
;
117 #endif /* VG_MEM_POOL_H */