logoalt Hacker News

foobarian • today at 2:41 PM • 2 replies • view on HN

Disagree, I found malloc source useful, and writing a toy allocator especially useful because you learn about the brk() syscall which is a great breadcrumb into kernel land and a great bridge to connect the memory mapping lessons from computer architecture with application code.


Replies

stevekemp • today at 2:55 PM

Depending on how low-level you're going, you don't even need to call brk.

My toy stop/copy GC and allocation routines just have this:

    %define HEAP_SIZE (4 * 1024 * 1024 * 1024)

    .section bss
    ;;
    ;; Two heaps so we can flip-flop between them
    ;;
    heap_a:
        resb HEAP_SIZE
    heap_a_end:
    heap_b:
        resb HEAP_SIZE
    heap_b_end:
Of course there are other syscalls involved in my compiler/runtime, but for memory allocations the static area sufficed for me.
Joker_vD • today at 4:00 PM

> and writing a toy allocator especially useful because you learn about the brk() syscall

Nobody in their right mind (except musl) use brk(2) nowadays; mmap(2) is pretty much universally accessible, and brk() has been non-portable for more than 20 years already (POSIX ditched it in 2001) anyhow. For goodness sake, stop keeping this stupid API from VM-lacking PDP-7 alive, and let it go away!

Edit: also, I have no idea how musl even uses it:

    uintptr_t new = ctx.brk + pagesize;
    int need_guard = 0;
    if (!ctx.brk) {
        need_guard = 1;
        ctx.brk = brk(0);
        // some ancient kernels returned _ebss
        // instead of next page as initial brk.
        ctx.brk += -ctx.brk & (pagesize-1);
        new = ctx.brk + 2*pagesize;
    }
    if (brk(new) != new) {
        ctx.brk = -1;
    } else {
        if (need_guard) mmap((void *)ctx.brk, pagesize,
                PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
        ctx.brk = new;
        ctx.avail_meta_areas = (void *)(new - pagesize);
        ctx.avail_meta_area_count = pagesize>>12;
        need_unprotect = 0;
    }
That's... not what brk() returns; it returns 0 on success and -1 on failure. Huh?