Skip to content

Instantly share code, notes, and snippets.

@TerrorJack
Created May 19, 2023 23:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TerrorJack/285ed1b3881b9e885faba4a52624596d to your computer and use it in GitHub Desktop.
Save TerrorJack/285ed1b3881b9e885faba4a52624596d to your computer and use it in GitHub Desktop.

The malloc implementation you provided is based on the dlmalloc (Doug Lea's Malloc) algorithm. This is a general-purpose allocator that is widely used due to its combination of speed and efficient use of memory.

The main concepts behind dlmalloc are:

  1. Chunk: The basic unit of memory allocation. Each chunk contains a header with size and status information, and a payload where user data is stored.

  2. Bin: A collection of free chunks of similar sizes. There are small bins (for small chunks) and tree bins (for large chunks).

  3. Segment: A large chunk of memory obtained from the system. Segments are divided into chunks which are then allocated to the user or stored in bins.

  4. Arena: A space where allocations take place. Each thread can have its own arena to avoid locking contention.

The function you're asking for is typically called a "heap extension" function. It allows the allocator to increase the size of the heap when it runs out of memory. In the context of dlmalloc, this function would add a new segment to the arena.

Here's a simple implementation of such a function:

#include "malloc.h" // Include the header file for the malloc implementation

void extend_heap(void* ptr, size_t length) {
    // Ensure the pointer is aligned. dlmalloc requires that all chunks are
    // aligned to at least 8-byte boundaries.
    if ((uintptr_t)ptr % CHUNK_ALIGN != 0) {
        // The pointer is not properly aligned. Handle this error as appropriate
        // for your application.
        return;
    }

    // Create a new segment
    msegmentptr seg = malloc(sizeof(struct malloc_segment));
    if (seg == NULL) {
        // Failed to allocate the segment descriptor. Handle this error as
        // appropriate for your application.
        return;
    }

    // Initialize the segment
    seg->base = ptr;
    seg->size = length;
    seg->next = NULL;

    // Add the segment to the arena
    // Note: gm is a global variable in the dlmalloc implementation that
    // represents the main arena. If you're using a different arena, replace gm
    // with a pointer to your arena.
    if (gm->seg == NULL) {
        // This is the first segment
        gm->seg = seg;
    } else {
        // Add the new segment to the end of the list
        msegmentptr last = gm->seg;
        while (last->next != NULL) {
            last = last->next;
        }
        last->next = seg;
    }

    // The new memory is initially one large free chunk. Split it into chunks
    // and add them to the appropriate bins.
    init_bins(seg);
}

This function first checks that the pointer is properly aligned, as required by dlmalloc. It then creates a new segment descriptor and initializes it with the provided pointer and length. The new segment is added to the arena, and the memory is split into chunks and added to the appropriate bins.

Please note that this is a simplified implementation and may need to be adjusted to fit your specific needs. For example, it doesn't handle errors other than by returning early, and it doesn't lock the arena during the operation, which could be necessary in a multithreaded environment. Also, the init_bins function is not part of the standard dlmalloc implementation and would need to be implemented separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment