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);
}