From: hgn Date: Wed, 26 Mar 2025 04:03:41 +0000 (+0000) Subject: vg_queue api X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=9dbbae68cefcb4a2c77235850df684548ff568ac;p=vg.git vg_queue api --- diff --git a/src/fonts/vg_font_thin_3.xcf b/src/fonts/vg_font_thin_3.xcf index 3e2c1cb..a62e594 100644 Binary files a/src/fonts/vg_font_thin_3.xcf and b/src/fonts/vg_font_thin_3.xcf differ diff --git a/vg_io.c b/vg_io.c index a061d0f..027daa5 100644 --- a/vg_io.c +++ b/vg_io.c @@ -191,8 +191,7 @@ void *vg_file_read( void *lin_alloc, const char *path, u32 *size ) FILE *f = fopen( path, "rb" ); if( f ) { - void *buffer = lin_alloc? vg_linear_alloc( lin_alloc, 0 ): - NULL; + void *buffer = lin_alloc? vg_linear_alloc( lin_alloc, 0 ): NULL; u64 current = 0; /* read in chunks */ diff --git a/vg_mem_queue.c b/vg_mem_queue.c index 3b1a9d6..cc410d8 100644 --- a/vg_mem_queue.c +++ b/vg_mem_queue.c @@ -5,55 +5,116 @@ #include /* - * Allocate memory on the queue. Returns NULL if allocation failed for any - * any reason. + * Copy q1 to q2, and reorganize the memory to correct for q2's new size */ -vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size ) +void vg_queue_copy_upgrade( vg_queue *q1, vg_queue *q2 ) { - u32 total = vg_align8(size) + sizeof(vg_queue_frame); - vg_queue_frame *frame = NULL; + VG_ASSERT( q2->size >= q1->size ); + if( q1->allocation_count == 0 ) + { + q2->head_offset = 0; + q2->tail_offset = 0; + q2->allocation_count = 0; + return; + } + + vg_queue_item *head = q1->buffer + q1->head_offset; + u32 end = q1->head_offset + head->alloc_size, + start = q1->tail_offset; + + q2->allocation_count = q1->allocation_count; + q2->tail_offset = 0; + if( start < end ) + { + u32 r0 = end-start; + memcpy( q2->buffer, q1->buffer+start, r0 ); + q2->head_offset = r0 - head->alloc_size; + } + else + { + u32 r0 = q1->size - start; + memcpy( q2->buffer, q1->buffer+start, r0 ); + memcpy( q2->buffer + r0, q1->buffer, end ); + q2->head_offset = r0 + end - head->alloc_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; +} + +/* + * Allocate memory on the queue. Returns NULL if allocation failed for any reason & out_offset undefined + */ +void *vg_queue_alloc( vg_queue *q, u32 size, u32 *out_offset ) +{ + u32 total = vg_align8(size) + sizeof(vg_queue_item); if( total > q->size ) return NULL; - if( q->head ) + u32 new_item_offset; + if( q->allocation_count ) { - u32 end = ((u8 *)q->head - q->buffer) + q->head->alloc_size, - start = ((u8 *)q->tail - q->buffer), + 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; + if( start < end ) + { + r0 = q->size - end; r1 = start; } else r0 = start - end; - if( total < r0 ){ - frame = (vg_queue_frame *)(q->buffer + end); - } - else { - if( total < r1 ){ - q->head->alloc_size += r0; - frame = (vg_queue_frame *)q->buffer; + if( total < r0 ) + new_item_offset = end; + else + { + if( total < r1 ) + { + head->alloc_size += r0; + new_item_offset = 0; + } + else + { + /* Full */ + return NULL; } } - - if( !frame ) return NULL; } - else{ - frame = (vg_queue_frame *)q->buffer; - q->tail = frame; + else + { + new_item_offset = 0; + q->tail_offset = 0; } - memset( frame, 0, sizeof(vg_queue_frame) ); + 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; - q->head = frame; - frame->alloc_size = total; - frame->size = size; + q->head_offset = new_item_offset; + q->allocation_count ++; - return frame; + if( out_offset ) + *out_offset = new_item_offset; + return item->data; } /* @@ -61,17 +122,21 @@ vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size ) */ void vg_queue_pop( vg_queue *q ) { - if( q->head == q->tail ){ - q->head = NULL; - q->tail = NULL; + VG_ASSERT( q->allocation_count ); + q->allocation_count --; + + if( q->head_offset == q->tail_offset ) + { + q->head_offset = 0; + q->tail_offset = 0; return; } - u32 start = ((u8 *)q->tail - q->buffer); - start += q->tail->alloc_size; + 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 = (vg_queue_frame *)(q->buffer + start); + q->tail_offset = start; } diff --git a/vg_mem_queue.h b/vg_mem_queue.h index f898ada..3e14ae5 100644 --- a/vg_mem_queue.h +++ b/vg_mem_queue.h @@ -1,9 +1,11 @@ #pragma once +#define VG_MEM_QUEUE_INVALID 0xffffffff + typedef struct vg_queue vg_queue; -typedef struct vg_queue_frame vg_queue_frame; +typedef struct vg_queue_item vg_queue_item; -struct vg_queue_frame +struct vg_queue_item { u32 alloc_size,size; u8 data[]; @@ -11,11 +13,16 @@ struct vg_queue_frame struct vg_queue { - u8 *buffer; + void *buffer; u32 size; - - vg_queue_frame *head, *tail; + u32 head_offset, tail_offset; + u32 allocation_count; }; -vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size ); +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 ); + void vg_queue_pop( vg_queue *q ); +void vg_queue_copy_upgrade( vg_queue *q1, vg_queue *q2 );