From 7fc03b0c326ec2ad85a8cdaa9484a121f83c47ff Mon Sep 17 00:00:00 2001 From: Heng Li Date: Thu, 18 Jul 2019 09:13:30 -0400 Subject: [PATCH] r953: krealloc is buggy Its use in minimap2 didn't trigger the bug, so the older minimap2 is still ok. --- kalloc.c | 35 +++++++++++++++++++++-------------- kalloc.h | 10 ++++++++++ main.c | 2 +- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/kalloc.c b/kalloc.c index b36c333..8499552 100644 --- a/kalloc.c +++ b/kalloc.c @@ -18,15 +18,14 @@ * | | | | * p=p->ptr->ptr->ptr->ptr p->ptr p->ptr->ptr p->ptr->ptr->ptr */ - -#define MIN_CORE_SIZE 0x80000 - typedef struct header_t { size_t size; struct header_t *ptr; } header_t; typedef struct { + void *par; + size_t min_core_size; header_t base, *loop_head, *core_head; /* base is a zero-sized block always kept in the loop */ } kmem_t; @@ -36,31 +35,39 @@ static void panic(const char *s) abort(); } -void *km_init(void) +void *km_init2(void *km_par, size_t min_core_size) { - return calloc(1, sizeof(kmem_t)); + kmem_t *km; + km = (kmem_t*)kcalloc(km_par, 1, sizeof(kmem_t)); + km->par = km_par; + km->min_core_size = min_core_size > 0? min_core_size : 0x80000; + return (void*)km; } +void *km_init(void) { return km_init2(0, 0); } + void km_destroy(void *_km) { kmem_t *km = (kmem_t*)_km; + void *km_par; header_t *p, *q; if (km == NULL) return; + km_par = km->par; for (p = km->core_head; p != NULL;) { q = p->ptr; - free(p); + kfree(km_par, p); p = q; } - free(km); + kfree(km_par, km); } static header_t *morecore(kmem_t *km, size_t nu) { header_t *q; size_t bytes, *p; - nu = (nu + 1 + (MIN_CORE_SIZE - 1)) / MIN_CORE_SIZE * MIN_CORE_SIZE; /* the first +1 for core header */ + nu = (nu + 1 + (km->min_core_size - 1)) / km->min_core_size * km->min_core_size; /* the first +1 for core header */ bytes = nu * sizeof(header_t); - q = (header_t*)malloc(bytes); + q = (header_t*)kmalloc(km->par, bytes); if (!q) panic("[morecore] insufficient memory"); q->ptr = km->core_head, q->size = nu, km->core_head = q; p = (size_t*)(q + 1); @@ -125,7 +132,7 @@ void *kmalloc(void *_km, size_t n_bytes) if (n_bytes == 0) return 0; if (km == NULL) return malloc(n_bytes); - n_units = (n_bytes + sizeof(size_t) + sizeof(header_t) - 1) / sizeof(header_t) + 1; + n_units = (n_bytes + sizeof(size_t) + sizeof(header_t) - 1) / sizeof(header_t); /* header+n_bytes requires at least this number of units */ if (!(q = km->loop_head)) /* the first time when kmalloc() is called, intialize it */ q = km->loop_head = km->base.ptr = &km->base; @@ -160,18 +167,18 @@ void *kcalloc(void *_km, size_t count, size_t size) void *krealloc(void *_km, void *ap, size_t n_bytes) // TODO: this can be made more efficient in principle { kmem_t *km = (kmem_t*)_km; - size_t n_units, *p, *q; + size_t cap, *p, *q; if (n_bytes == 0) { kfree(km, ap); return 0; } if (km == NULL) return realloc(ap, n_bytes); if (ap == NULL) return kmalloc(km, n_bytes); - n_units = (n_bytes + sizeof(size_t) + sizeof(header_t) - 1) / sizeof(header_t); p = (size_t*)ap - 1; - if (*p >= n_units) return ap; /* TODO: this prevents shrinking */ + cap = (*p) * sizeof(header_t) - sizeof(size_t); + if (cap >= n_bytes) return ap; /* TODO: this prevents shrinking */ q = (size_t*)kmalloc(km, n_bytes); - memcpy(q, ap, (*p - 1) * sizeof(header_t)); + memcpy(q, ap, cap); kfree(km, ap); return q; } diff --git a/kalloc.h b/kalloc.h index e891892..6d72e4e 100644 --- a/kalloc.h +++ b/kalloc.h @@ -17,6 +17,7 @@ void *kcalloc(void *km, size_t count, size_t size); void kfree(void *km, void *ptr); void *km_init(void); +void *km_init2(void *km_par, size_t min_core_size); void km_destroy(void *km); void km_stat(const void *_km, km_stat_t *s); @@ -24,4 +25,13 @@ void km_stat(const void *_km, km_stat_t *s); } #endif +#define KMALLOC(km, ptr, len) ((ptr) = (__typeof__(ptr))kmalloc((km), (len) * sizeof(*(ptr)))) +#define KCALLOC(km, ptr, len) ((ptr) = (__typeof__(ptr))kcalloc((km), (len), sizeof(*(ptr)))) +#define KREALLOC(km, ptr, len) ((ptr) = (__typeof__(ptr))krealloc((km), (ptr), (len) * sizeof(*(ptr)))) + +#define KEXPAND(km, a, m) do { \ + (m) = (m) >= 4? (m) + ((m)>>1) : 16; \ + KREALLOC((km), (a), (m)); \ + } while (0) + #endif diff --git a/main.c b/main.c index 9f9b5d7..2a1ff15 100644 --- a/main.c +++ b/main.c @@ -7,7 +7,7 @@ #include "mmpriv.h" #include "ketopt.h" -#define MM_VERSION "2.17-r943-dirty" +#define MM_VERSION "2.17-r953-dirty" #ifdef __linux__ #include