Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/tup/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ static int add_parser_files_locked(struct file_info *finfo,
struct tent_entries *root, tupid_t vardt,
int full_deps);

static _Thread_local struct mempool pool = MEMPOOL_INITIALIZER(struct file_entry);
// Note it will not work with per-thread pools here because all the allocation
// is done by the fuse server thread while all the free is done by the
// worker threads. Thus the free'd memory cannot be reused by the fuse server
// thread so the memory usage just keeps growing.
static struct mempool pool = MEMPOOL_INITIALIZER(struct file_entry);
static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;

int init_file_info(struct file_info *info, int do_unlink)
{
Expand Down Expand Up @@ -549,15 +554,19 @@ static struct file_entry *new_entry(const char *filename)
{
struct file_entry *fent;

pthread_mutex_lock(&pool_lock);
fent = mempool_alloc(&pool);
pthread_mutex_unlock(&pool_lock);
if(!fent) {
return NULL;
}

fent->filename = strdup(filename);
if(!fent->filename) {
perror("strdup");
pthread_mutex_lock(&pool_lock);
mempool_free(&pool, fent);
pthread_mutex_unlock(&pool_lock);
return NULL;
}
return fent;
Expand All @@ -567,7 +576,9 @@ void del_file_entry(struct file_entry_head *head, struct file_entry *fent)
{
TAILQ_REMOVE(head, fent, list);
free(fent->filename);
pthread_mutex_lock(&pool_lock);
mempool_free(&pool, fent);
pthread_mutex_unlock(&pool_lock);
}

int handle_rename(const char *from, const char *to, struct file_info *info)
Expand Down
4 changes: 2 additions & 2 deletions src/tup/mempool.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void *mempool_alloc(struct mempool *pool)
* memory allocated here is not freed until the program quits.
*/
if(pool->item_size < sizeof(struct mementry)) {
fprintf(stderr, "tup internal error: mempool item size too small: %i\n", pool->item_size);
fprintf(stderr, "tup internal error: mempool item size too small: %zu\n", pool->item_size);
return NULL;
}

Expand Down Expand Up @@ -79,7 +79,7 @@ void *mempool_alloc(struct mempool *pool)
* next item from the pool's memory.
*/
if(((uintptr_t)pool->mem & (pool->alignment-1)) != 0) {
fprintf(stderr, "tup internal error: memory address in mempool (%p) not aligned to %u bytes.\n", pool->mem, pool->alignment);
fprintf(stderr, "tup internal error: memory address in mempool (%p) not aligned to %zu bytes.\n", pool->mem, pool->alignment);
return NULL;
}
ret = (void*)pool->mem;
Expand Down
10 changes: 6 additions & 4 deletions src/tup/mempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@

#include "bsd/queue.h"

#include <stddef.h>

struct mementry {
SLIST_ENTRY(mementry) list;
};
SLIST_HEAD(mementry_head, mementry);

struct mempool {
struct mementry_head free_list;
unsigned int item_size;
unsigned int next_alloc_size;
unsigned int alignment;
int free_count;
size_t item_size;
size_t next_alloc_size;
size_t alignment;
size_t free_count;
char *mem;
};
TAILQ_HEAD(mempool_head, mempool);
Expand Down