Some nice extras for memory things
authorhgn <hgodden00@gmail.com>
Fri, 4 Apr 2025 07:11:36 +0000 (08:11 +0100)
committerhgn <hgodden00@gmail.com>
Fri, 4 Apr 2025 07:11:36 +0000 (08:11 +0100)
vg_mem_pool.c
vg_mem_pool.h
vg_mem_queue.c
vg_mem_queue.h

index 0a830a2658d02749ef91740bdcaa02bb5df08662..01b5e27567f6006167bb5d5a4b90d775242a0636 100644 (file)
@@ -13,6 +13,7 @@ vg_pool_node *vg_pool_nodeptr( vg_pool *pool, u16 id ){
    }
 }
 
+/* is thread safe */
 void *vg_pool_item( vg_pool *pool, u16 id )
 {
    if( (id == 0) || (id > pool->count) ) 
@@ -79,7 +80,7 @@ void vg_pool_watch( vg_pool *pool, u16 id )
 }
 
 /* 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 );
 
@@ -92,9 +93,13 @@ void vg_pool_unwatch( vg_pool *pool, u16 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;
 }
index 3a61881ddca69ae9584f3243bc6121ebb318c993..28e2b54cfa05aba7767cd2d19824eeef1edd666e 100644 (file)
@@ -23,4 +23,4 @@ void          vg_pool_init     ( vg_pool *pool );
 u16           vg_pool_id       ( vg_pool *pool, void *item );
 u16           vg_pool_lru      ( vg_pool *pool );
 void          vg_pool_watch    ( vg_pool *pool, u16 id );
-void          vg_pool_unwatch  ( vg_pool *pool, u16 id );
+bool          vg_pool_unwatch  ( vg_pool *pool, u16 id );
index 8cf8adff569df583bc4a5b6fd9b4862275c8a608..f050ebea68c6593039ee155d0fdec03fac3c380e 100644 (file)
@@ -4,13 +4,23 @@
 #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;
@@ -23,23 +33,34 @@ void vg_queue_copy_upgrade( vg_queue *q1, vg_queue *q2 )
    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;
@@ -48,12 +69,8 @@ void *vg_queue_data( vg_queue *q, u32 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;
 }
 
 /*
@@ -65,6 +82,7 @@ void *vg_queue_alloc( vg_queue *q, u32 size, u32 *out_offset )
    if( total > q->size )
       return NULL;
 
+   u32 prev_size = 0;
    u32 new_item_offset;
    if( q->allocation_count )
    {
@@ -97,6 +115,8 @@ void *vg_queue_alloc( vg_queue *q, u32 size, u32 *out_offset )
             return NULL;
          }
       }
+
+      prev_size = head->alloc_size;
    }
    else
    {
@@ -107,7 +127,7 @@ void *vg_queue_alloc( vg_queue *q, u32 size, u32 *out_offset )
    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 ++;
@@ -125,7 +145,7 @@ void vg_queue_pop( vg_queue *q )
    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;
@@ -139,6 +159,39 @@ void vg_queue_pop( vg_queue *q )
       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 )
index 22b8750ee50b11e8b29e850d9cb815a8c35192e8..22a1bdd63d09c5532bc65fe8ebaf6dd405d7df57 100644 (file)
@@ -7,7 +7,7 @@ typedef struct vg_queue_item vg_queue_item;
 
 struct vg_queue_item
 {
-   u32 alloc_size,size;
+   u32 alloc_size,prev_size;
    u8 data[];
 };
 
@@ -17,6 +17,7 @@ struct vg_queue
    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 );
@@ -24,7 +25,13 @@ 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 );