{"thread":{"id":"10750","subject":"[PATCH 02/11] Reorganize the object memory pools so we can release them","startedAt":"2007-11-09T11:06:13Z","lastAt":"2007-11-09T11:06:13Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":11},"messages":[{"id":"59019","messageId":"20071109110613.GB19368@spearce.org","threadId":"10750","inReplyTo":null,"subject":"[PATCH 02/11] Reorganize the object memory pools so we can release them","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-11-09T11:06:13Z","receivedAt":"2007-11-09T11:06:13Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"This changes the object memory allocators in alloc.c so that we\nare storing all information about each allocator within a single\nstruct, rather than hiding it inside of the allocation function.\nBy keeping this state information in a struct we are better able to\norganize a function that would release the allocated memory blocks\nback to the system allocator.\n\nEach block allocated via xmalloc() is chained together into a linked\nlist so we can free them when if we later need to.  A nice side\neffect of this change is we can avoid the increment of the number\nof allocations and instead compute this after the fact based upon\nthe number of blocks in the linked lists.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n alloc.c |   86 ++++++++++++++++++++++++++++++++++++++++----------------------\n 1 files changed, 55 insertions(+), 31 deletions(-)\n\ndiff --git a/alloc.c b/alloc.c\nindex 216c23a..a61ae41 100644\n--- a/alloc.c\n+++ b/alloc.c\n@@ -18,23 +18,62 @@\n \n #define BLOCKING 1024\n \n-#define DEFINE_ALLOCATOR(name, type)\t\t\t\t\\\n-static unsigned int name##_allocs;\t\t\t\t\\\n+struct node_block\n+{\n+\tstruct node_block *next;\n+};\n+\n+struct node_pool\n+{\n+\tstruct node_block *block_list;\n+\tchar *base;\n+\tsize_t nr;\n+};\n+\n+#ifdef NO_C99_FORMAT\n+#define SZ_FMT \"%5u\"\n+#else\n+#define SZ_FMT \"%5zu\"\n+#endif\n+\n+static void report(const char* name, struct node_pool *p, size_t sz)\n+{\n+\tunsigned int count = 0;\n+\tstruct node_block *b;\n+\n+\tfor (b = p->block_list; b; b = b->next)\n+\t\tcount += BLOCKING;\n+\tcount -= p->nr;\n+\n+\tsz = (count * sz) >> 10;\n+\tfprintf(stderr, \"%10s: %8u (\" SZ_FMT \" kB)\\n\", name, count, sz);\n+}\n+\n+#undef SZ_FMT\n+\n+#define DEFINE_ALLOCATOR(name, t)\t\t\t\t\\\n+static struct node_pool name##_pool;\t\t\t\t\\\n void *alloc_##name##_node(void)\t\t\t\t\t\\\n {\t\t\t\t\t\t\t\t\\\n-\tstatic int nr;\t\t\t\t\t\t\\\n-\tstatic type *block;\t\t\t\t\t\\\n \tvoid *ret;\t\t\t\t\t\t\\\n \t\t\t\t\t\t\t\t\\\n-\tif (!nr) {\t\t\t\t\t\t\\\n-\t\tnr = BLOCKING;\t\t\t\t\t\\\n-\t\tblock = xmalloc(BLOCKING * sizeof(type));\t\\\n+\tif (!name##_pool.nr) {\t\t\t\t\t\\\n+\t\tstruct node_block *b;\t\t\t\t\\\n+\t\tb = xmalloc(sizeof(*b) + BLOCKING * sizeof(t));\t\\\n+\t\tb->next = name##_pool.block_list;\t\t\\\n+\t\tname##_pool.block_list = b;\t\t\t\\\n+\t\tname##_pool.base = (char*)(b + 1);\t\t\\\n+\t\tname##_pool.nr = BLOCKING;\t\t\t\\\n \t}\t\t\t\t\t\t\t\\\n-\tnr--;\t\t\t\t\t\t\t\\\n-\tname##_allocs++;\t\t\t\t\t\\\n-\tret = block++;\t\t\t\t\t\t\\\n-\tmemset(ret, 0, sizeof(type));\t\t\t\t\\\n+\tret = name##_pool.base;\t\t\t\t\t\\\n+\tname##_pool.nr--;\t\t\t\t\t\\\n+\tname##_pool.base += sizeof(t);\t\t\t\t\\\n+\tmemset(ret, 0, sizeof(t));\t\t\t\t\\\n \treturn ret;\t\t\t\t\t\t\\\n+}\t\t\t\t\t\t\t\t\\\n+static void report_##name(void)\t\t\t\t\t\\\n+{\t\t\t\t\t\t\t\t\\\n+\treport(#name, &name##_pool, sizeof(t));\t\t\t\\\n }\n \n union any_object {\n@@ -51,26 +90,11 @@ DEFINE_ALLOCATOR(commit, struct commit)\n DEFINE_ALLOCATOR(tag, struct tag)\n DEFINE_ALLOCATOR(object, union any_object)\n \n-#ifdef NO_C99_FORMAT\n-#define SZ_FMT \"%u\"\n-#else\n-#define SZ_FMT \"%zu\"\n-#endif\n-\n-static void report(const char* name, unsigned int count, size_t size)\n-{\n-    fprintf(stderr, \"%10s: %8u (\" SZ_FMT \" kB)\\n\", name, count, size);\n-}\n-\n-#undef SZ_FMT\n-\n-#define REPORT(name)\t\\\n-    report(#name, name##_allocs, name##_allocs*sizeof(struct name) >> 10)\n-\n void alloc_report(void)\n {\n-\tREPORT(blob);\n-\tREPORT(tree);\n-\tREPORT(commit);\n-\tREPORT(tag);\n+\treport_blob();\n+\treport_tree();\n+\treport_commit();\n+\treport_tag();\n+\treport_object();\n }\n-- \n1.5.3.5.1622.g41d10\n"}]}