ack/lang/cem/libcc.ansi/stdlib/malloc/log.c
1994-06-24 14:02:31 +00:00

130 lines
2.5 KiB
C

/* $Id$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#include "param.h"
#include "impl.h"
#include "check.h"
#include "log.h"
/* Logical manipulations.
The chunks are properly chained in the physical chain.
*/
privatedata mallink *free_list[MAX_FLIST+1];
public
link_free_chunk(register mallink *ml)
{
/* The free chunk ml is inserted in its proper logical
chain.
*/
register mallink **mlp = &free_list[0];
register size_type n = size_of(ml);
register mallink *ml1;
assert(n < (1L << LOG_MAX_SIZE));
do {
n >>= 1;
mlp++;
}
while (n >= MIN_SIZE);
ml1 = *--mlp;
set_log_prev(ml, MAL_NULL);
set_log_next(ml, ml1);
calc_checksum(ml);
if (ml1) {
/* link backwards
*/
set_log_prev(ml1, ml);
calc_checksum(ml1);
}
*mlp = ml;
}
public
unlink_free_chunk(register mallink *ml)
{
/* Unlinks a free chunk from (the middle of) the
logical chain.
*/
register mallink *next = log_next_of(ml);
register mallink *prev = log_prev_of(ml);
if (!prev) {
/* it is the first in the chain */
register mallink **mlp = &free_list[-1];
register size_type n = size_of(ml);
assert(n < (1L << LOG_MAX_SIZE));
do {
n >>= 1;
mlp++;
}
while (n >= MIN_SIZE);
*mlp = next;
}
else {
set_log_next(prev, next);
calc_checksum(prev);
}
if (next) {
set_log_prev(next, prev);
calc_checksum(next);
}
}
public mallink *
search_free_list(int class, size_t n)
{
/* Searches the free_list[class] for a chunk of at least size n;
since it is searching a slightly undersized list,
such a block may not be there.
*/
register mallink *ml;
for (ml = free_list[class]; ml; ml = log_next_of(ml))
if (size_of(ml) >= n)
return ml;
return MAL_NULL; /* nothing found */
}
public mallink *
first_present(int class)
{
/* Find the index i in free_list[] such that:
i >= class && free_list[i] != MAL_NULL.
Return MAL_NULL if no such i exists;
Otherwise, return the first block of this list, after
unlinking it.
*/
register mallink **mlp, *ml;
for (mlp = &free_list[class]; mlp < &free_list[MAX_FLIST]; mlp++) {
if ((ml = *mlp) != MAL_NULL) {
*mlp = log_next_of(ml); /* may be MAL_NULL */
if (*mlp) {
/* unhook backward link
*/
set_log_prev(*mlp, MAL_NULL);
calc_checksum(*mlp);
}
return ml;
}
}
return MAL_NULL;
}
#ifdef CHECK
public mallink *
free_list_entry(int i) {
/* To allow maldump.c access to log.c's private data.
*/
return free_list[i];
}
#endif /* CHECK */