[PATCH] fwts-alloc: garbage collect hash records

Colin King colin.king at canonical.com
Thu Feb 2 17:02:00 UTC 2017


From: Colin Ian King <colin.king at canonical.com>

The hash table that tracks low memory allocations does not
automatically free records when they are not used (instead
it marks them as re-usable which is faster).  This patch
adds garbage collection to the hash table when the number
of free'd items drops down to zero. This lazy deferral
allows us to efficiently reap the hash when it is no longer
in use.

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 src/lib/src/fwts_alloc.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/src/lib/src/fwts_alloc.c b/src/lib/src/fwts_alloc.c
index 1901a53..2e9b60b 100644
--- a/src/lib/src/fwts_alloc.c
+++ b/src/lib/src/fwts_alloc.c
@@ -39,6 +39,7 @@ typedef struct hash_alloc {
 } hash_alloc_t;
 
 static hash_alloc_t *hash_allocs[HASH_ALLOC_SIZE];
+static int hash_count;
 
 /*
  *  hash_addr()
@@ -87,6 +88,7 @@ static bool hash_alloc_add(void *addr)
 	new->addr = addr;
 	new->next = hash_allocs[h];
 	hash_allocs[h] = new;
+	hash_count++;
 
 	return true;
 }
@@ -104,6 +106,7 @@ static bool hash_alloc_remove(const void *addr)
 	while (ha) {
 		if (ha->addr == addr) {
 			/* Just nullify it */
+			hash_count--;
 			ha->addr = NULL;
 			return true;
 		}
@@ -113,6 +116,30 @@ static bool hash_alloc_remove(const void *addr)
 }
 
 /*
+ *  hash_alloc_garbage_collect()
+ *	free all hash records when the hash
+ *	is empty.
+ */
+static void hash_alloc_garbage_collect(void)
+{
+	size_t i;
+
+	if (hash_count)
+		return;
+
+	for (i = 0; i < HASH_ALLOC_SIZE; i++) {
+		hash_alloc_t *ha = hash_allocs[i];
+
+		while (ha) {
+			hash_alloc_t *next = ha->next;
+
+			free(ha);
+			ha = next;
+		}
+	}
+}
+
+/*
  * We implement a low memory allocator to allow us to allocate
  * memory < 2G limit for the ACPICA table handling.  On 64 bit
  * machines we have to ensure that cached copies of ACPI tables
@@ -406,4 +433,6 @@ void fwts_low_free(const void *ptr)
 	/* Be doubly sure by checking magic before we munmap */
 	if (hdr->magic == FWTS_ALLOC_MAGIC)
 		munmap(hdr, hdr->size);
+
+	hash_alloc_garbage_collect();
 }
-- 
2.10.2




More information about the fwts-devel mailing list