X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_mem_pool.h;h=412d2c0a3b11be67d43c5e75f97a80d80bc3fb52;hb=3b841cc427adddeeb5b624d254587a45622d506d;hp=d5742b48009bf792dba7bfe6f7d187a655f75e83;hpb=48149581c10efff916dfad10f014b90837d531ea;p=vg.git diff --git a/vg_mem_pool.h b/vg_mem_pool.h index d5742b4..412d2c0 100644 --- a/vg_mem_pool.h +++ b/vg_mem_pool.h @@ -1,8 +1,9 @@ #ifndef VG_MEM_POOL_H #define VG_MEM_POOL_H -/* pool for loaded addons */ -#define VG_POOL_NIL 0xffff +#include "vg_mem.h" +#include "stddef.h" +#include "vg_stdint.h" typedef struct vg_pool vg_pool; typedef struct vg_pool_node vg_pool_node; @@ -18,62 +19,77 @@ struct vg_pool { size_t stride, offset; }; -static vg_pool_node *vg_pool_nodeptr ( vg_pool *pool, void *item ); -static void *vg_pool_item ( vg_pool *pool, u16 index ); +static vg_pool_node *vg_pool_nodeptr ( vg_pool *pool, u16 id ); +static void *vg_pool_item ( vg_pool *pool, u16 id ); static void vg_pool_init ( vg_pool *pool ); -static u16 addon_item_index ( vg_pool *pool, void *item ); -static void *vg_pool_lru ( vg_pool *pool ); -static void vg_pool_watch ( vg_pool *pool, void *item ); -static void vg_pool_unwatch ( vg_pool *pool, void *item ); +static u16 vg_pool_id ( vg_pool *pool, void *item ); +static u16 vg_pool_lru ( vg_pool *pool ); +static void vg_pool_watch ( vg_pool *pool, u16 id ); +static void vg_pool_unwatch ( vg_pool *pool, u16 id ); /* implementation * -------------------------------------------------------------------------- */ -static vg_pool_node *vg_pool_nodeptr( vg_pool *pool, void *item ){ - if( !item ) return NULL; - else return item + pool->offset; +static vg_pool_node *vg_pool_nodeptr( vg_pool *pool, u16 id ){ + if( !id ) return NULL; + else { + return pool->buffer + (pool->stride*(id-1)) + pool->offset; + } } -static void *vg_pool_item( vg_pool *pool, u16 index ){ - if( index == VG_POOL_NIL ) return NULL; - else return pool->buffer + pool->stride*(size_t)index; +static void *vg_pool_item( vg_pool *pool, u16 id ){ + if( (id == 0) || (id > pool->count) ) + return NULL; + + return pool->buffer + pool->stride*(size_t)(id-1); } static void vg_pool_init( vg_pool *pool ){ - pool->head = 0; - pool->tail = pool->count -1; - for( i32 ib=0; ib < pool->count; ib++ ){ - void *vb = vg_pool_item( pool, ib ); - vg_pool_node *nb = vg_pool_nodeptr( pool, vb ); - - i32 ia = ib-1, ic = ib+1; - nb->l = ia>=0? ia: VG_POOL_NIL, - nb->r = iccount? ic: VG_POOL_NIL; + pool->head = 1; + pool->tail = pool->count; + for( u16 ib=1; ib <= pool->count; ib++ ){ + vg_pool_node *nb = vg_pool_nodeptr( pool, ib ); + + u16 ia = ib-1, ic = ib+1; + nb->l = ia; + nb->r = ic<=pool->count? ic: 0; nb->ref_count = 0; } } -static u16 addon_item_index( vg_pool *pool, void *item ){ - return (item - pool->buffer) / pool->stride; +static u16 vg_pool_id( vg_pool *pool, void *item ){ + return ((item - pool->buffer) / pool->stride) + 1; } -static void *vg_pool_lru( vg_pool *pool ){ - u16 head = pool->head; - if( head == VG_POOL_NIL ) return NULL; +static void vg_pool_unlink( vg_pool *pool, u16 id ){ + vg_pool_node *node = vg_pool_nodeptr( pool, id ); + vg_pool_node *l = vg_pool_nodeptr( pool, node->l ), + *r = vg_pool_nodeptr( pool, node->r ); - void *item = vg_pool_item( pool, head ); - vg_pool_node *node = vg_pool_nodeptr( pool, item ); + if( pool->head == id ) pool->head = node->r; + if( pool->tail == id ) pool->tail = node->l; + + if( l ) l->r = node->r; + if( r ) r->l = node->l; - if( pool->head == pool->tail ) pool->tail = VG_POOL_NIL; - pool->head = node->r; + node->r = 0; + node->l = 0; +} - node->l = VG_POOL_NIL; - node->r = VG_POOL_NIL; - return item; +static u16 vg_pool_lru( vg_pool *pool ){ + u16 head = pool->head; + if( !head ) return 0; + + vg_pool_unlink( pool, head ); + return head; } -static void vg_pool_watch( vg_pool *pool, void *item ){ - vg_pool_node *node = vg_pool_nodeptr( pool, item ); +static void vg_pool_watch( vg_pool *pool, u16 id ){ + vg_pool_node *node = vg_pool_nodeptr( pool, id ); + + if( !node->ref_count ){ + vg_pool_unlink( pool, id ); + } if( node->ref_count >= 128 ) vg_fatal_error( "pool watch missmatch (limit is 128)\n" ); @@ -82,24 +98,21 @@ static void vg_pool_watch( vg_pool *pool, void *item ){ } /* if after this no more watches, places back into the volatile list */ -static void vg_pool_unwatch( vg_pool *pool, void *item ){ - vg_pool_node *node = vg_pool_nodeptr( pool, item ); +static void vg_pool_unwatch( vg_pool *pool, u16 id ){ + vg_pool_node *node = vg_pool_nodeptr( pool, id ); if( node->ref_count == 0 ) vg_fatal_error( "pool unwatch missmatch (no watchers)\n" ); node->ref_count --; if( !node->ref_count ){ - void *item_head = vg_pool_item( pool, pool->head ), - *item_tail = vg_pool_item( pool, pool->tail ); - vg_pool_node *head = vg_pool_nodeptr( pool, item_head ), - *tail = vg_pool_nodeptr( pool, item_tail ); + vg_pool_node *head = vg_pool_nodeptr( pool, pool->head ), + *tail = vg_pool_nodeptr( pool, pool->tail ); - u16 index = addon_item_index( pool, item ); - if( tail ) tail->r = index; + if( tail ) tail->r = id; node->l = pool->tail; - pool->tail = index; - if( !head ) pool->head = index; + pool->tail = id; + if( !head ) pool->head = id; } }