diff --git a/core/fiber.c b/core/fiber.c index 9114abe6b2f6844f4788a35f52dcbd6a56a7e80c..0575a7e7d2e1b9136037facefc26307ccc79cfd8 100644 --- a/core/fiber.c +++ b/core/fiber.c @@ -406,19 +406,24 @@ fiber_create(const char *restrict name, int fd, int inbox_size, void (*f) (void * so, struct fiber and some of its members are leaked forever */ +void +fiber_destroy(struct fiber *f) +{ + if (f == fiber) /* do not destroy running fiber */ + return; + if (strcmp(f->name, "sched") == 0) + return; + + palloc_destroy_pool(f->pool); + tarantool_coro_destroy(&f->coro); +} + void fiber_destroy_all() { struct fiber *f; - SLIST_FOREACH(f, &fibers, link) { - if (f == fiber) /* do not destroy running fiber */ - continue; - if (strcmp(f->name, "sched") == 0) - continue; - - palloc_destroy_pool(f->pool); - tarantool_coro_destroy(&f->coro); - } + SLIST_FOREACH(f, &fibers, link) + fiber_destroy(f); } diff --git a/core/palloc.c b/core/palloc.c index a8171ce944b6abf7bc9f57e8770cde95806ddf11..9d11d8b45cbccf4565ee50e50de7d7dbd774bcdc 100644 --- a/core/palloc.c +++ b/core/palloc.c @@ -55,7 +55,7 @@ SLIST_HEAD(chunk_list_head, chunk); struct chunk_class { int i; - u32 size; + u32 allocated_size; int chunks_count; struct chunk_list_head chunks; TAILQ_ENTRY(chunk_class) link; @@ -106,7 +106,7 @@ class_init(size_t size) class->i = class_count++; class->chunks_count = 0; - class->size = size; + class->allocated_size = size; SLIST_INIT(&class->chunks); TAILQ_INSERT_TAIL(&classes, class, link); @@ -128,7 +128,7 @@ palloc_init(void) */ for (size_t size = 4096 * 8; size <= 1 << 16; size *= 2) { - if (class_init(size - sizeof(struct chunk)) == NULL) + if (class_init(size) == NULL) return 0; } @@ -166,10 +166,10 @@ next_chunk_for(struct palloc_pool *restrict pool, size_t size) else class = TAILQ_FIRST(&classes); - if (class->size == -1) + if (class->allocated_size == -1) class = TAILQ_PREV(class, class_tailq_head, link); - while (class != NULL && class->size < size) + while (class != NULL && class->allocated_size < size + sizeof(struct chunk)) class = TAILQ_NEXT(class, link); assert(class != NULL); @@ -181,13 +181,13 @@ next_chunk_for(struct palloc_pool *restrict pool, size_t size) } if (size > palloc_greatest_size()) { - chunk_size = size; - chunk = malloc(sizeof(struct chunk) + chunk_size); + chunk_size = size + sizeof(struct chunk); + chunk = malloc(chunk_size); if (chunk == NULL) return NULL; } else { - chunk_size = class->size; - chunk = mmap(NULL, sizeof(struct chunk) + chunk_size, + chunk_size = class->allocated_size; + chunk = mmap(NULL, chunk_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (chunk == MAP_FAILED) return NULL; @@ -196,7 +196,7 @@ next_chunk_for(struct palloc_pool *restrict pool, size_t size) class->chunks_count++; chunk->magic = chunk_magic; chunk->size = chunk_size; - chunk->free = chunk_size; + chunk->free = chunk_size - sizeof(struct chunk); chunk->brk = (void *)chunk + sizeof(struct chunk); chunk->class = class; found: @@ -330,14 +330,14 @@ palloc_destroy_pool(struct palloc_pool *pool) } void -palloc_unmap_unused(void) +palloc_free_unused(void) { struct chunk_class *class; struct chunk *chunk, *next_chunk; TAILQ_FOREACH(class, &classes, link) { SLIST_FOREACH_SAFE(chunk, &class->chunks, free_link, next_chunk) - munmap(chunk, class->size + sizeof(struct chunk)); + munmap(chunk, class->allocated_size); SLIST_INIT(&class->chunks); } } @@ -359,7 +359,7 @@ palloc_stat(struct tbuf *buf) tbuf_printf(buf, " - { size: %"PRIu32 - ", free_chunks: %- 6i, busy_chunks: %- 6i }" CRLF, class->size, + ", free_chunks: %- 6i, busy_chunks: %- 6i }" CRLF, class->allocated_size, free_chunks, class->chunks_count - free_chunks); } tbuf_printf(buf, " pools:" CRLF); @@ -382,7 +382,7 @@ palloc_stat(struct tbuf *buf) if (chunks[class->i] == 0) continue; tbuf_printf(buf, " - { size: %"PRIu32", used: %i }" CRLF, - class->size, chunks[class->i]); + class->allocated_size, chunks[class->i]); if (indent == 0) indent = 19; diff --git a/core/tarantool.c b/core/tarantool.c index b3b45a5aca3ca5c271c0aa41478f45be0ab42bc8..e235300e9c042f80aa801d1fcb83b97b870b6bbb 100644 --- a/core/tarantool.c +++ b/core/tarantool.c @@ -189,7 +189,7 @@ snapshot(void *ev __unused__, int events __unused__) fiber->name = "dumper"; set_proc_title("dumper (%" PRIu32 ")", getppid()); fiber_destroy_all(); - palloc_unmap_unused(); + palloc_free_unused(); close_all_xcpt(1, sayfd); snapshot_save(recovery_state, mod_snapshot); #ifdef ENABLE_GCOV diff --git a/include/fiber.h b/include/fiber.h index 638ef39794b3931e37177161c317f9190406bb66..bba48b961f3b00bc1babaff0a2c25178ceb75776 100644 --- a/include/fiber.h +++ b/include/fiber.h @@ -118,6 +118,7 @@ void wait_for_child(pid_t pid); void unwait(int events); void yield(void); void raise_(int); +void fiber_destroy_all(); #define raise(v, err) \ ({ \ say_debug("raise 0x%x/%s at %s:%i", v, err, __FILE__, __LINE__); \ diff --git a/include/palloc.h b/include/palloc.h index 2b9217b4d038056f1525e16281cbca2539825203..582865958c6bad45d435fda9dcae00bcc65c4ad3 100644 --- a/include/palloc.h +++ b/include/palloc.h @@ -45,7 +45,7 @@ void prelease(struct palloc_pool *pool); void prelease_after(struct palloc_pool *pool, size_t after); struct palloc_pool *palloc_create_pool(const char *name); void palloc_destroy_pool(struct palloc_pool *); -void palloc_unmap_unused(void); +void palloc_free_unused(void); const char *palloc_name(struct palloc_pool *, const char *); size_t palloc_allocated(struct palloc_pool *);