fast-import: introduce mem_pool type

Introduce the mem_pool type which encapsulates all the information necessary to manage a pool of memory. This change moves the existing variables in fast-import used to support the global memory pool to use this structure. It also renames variables that are no longer used by memory pools to reflect their more scoped usage. These changes allow for the multiple instances of a memory pool to exist and be reused outside of fast-import. In a future commit the mem_pool type will be moved to its own file. Signed-off-by: Jameson Miller <jamill@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jameson Miller committed Apr 11, 2018 at 18:37 UTC 96c47d1466d2d11e2028b79fdc0bcaf7a4bb7345
1 file changed +52 -29
fast-import.c
+52 -29
@@ -216,6 +216,19 @@ struct mp_block {
216 uintmax_t space[FLEX_ARRAY]; /* more */
217 };
218
219 +struct mem_pool {
220 + struct mp_block *mp_block;
221 +
222 + /*
223 + * The amount of available memory to grow the pool by.
224 + * This size does not include the overhead for the mp_block.
225 + */
226 + size_t block_alloc;
227 +
228 + /* The total amount of memory allocated by the pool. */
229 + size_t pool_alloc;
230 +};
231 +
232 struct atom_str {
233 struct atom_str *next_atom;
234 unsigned short str_len;
@@ -304,9 +317,8 @@ static int global_argc;
317 static const char **global_argv;
318
319 /* Memory pools */
307 -static size_t mem_pool_alloc = 2*1024*1024 - sizeof(struct mp_block);
308 -static size_t total_allocd;
309 -static struct mp_block *mp_block_head;
320 +static struct mem_pool fi_mem_pool = {NULL, 2*1024*1024 -
321 + sizeof(struct mp_block), 0 };
322
323 /* Atom management */
324 static unsigned int atom_table_sz = 4451;
@@ -341,6 +353,7 @@ static unsigned int tree_entry_alloc = 1000;
353 static void *avail_tree_entry;
354 static unsigned int avail_tree_table_sz = 100;
355 static struct avail_tree_content **avail_tree_table;
356 +static size_t tree_entry_allocd;
357 static struct strbuf old_tree = STRBUF_INIT;
358 static struct strbuf new_tree = STRBUF_INIT;
359
@@ -634,7 +647,21 @@ static unsigned int hc_str(const char *s, size_t len)
647 return r;
648 }
649
637 -static void *pool_alloc(size_t len)
650 +static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool, size_t block_alloc)
651 +{
652 + struct mp_block *p;
653 +
654 + mem_pool->pool_alloc += sizeof(struct mp_block) + block_alloc;
655 + p = xmalloc(st_add(sizeof(struct mp_block), block_alloc));
656 + p->next_block = mem_pool->mp_block;
657 + p->next_free = (char *)p->space;
658 + p->end = p->next_free + block_alloc;
659 + mem_pool->mp_block = p;
660 +
661 + return p;
662 +}
663 +
664 +static void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len)
665 {
666 struct mp_block *p;
667 void *r;
@@ -643,21 +670,17 @@ static void *pool_alloc(size_t len)
670 if (len & (sizeof(uintmax_t) - 1))
671 len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
672
646 - for (p = mp_block_head; p; p = p->next_block)
647 - if ((p->end - p->next_free >= len))
673 + for (p = mem_pool->mp_block; p; p = p->next_block)
674 + if (p->end - p->next_free >= len)
675 break;
676
677 if (!p) {
651 - if (len >= (mem_pool_alloc/2)) {
652 - total_allocd += len;
678 + if (len >= (mem_pool->block_alloc / 2)) {
679 + mem_pool->pool_alloc += len;
680 return xmalloc(len);
681 }
655 - total_allocd += sizeof(struct mp_block) + mem_pool_alloc;
656 - p = xmalloc(st_add(sizeof(struct mp_block), mem_pool_alloc));
657 - p->next_block = mp_block_head;
658 - p->next_free = (char *) p->space;
659 - p->end = p->next_free + mem_pool_alloc;
660 - mp_block_head = p;
682 +
683 + p = mem_pool_alloc_block(mem_pool, mem_pool->block_alloc);
684 }
685
686 r = p->next_free;
@@ -665,10 +688,10 @@ static void *pool_alloc(size_t len)
688 return r;
689 }
690
668 -static void *pool_calloc(size_t count, size_t size)
691 +static void *mem_pool_calloc(struct mem_pool *mem_pool, size_t count, size_t size)
692 {
670 - size_t len = count * size;
671 - void *r = pool_alloc(len);
693 + size_t len = st_mult(count, size);
694 + void *r = mem_pool_alloc(mem_pool, len);
695 memset(r, 0, len);
696 return r;
697 }
@@ -676,7 +699,7 @@ static void *pool_calloc(size_t count, size_t size)
699 static char *pool_strdup(const char *s)
700 {
701 size_t len = strlen(s) + 1;
679 - char *r = pool_alloc(len);
702 + char *r = mem_pool_alloc(&fi_mem_pool, len);
703 memcpy(r, s, len);
704 return r;
705 }
@@ -685,7 +708,7 @@ static void insert_mark(uintmax_t idnum, struct object_entry *oe)
708 {
709 struct mark_set *s = marks;
710 while ((idnum >> s->shift) >= 1024) {
688 - s = pool_calloc(1, sizeof(struct mark_set));
711 + s = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct mark_set));
712 s->shift = marks->shift + 10;
713 s->data.sets[0] = marks;
714 marks = s;
@@ -694,7 +717,7 @@ static void insert_mark(uintmax_t idnum, struct object_entry *oe)
717 uintmax_t i = idnum >> s->shift;
718 idnum -= i << s->shift;
719 if (!s->data.sets[i]) {
697 - s->data.sets[i] = pool_calloc(1, sizeof(struct mark_set));
720 + s->data.sets[i] = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct mark_set));
721 s->data.sets[i]->shift = s->shift - 10;
722 }
723 s = s->data.sets[i];
@@ -732,7 +755,7 @@ static struct atom_str *to_atom(const char *s, unsigned short len)
755 if (c->str_len == len && !strncmp(s, c->str_dat, len))
756 return c;
757
735 - c = pool_alloc(sizeof(struct atom_str) + len + 1);
758 + c = mem_pool_alloc(&fi_mem_pool, sizeof(struct atom_str) + len + 1);
759 c->str_len = len;
760 memcpy(c->str_dat, s, len);
761 c->str_dat[len] = 0;
@@ -763,7 +786,7 @@ static struct branch *new_branch(const char *name)
786 if (check_refname_format(name, REFNAME_ALLOW_ONELEVEL))
787 die("Branch name doesn't conform to GIT standards: %s", name);
788
766 - b = pool_calloc(1, sizeof(struct branch));
789 + b = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct branch));
790 b->name = pool_strdup(name);
791 b->table_next_branch = branch_table[hc];
792 b->branch_tree.versions[0].mode = S_IFDIR;
@@ -799,7 +822,7 @@ static struct tree_content *new_tree_content(unsigned int cnt)
822 avail_tree_table[hc] = f->next_avail;
823 } else {
824 cnt = cnt & 7 ? ((cnt / 8) + 1) * 8 : cnt;
802 - f = pool_alloc(sizeof(*t) + sizeof(t->entries[0]) * cnt);
825 + f = mem_pool_alloc(&fi_mem_pool, sizeof(*t) + sizeof(t->entries[0]) * cnt);
826 f->entry_capacity = cnt;
827 }
828
@@ -844,7 +867,7 @@ static struct tree_entry *new_tree_entry(void)
867
868 if (!avail_tree_entry) {
869 unsigned int n = tree_entry_alloc;
847 - total_allocd += n * sizeof(struct tree_entry);
870 + tree_entry_allocd += n * sizeof(struct tree_entry);
871 ALLOC_ARRAY(e, n);
872 avail_tree_entry = e;
873 while (n-- > 1) {
@@ -2862,7 +2885,7 @@ static void parse_new_tag(const char *arg)
2885 enum object_type type;
2886 const char *v;
2887
2865 - t = pool_alloc(sizeof(struct tag));
2888 + t = mem_pool_alloc(&fi_mem_pool, sizeof(struct tag));
2889 memset(t, 0, sizeof(struct tag));
2890 t->name = pool_strdup(arg);
2891 if (last_tag)
@@ -3461,12 +3484,12 @@ int cmd_main(int argc, const char **argv)
3484 atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*));
3485 branch_table = xcalloc(branch_table_sz, sizeof(struct branch*));
3486 avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
3464 - marks = pool_calloc(1, sizeof(struct mark_set));
3487 + marks = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct mark_set));
3488
3489 global_argc = argc;
3490 global_argv = argv;
3491
3469 - rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
3492 + rc_free = mem_pool_alloc(&fi_mem_pool, cmd_save * sizeof(*rc_free));
3493 for (i = 0; i < (cmd_save - 1); i++)
3494 rc_free[i].next = &rc_free[i + 1];
3495 rc_free[cmd_save - 1].next = NULL;
@@ -3541,8 +3564,8 @@ int cmd_main(int argc, const char **argv)
3564 fprintf(stderr, "Total branches: %10lu (%10lu loads )\n", branch_count, branch_load_count);
3565 fprintf(stderr, " marks: %10" PRIuMAX " (%10" PRIuMAX " unique )\n", (((uintmax_t)1) << marks->shift) * 1024, marks_set_count);
3566 fprintf(stderr, " atoms: %10u\n", atom_cnt);
3544 - fprintf(stderr, "Memory total: %10" PRIuMAX " KiB\n", (total_allocd + alloc_count*sizeof(struct object_entry))/1024);
3545 - fprintf(stderr, " pools: %10lu KiB\n", (unsigned long)(total_allocd/1024));
3567 + fprintf(stderr, "Memory total: %10" PRIuMAX " KiB\n", (tree_entry_allocd + fi_mem_pool.pool_alloc + alloc_count*sizeof(struct object_entry))/1024);
3568 + fprintf(stderr, " pools: %10lu KiB\n", (unsigned long)((tree_entry_allocd + fi_mem_pool.pool_alloc) /1024));
3569 fprintf(stderr, " objects: %10" PRIuMAX " KiB\n", (alloc_count*sizeof(struct object_entry))/1024);
3570 fprintf(stderr, "---------------------------------------------------------------------\n");
3571 pack_report();