From afe1e1d12e42a0881aff63c766c14e48319b560c Mon Sep 17 00:00:00 2001
From: 3gg <3gg@shellblade.net>
Date: Sat, 9 Mar 2024 08:36:02 -0800
Subject: Define functions to get the number of used blocks.

---
 mem/include/mem.h | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

(limited to 'mem/include/mem.h')

diff --git a/mem/include/mem.h b/mem/include/mem.h
index 892ea4f..224b069 100644
--- a/mem/include/mem.h
+++ b/mem/include/mem.h
@@ -86,9 +86,15 @@
 #define mem_get_chunk_handle(MEM, CHUNK_PTR) \
   mem_get_chunk_handle_(&(MEM)->mem, CHUNK_PTR)
 
-/// Return the total capacity of the allocator in bytes.
+/// Return the block size in bytes.
+#define mem_block_size_bytes(MEM) memp_block_size_bytes_(&(MEM)->pool)
+
+/// Return the total capacity of the allocator.
 #define mem_capacity(MEM) mem_capacity_(&(MEM)->mem)
 
+/// Return the number of used blocks in the allocator.
+#define mem_size(MEM) mem_size_(&(MEM)->mem)
+
 /// Set whether to trap when attempting to allocate beyond capacity.
 #define mem_enable_traps(MEM, enable) mem_enable_traps_(&(MEM)->mem, enable)
 
@@ -97,18 +103,20 @@
 /// The caller can use 'i' as the index of the current chunk.
 ///
 /// It is valid to mem_free() the chunk at each step of the iteration.
-#define mem_foreach(MEM, ITER, BODY)                                  \
-  {                                                                   \
-    size_t i = 0;                                                     \
-    do {                                                              \
-      if ((MEM)->mem.chunks[i].used) {                                \
-        __typeof__((MEM)->object[0])* ITER =                          \
-            &(((__typeof__((MEM)->object[0])*)(MEM)->mem.blocks))[i]; \
-        (void)ITER;                                                   \
-        BODY;                                                         \
-      }                                                               \
-      i = (MEM)->mem.chunks[i].next;                                  \
-    } while (i);                                                      \
+#define mem_foreach(MEM, ITER, BODY)                                    \
+  {                                                                     \
+    size_t i = 0;                                                       \
+    if ((MEM)->mem.num_used_blocks > 0) {                               \
+      do {                                                              \
+        if ((MEM)->mem.chunks[i].used) {                                \
+          __typeof__((MEM)->object[0])* ITER =                          \
+              &(((__typeof__((MEM)->object[0])*)(MEM)->mem.blocks))[i]; \
+          (void)ITER;                                                   \
+          BODY;                                                         \
+        }                                                               \
+        i = (MEM)->mem.chunks[i].next;                                  \
+      } while (i);                                                      \
+    }                                                                   \
   }
 
 // -----------------------------------------------------------------------------
@@ -137,6 +145,7 @@ typedef struct Chunk {
 typedef struct Memory {
   size_t   block_size_bytes;
   size_t   num_blocks;
+  size_t   num_used_blocks;
   size_t   next_free_chunk;
   bool     dynamic; /// True if blocks and chunks are dynamically-allocated.
   bool     trap;    /// Whether to trap when allocating beyond capacity.
@@ -164,5 +173,7 @@ void*  mem_alloc_(Memory*, size_t num_blocks);
 void   mem_free_(Memory*, void** chunk_ptr);
 void*  mem_get_chunk_(const Memory*, size_t chunk_handle);
 size_t mem_get_chunk_handle_(const Memory*, const void* chunk);
+size_t mem_block_size_bytes_(const Memory*);
 size_t mem_capacity_(const Memory*);
+size_t mem_size_(const Memory*);
 void   mem_enable_traps_(Memory*, bool);
-- 
cgit v1.2.3