}
}
+/* is thread safe */
void *vg_pool_item( vg_pool *pool, u16 id )
{
if( (id == 0) || (id > pool->count) )
}
/* if after this no more watches, places back into the volatile list */
-void vg_pool_unwatch( vg_pool *pool, u16 id )
+bool vg_pool_unwatch( vg_pool *pool, u16 id )
{
vg_pool_node *node = vg_pool_nodeptr( pool, id );
vg_pool_node *head = vg_pool_nodeptr( pool, pool->head ),
*tail = vg_pool_nodeptr( pool, pool->tail );
- if( tail ) tail->r = id;
+ if( tail )
+ tail->r = id;
node->l = pool->tail;
pool->tail = id;
- if( !head ) pool->head = id;
+ if( !head )
+ pool->head = id;
+ return 1;
}
+ else return 0;
}
#include <stddef.h>
#include <string.h>
+void vg_queue_memcpy( vg_queue *q, void *dst, u32 start, u32 size )
+{
+ if( start + size > q->size )
+ {
+ u32 r0 = q->size - start;
+ memcpy( dst, q->buffer + start, r0 );
+ memcpy( dst+r0, q->buffer, size-r0 );
+ }
+ else
+ memcpy( dst, q->buffer + start, size );
+}
+
/*
* Copy q1 to q2, and reorganize the memory to correct for q2's new size
*/
void vg_queue_copy_upgrade( vg_queue *q1, vg_queue *q2 )
{
- VG_ASSERT( q2->size >= q1->size );
-
if( q1->allocation_count == 0 )
{
q2->head_offset = 0;
u32 end = q1->head_offset + head->alloc_size,
start = q1->tail_offset;
+ q2->y0 = start;
q2->allocation_count = q1->allocation_count;
q2->tail_offset = 0;
if( start < end )
{
u32 r0 = end-start;
+ VG_ASSERT( q2->size >= r0 );
memcpy( q2->buffer, q1->buffer+start, r0 );
q2->head_offset = r0 - head->alloc_size;
+ q2->z0 = r0;
}
else
{
u32 r0 = q1->size - start;
+ VG_ASSERT( q2->size >= (r0+end) );
memcpy( q2->buffer, q1->buffer+start, r0 );
memcpy( q2->buffer + r0, q1->buffer, end );
q2->head_offset = r0 + end - head->alloc_size;
+ q2->z0 = r0;
}
}
+u32 vg_queue_offset_upgrade( vg_queue *q, u32 offset )
+{
+ if( offset > q->y0 ) return offset - q->y0;
+ else return offset + q->z0;
+}
+
void *vg_queue_data( vg_queue *q, u32 offset )
{
vg_queue_item *item = q->buffer + offset;
void *vg_queue_tail_data( vg_queue *q )
{
- if( q->allocation_count )
- {
- return vg_queue_data( q, q->tail_offset );
- }
- else
- return NULL;
+ if( q->allocation_count ) return vg_queue_data( q, q->tail_offset );
+ else return NULL;
}
/*
if( total > q->size )
return NULL;
+ u32 prev_size = 0;
u32 new_item_offset;
if( q->allocation_count )
{
return NULL;
}
}
+
+ prev_size = head->alloc_size;
}
else
{
vg_queue_item *item = (vg_queue_item *)(q->buffer + new_item_offset);
memset( item, 0, sizeof(vg_queue_item) );
item->alloc_size = total;
- item->size = size;
+ item->prev_size = prev_size;
q->head_offset = new_item_offset;
q->allocation_count ++;
VG_ASSERT( q->allocation_count );
q->allocation_count --;
- if( q->head_offset == q->tail_offset )
+ if( q->allocation_count == 0 )
{
q->head_offset = 0;
q->tail_offset = 0;
start = 0;
q->tail_offset = start;
+
+ tail = q->buffer + q->tail_offset;
+ tail->prev_size = 0;
+}
+
+bool vg_queue_previous( vg_queue *q, u32 item_id, u32 *out_prev )
+{
+ vg_queue_item *item = q->buffer + item_id;
+ if( item_id != q->tail_offset )
+ {
+ if( item_id == 0 ) *out_prev = q->size - item->prev_size;
+ else *out_prev = item_id - item->prev_size;
+ return 1;
+ }
+ else return 0;
+}
+
+u32 vg_queue_item_size( vg_queue *q, u32 item_id )
+{
+ vg_queue_item *item = q->buffer + item_id;
+ return item->alloc_size;
+}
+
+bool vg_queue_next( vg_queue *q, u32 item_id, u32 *out_next )
+{
+ if( item_id != q->head_offset )
+ {
+ vg_queue_item *item = q->buffer + item_id;
+ if( item_id + item->alloc_size == q->size ) *out_next = 0;
+ else *out_next = item_id + item->alloc_size;
+ return 1;
+ }
+ else return 0;
}
u32 vg_queue_usage( vg_queue *q )
struct vg_queue_item
{
- u32 alloc_size,size;
+ u32 alloc_size,prev_size;
u8 data[];
};
u32 size;
u32 head_offset, tail_offset;
u32 allocation_count;
+ u32 y0, z0;
};
void *vg_queue_alloc( vg_queue *q, u32 size, u32 *out_offset );
void *vg_queue_data( vg_queue *q, u32 offset );
void *vg_queue_tail_data( vg_queue *q );
+/* warning: this is not the size but the allocation size (may be padded) */
+u32 vg_queue_item_size( vg_queue *q, u32 item_id );
+bool vg_queue_next( vg_queue *q, u32 item_id, u32 *out_next );
+bool vg_queue_previous( vg_queue *q, u32 item_id, u32 *out_prev );
void vg_queue_pop( vg_queue *q );
void vg_queue_copy_upgrade( vg_queue *q1, vg_queue *q2 );
+u32 vg_queue_offset_upgrade( vg_queue *q, u32 offset );
+void vg_queue_memcpy( vg_queue *q, void *dst, u32 start, u32 size );
u32 vg_queue_usage( vg_queue *q );