1989-12-18 13:31:20 +00:00
|
|
|
/* $Header$ */
|
|
|
|
/*
|
|
|
|
* (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.
|
|
|
|
*/
|
|
|
|
|
1993-10-06 13:15:12 +00:00
|
|
|
privatedata mallink *free_list[MAX_FLIST+1];
|
1989-12-18 13:31:20 +00:00
|
|
|
|
|
|
|
public
|
|
|
|
link_free_chunk(register mallink *ml)
|
|
|
|
{
|
|
|
|
/* The free chunk ml is inserted in its proper logical
|
|
|
|
chain.
|
|
|
|
*/
|
1993-10-06 13:15:12 +00:00
|
|
|
register mallink **mlp = &free_list[0];
|
1990-08-24 17:05:53 +00:00
|
|
|
register size_type n = size_of(ml);
|
1989-12-18 13:31:20 +00:00
|
|
|
register mallink *ml1;
|
|
|
|
|
|
|
|
assert(n < (1L << LOG_MAX_SIZE));
|
|
|
|
|
|
|
|
do {
|
|
|
|
n >>= 1;
|
|
|
|
mlp++;
|
|
|
|
}
|
|
|
|
while (n >= MIN_SIZE);
|
|
|
|
|
1993-10-06 13:15:12 +00:00
|
|
|
ml1 = *--mlp;
|
1989-12-18 13:31:20 +00:00
|
|
|
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];
|
1990-08-24 17:05:53 +00:00
|
|
|
register size_type n = size_of(ml);
|
1989-12-18 13:31:20 +00:00
|
|
|
|
|
|
|
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 */
|