/media/sda-magnetic/david/Dok-15-2023-11-27/fernuni-hagen/cs-i-ii/fsm/fsm/c-2020-11-08/alloc.c


PUBLIC free_mem (phys_clicks base, phys_clicks clicks) {
    register struct *hp, *new_ptr, *prev_ptr;
    
    if ((new_ptr = free_slots) == NIL_HOLE) 
        panic ("Hole table full", NO_NUM);
    
    new_ptr->h_base = base;
    new_ptr->h_len = clicks;
    free_slots = new_ptr->h_next;
    
    hp = hole_head;
    
    if (hp == NIL_HOLE || base <= hp->h_base) {
        new_ptr->h_next = hp;
        hole_head = new_ptr;
        merge (new_ptr);
        return;
    }
    
    while (hp != NIL_HOLE && base > hp->h_base) {
        prev_ptr = hp;
        hp = hp->h_next;
    }
    
    new_ptr->h_next = prev_ptr->h_next;
    prev_ptr->h_next = new_ptr;
    merge (prev_ptr);
}

PRIVATE merge (register struct hole *hp) {
    register struct hole *next_ptr;
    
    if ((next_ptr = hp->h_next) == NIL_HOLE)
        return;
    if ((hp->h_base + hp->h_len == next_ptr->h_base) {
        hp->h_len += next_ptr->h_len;
        del_slot (hp, next_ptr);
    }
    else {
        hp = next_ptr;
    }
    
    if ((next_ptr = hp->h_next) == NIL_HOLE)
        return;
    if (hp->h_base + hp->h_len == next_ptr->h_base) {
        hp->h_len += next_ptr->h_len;
        del_slot (hp, next_ptr);
    }
}
    
PUBLIC phys_click max_hole () {
    register struct hole *hp;
    register phys_clicks max;
    
    hp = hole_head;
    max = 0;
    while (hp != NIL_HOLE) {
        if (hp->h_len > max) 
            max = hp->h_len;
        hp = hp->h_next;
    }
    return (max);
}