如何使我自己的 malloc 线程安全以及在哪里锁定和解锁?

How to make my own malloc thread safe and where to lock and unlock?

我正在实现自己的内存分配器,但我想解决线程安全问题。这是我的 malloc 实现:

pthread_mutex_t alloc_mutex = PTHREAD_MUTEX_INITIALIZER; /*< Mutex for protecting the linked list */
void *malloc(size_t size)
{
pthread_mutex_lock(&alloc_mutex);
size_t total_size = size + sizeof(struct mem_block);
size_t aligned_size = total_size;
if (total_size % 8 !=0) {
    aligned_size = (total_size / 8) * 8 + 8;
}

LOG("Allocation: request size = %zu, total size = %zu, aligned size = %zu\n", size, total_size, aligned_size);

struct mem_block *reused_block = reuse(aligned_size);
if(reused_block != NULL){
    return reused_block + 1;
}

int page_size = getpagesize();
size_t num_pages = aligned_size / page_size;
if(aligned_size % page_size != 0){
    num_pages++;
}
size_t region_size = num_pages * page_size;

struct mem_block *block = mmap(NULL, region_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

if(block == MAP_FAILED){
    perror("mmap");
    return NULL;
}

snprintf(block->name, 32, "Allocation %lu", g_allocations++);
block->size = region_size;
block->free = true;
block->region_id = g_regions++;

if(g_head == NULL && g_tail == NULL){
    block->next = NULL;
    block->prev = NULL;
    g_head = block;
     g_tail = block;
}
else {
    g_tail->next = block;
    block->prev = g_tail;
    block->next = NULL;
    g_tail = block;
}

split_block(block, aligned_size);
block->free = false;
pthread_mutex_unlock(&alloc_mutex);
return block+1;
}

我的主要问题是:为了实现线程安全,我需要在哪里锁定和解锁?因为不是。

您可以实现两个函数,一个称为 'malloc_impl',具有主要功能,另一个称为 'malloc',用于锁定互斥体,调用 'malloc_impl' 并将其解锁。

另一个解决方案是使用 'goto'。视情况跳转到具体的label,这样只需要指定一次解锁即可。

示例:

void *block = NULL;

if (err_cond) 
    goto fail;

if (cond) 
    goto done;

// do some other stuff

goto done;

fail:
    block = NULL;
done:
    unlock_mutex();
    return block;

p.s。是的,goto 是邪恶的,但有时非常(非常)有用。