Hi there,

I am reading and learning the internals of malloc(3).
So, after compiling the debug version of libc and using it for one
basic sample code for malloc(3).

Not able to understand some parts of the following code snippet:

void
_malloc_init(int from_rthreads)
{
    u_int i, nmutexes;
    struct dir_info *d;

    _MALLOC_LOCK(1);
    if (!from_rthreads && mopts.malloc_pool[1]) {
        _MALLOC_UNLOCK(1);
        return;
    }
    if (!mopts.malloc_canary)
        omalloc_init();

    nmutexes = from_rthreads ? mopts.malloc_mutexes : 2;
    if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0)
        mprotect(&malloc_readonly, sizeof(malloc_readonly),
            PROT_READ | PROT_WRITE);
    for (i = 0; i < nmutexes; i++) {
        if (mopts.malloc_pool[i])
            continue;
        if (i == 0) {
            omalloc_poolinit(&d, MAP_CONCEAL);
            d->malloc_junk = 2;
            d->malloc_cache = 0;
        } else {
            omalloc_poolinit(&d, 0);
            d->malloc_junk = mopts.def_malloc_junk;
            d->malloc_cache = mopts.def_malloc_cache;
        }
        d->mutex = i;
        mopts.malloc_pool[i] = d;
    }

    if (from_rthreads)
        mopts.malloc_mt = 1;
    else
        mopts.internal_funcs = 1;

    /*
     * Options have been set and will never be reset.
     * Prevent further tampering with them.
     */
    if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0)
        mprotect(&malloc_readonly, sizeof(malloc_readonly), PROT_READ);
    _MALLOC_UNLOCK(1);
}

In the above code snippet, could some please through some light on the
following queries
1. Use of nmutexes?
2. And, why it is looping till nmutexes and calls function
omalloc_poolinit(&d, MAP_CONCEAL) /* when i == 0*/
and other calls to omalloc_poolinit(&d, 0) /* when i != 0 */
So, suppose in the case of nmutexes = 2, I am not sure where are the
uses of these 3 initialized pools, that is, malloc_pool[0],
malloc_pool[1] and malloc_pool[2]?


static void
omalloc_poolinit(struct dir_info **dp, int mmap_flag)
{
    char *p;
    size_t d_avail, regioninfo_size;
    struct dir_info *d;
    int i, j;

    /*
     * Allocate dir_info with a guard page on either side. Also
     * randomise offset inside the page at which the dir_info
     * lies (subject to alignment by 1 << MALLOC_MINSHIFT)
     */
    if ((p = MMAPNONE(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2), mmap_flag)) ==
        MAP_FAILED)
        wrterror(NULL, "malloc init mmap failed");
    mprotect(p + MALLOC_PAGESIZE, DIR_INFO_RSZ, PROT_READ | PROT_WRITE);
    d_avail = (DIR_INFO_RSZ - sizeof(*d)) >> MALLOC_MINSHIFT;
    d = (struct dir_info *)(p + MALLOC_PAGESIZE +
        (arc4random_uniform(d_avail) << MALLOC_MINSHIFT));

    rbytes_init(d);
    d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS;
    regioninfo_size = d->regions_total * sizeof(struct region_info);
    d->r = MMAP(regioninfo_size, mmap_flag);
    if (d->r == MAP_FAILED) {
        d->regions_total = 0;
        wrterror(NULL, "malloc init mmap failed");
    }
    for (i = 0; i <= MALLOC_MAXSHIFT; i++) {
        LIST_INIT(&d->chunk_info_list[i]);
        for (j = 0; j < MALLOC_CHUNK_LISTS; j++)
            LIST_INIT(&d->chunk_dir[i][j]);
...
...
...
In the above code, inside function omalloc_poolinit(), first, it will
allocate dir_info structure with a guard page on *both sides* like
[guard page] <dir_info> [guard page]?

And, why it is initializing the list  chunk_info_list to 32 times and
chunk_dir to 64 times, that is chunk_info_list[0...31] and
chunk_dir[0...31][0...31]?


Could someone please provide some hints on the above queries?

Regards,
Neeraj

Reply via email to