From: hgn Date: Thu, 2 Oct 2025 15:51:50 +0000 (+0000) Subject: update queue X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=4caec3ac0234620f01e33a99642c046928da3914;p=vg.git update queue --- diff --git a/include/common_api.h b/include/common_api.h index 61a0b11..3abb033 100644 --- a/include/common_api.h +++ b/include/common_api.h @@ -32,6 +32,10 @@ typedef unsigned char bool; #define i64_MAX 0x7FFFFFFFFFFFFFFF #define u64_MAX 0xFFFFFFFFFFFFFFFF +#define PAD_TO_4( X ) (((u32)X+0x3) & ~(u32)0x3) +#define PAD_TO_8( X ) (((u32)X+0x7) & ~(u32)0x7) +#define PAD_TO_16( X ) (((u32)X+0xf) & ~(u32)0xf) + static inline f32 f32_min( f32 a, f32 b ){ return a < b? a: b; } static inline f32 f32_max( f32 a, f32 b ){ return a > b? a: b; } static inline i32 i32_min( i32 a, i32 b ){ return a < b? a: b; } diff --git a/source/foundation/allocator_queue.c b/source/foundation/allocator_queue.c index e69de29..50ce585 100644 --- a/source/foundation/allocator_queue.c +++ b/source/foundation/allocator_queue.c @@ -0,0 +1,169 @@ +void queue_init( struct queue_allocator *queue, void *buffer, u32 buffer_size ) +{ + queue->buffer = buffer; + queue->size = buffer_size; + queue->head_offset = 0; + queue->tail_offset = 0; + queue->allocation_count = 0; +} + +void *queue_alloc( struct queue_allocator *queue, u32 size ) +{ + u32 total = PAD_TO_8(size) + sizeof( struct queue_item ); + if( total > queue->size ) + return NULL; + + u32 prev_size = 0; + u32 new_item_offset; + if( queue->allocation_count ) + { + struct queue_item *head = queue->buffer + queue->head_offset; + u32 end = queue->head_offset + head->alloc_size, + start = queue->tail_offset, + r0 = 0, + r1 = 0; + if( start < end ) + { + r0 = queue->size - end; + r1 = start; + } + else + r0 = start - end; + + if( total < r0 ) + new_item_offset = end; + else + { + if( total < r1 ) + { + head->alloc_size += r0; + new_item_offset = 0; + } + else + { + /* Full */ + return NULL; + } + } + + prev_size = head->alloc_size; + } + else + { + new_item_offset = 0; + queue->tail_offset = 0; + } + + struct queue_item *item = (struct queue_item *)(queue->buffer + new_item_offset); + zero_buffer( item, sizeof(struct queue_item) ); + item->alloc_size = total; + item->prev_size = prev_size; + + queue->head_offset = new_item_offset; + queue->allocation_count ++; + return item->data; +} + +void *queue_data( struct queue_allocator *queue, u32 offset ) +{ + return queue->buffer + offset; +} + +void *queue_tail_data( struct queue_allocator *queue ) +{ + if( queue->allocation_count ) return queue_data( queue, queue->tail_offset ); + else return NULL; +} + +u32 queue_offset( struct queue_allocator *queue, void *pointer ) +{ + return pointer - queue->buffer; +} + +u32 queue_item_size( struct queue_allocator *queue, u32 item_id ) +{ + struct queue_item *item = queue->buffer + item_id; + return item->alloc_size; +} + +bool queue_next( struct queue_allocator *queue, u32 item_id, u32 *out_next ) +{ + if( item_id != queue->head_offset ) + { + struct queue_item *item = queue->buffer + item_id; + if( item_id + item->alloc_size == queue->size ) *out_next = 0; + else *out_next = item_id + item->alloc_size; + return 1; + } + else return 0; +} + +bool queue_previous( struct queue_allocator *queue, u32 item_id, u32 *out_prev ) +{ + struct queue_item *item = queue->buffer + item_id; + if( item_id != queue->tail_offset ) + { + if( item_id == 0 ) *out_prev = queue->size - item->prev_size; + else *out_prev = item_id - item->prev_size; + return 1; + } + else return 0; +} + +void queue_pop( struct queue_allocator *queue ) +{ + ASSERT_CRITICAL( queue->allocation_count ); + queue->allocation_count --; + + if( queue->allocation_count == 0 ) + { + queue->head_offset = 0; + queue->tail_offset = 0; + return; + } + + struct queue_item *tail = queue->buffer + queue->tail_offset; + u32 start = queue->tail_offset + tail->alloc_size; + + if( start == queue->size ) + start = 0; + + queue->tail_offset = start; + tail = queue->buffer + queue->tail_offset; + tail->prev_size = 0; +} + +void queue_copy_buffer( struct queue_allocator *queue, void *dst, u32 start, u32 size ) +{ + if( start + size > queue->size ) + { + u32 r0 = queue->size - start; + buffer_copy( queue->buffer + start, r0, dst, r0 ); + buffer_copy( queue->buffer, size-r0, dst+r0, size-r0 ); + } + else + buffer_copy( queue->buffer + start, size, dst, size ); +} + +u32 queue_usage( struct queue_allocator *queue ) +{ + if( queue->allocation_count ) + { + struct queue_item *head = queue->buffer + queue->head_offset; + u32 end = queue->head_offset + head->alloc_size, + start = queue->tail_offset; + if( start < end ) + return end - start; + else + return (queue->size - start) + end; + } + else + return 0; +} + +void queue_clear( struct queue_allocator *queue ) +{ + queue->head_offset = 0; + queue->tail_offset = 0; + queue->allocation_count = 0; +} diff --git a/vg_mem_queue.c b/vg_mem_queue.c deleted file mode 100644 index f92da02..0000000 --- a/vg_mem_queue.c +++ /dev/null @@ -1,175 +0,0 @@ -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 ); -} - -void *vg_queue_data( vg_queue *q, u32 offset ) -{ - vg_queue_item *item = q->buffer + offset; - return item->data; -} - -void *vg_queue_tail_data( vg_queue *q ) -{ - if( q->allocation_count ) return vg_queue_data( q, q->tail_offset ); - else return NULL; -} - -u32 vg_queue_offset( vg_queue *q, void *pointer ) -{ - return pointer - q->buffer; -} - -void *vg_queue_pointer( vg_queue *q, u32 offset ) -{ - return q->buffer + offset; -} - -/* - * Allocate memory on the queue. Returns NULL if allocation failed for any reason - */ -void *vg_queue_alloc( vg_queue *q, u32 size ) -{ - u32 total = vg_align8(size) + sizeof(vg_queue_item); - if( total > q->size ) - return NULL; - - u32 prev_size = 0; - u32 new_item_offset; - if( q->allocation_count ) - { - vg_queue_item *head = q->buffer + q->head_offset; - u32 end = q->head_offset + head->alloc_size, - start = q->tail_offset, - r0 = 0, - r1 = 0; - - if( start < end ) - { - r0 = q->size - end; - r1 = start; - } - else - r0 = start - end; - - if( total < r0 ) - new_item_offset = end; - else - { - if( total < r1 ) - { - head->alloc_size += r0; - new_item_offset = 0; - } - else - { - /* Full */ - return NULL; - } - } - - prev_size = head->alloc_size; - } - else - { - new_item_offset = 0; - q->tail_offset = 0; - } - - vg_queue_item *item = (vg_queue_item *)(q->buffer + new_item_offset); - vg_zero_mem( item, sizeof(vg_queue_item) ); - item->alloc_size = total; - item->prev_size = prev_size; - - q->head_offset = new_item_offset; - q->allocation_count ++; - return item->data; -} - -/* - * Free last item from queue - */ -void vg_queue_pop( vg_queue *q ) -{ - VG_ASSERT( q->allocation_count ); - q->allocation_count --; - - if( q->allocation_count == 0 ) - { - q->head_offset = 0; - q->tail_offset = 0; - return; - } - - vg_queue_item *tail = q->buffer + q->tail_offset; - u32 start = q->tail_offset + tail->alloc_size; - - if( start == q->size ) - start = 0; - - q->tail_offset = start; - - tail = q->buffer + q->tail_offset; - tail->prev_size = 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_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; -} - -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 ) -{ - if( q->allocation_count ) - { - vg_queue_item *head = q->buffer + q->head_offset; - u32 end = q->head_offset + head->alloc_size, - start = q->tail_offset; - - if( start < end ) - return end - start; - else - return (q->size - start) + end; - } - else - return 0; -} - -void vg_queue_clear( vg_queue *q ) -{ - q->head_offset = 0; - q->tail_offset = 0; - q->allocation_count = 0; -} diff --git a/vg_mem_queue.h b/vg_mem_queue.h deleted file mode 100644 index a16701f..0000000 --- a/vg_mem_queue.h +++ /dev/null @@ -1,40 +0,0 @@ -#if defined( VG_IMPLEMENTATION ) -# include "vg/vg_mem_queue.c" -#else - -#define VG_MEM_QUEUE_INVALID 0xffffffff - -typedef struct vg_queue vg_queue; -typedef struct vg_queue_item vg_queue_item; - -struct vg_queue_item -{ - u32 alloc_size,prev_size; - u8 data[]; -}; - -struct vg_queue -{ - void *buffer; - u32 size; - u32 head_offset, tail_offset; - u32 allocation_count; -}; - -void *vg_queue_alloc( vg_queue *q, u32 size ); - -void *vg_queue_data( vg_queue *q, u32 offset ); -void *vg_queue_tail_data( vg_queue *q ); -u32 vg_queue_offset( vg_queue *q, void *pointer ); - -/* 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_memcpy( vg_queue *q, void *dst, u32 start, u32 size ); - -u32 vg_queue_usage( vg_queue *q ); -void vg_queue_clear( vg_queue *q ); - -#endif