int process_avail, process_spare;
-struct process_item process_head_core, process_head_swap;
+struct lru_item lru_head_core, lru_head_swap;
#if 1
static void check_invariants() {
swap_head.spare -
process_spare;
for (int i = 0; i < n_processes; ++i)
- if (processes[i].item.prev && processes[i].item.next) {
+ if (processes[i].lru_item.prev && processes[i].lru_item.next) {
assert(
processes[i].size ==
(
// in-core LRU list processes:
// must have core, can't have swap except the last
for (
- struct process *p = (struct process *)process_head_core.next;
- (struct process_item *)p != &process_head_core;
- p = (struct process *)p->item.next
+ struct process *p = (struct process *)lru_head_core.next;
+ (struct lru_item *)p != &lru_head_core;
+ p = (struct process *)p->lru_item.next
) {
- assert(p->item.prev->next == &p->item && p->item.next->prev == &p->item);
+ assert(p->lru_item.prev->next == &p->lru_item);
+ assert(p->lru_item.next->prev == &p->lru_item);
assert(p->core_item.prev);
- assert(p->swap_item.prev == NULL || p->item.next == &process_head_core);
+ assert(p->swap_item.prev == NULL || p->lru_item.next == &lru_head_core);
}
// in-swap LRU list processes:
// may have swap, can't have core
for (
- struct process *p = (struct process *)process_head_swap.next;
- (struct process_item *)p != &process_head_swap;
- p = (struct process *)p->item.next
+ struct process *p = (struct process *)lru_head_swap.next;
+ (struct lru_item *)p != &lru_head_swap;
+ p = (struct process *)p->lru_item.next
) {
- assert(p->item.prev->next == &p->item && p->item.next->prev == &p->item);
+ assert(p->lru_item.prev->next == &p->lru_item);
+ assert(p->lru_item.next->prev == &p->lru_item);
assert(p->core_item.prev == NULL);
}
}
process_avail = core_head.avail + swap_head.avail - spare;
process_spare = spare;
- process_head_core.prev = &process_head_core;
- process_head_core.next = &process_head_core;
+ lru_head_core.prev = &lru_head_core;
+ lru_head_core.next = &lru_head_core;
- process_head_swap.prev = &process_head_swap;
- process_head_swap.next = &process_head_swap;
+ lru_head_swap.prev = &lru_head_swap;
+ lru_head_swap.next = &lru_head_swap;
check_invariants();
}
do {
printf("victimized %d\n", (int)(victim - processes));
// remove from tail of in-core LRU list
- victim->item.prev->next = victim->item.next;
- victim->item.next->prev = victim->item.prev;
+ victim->lru_item.prev->next = victim->lru_item.next;
+ victim->lru_item.next->prev = victim->lru_item.prev;
// insert at head of in-swap LRU list
- victim->item.prev = &process_head_swap;
- victim->item.next = process_head_swap.next;
- victim->item.prev->next = &victim->item;
- victim->item.next->prev = &victim->item;
+ victim->lru_item.prev = &lru_head_swap;
+ victim->lru_item.next = lru_head_swap.next;
+ victim->lru_item.prev->next = &victim->lru_item;
+ victim->lru_item.next->prev = &victim->lru_item;
// remove from core pool for efficiency
// note: if zero length it's neither in core nor swap pool
loop_entry:
// there must be a victim, based on calculations above
- victim = (struct process *)process_head_core.prev;
- assert((struct process_item *)victim != &process_head_core);
+ victim = (struct process *)lru_head_core.prev;
+ assert((struct lru_item *)victim != &lru_head_core);
size = victim->core_item.limit - victim->core_item.base;
} while (size == 0);
int swap_out;
// must not be already allocated
- assert(process->item.prev == NULL && process->item.next == NULL);
+ assert(process->lru_item.prev == NULL && process->lru_item.next == NULL);
// check size, disregarding fragmentation
if (process_avail < size)
process->swap_item.prev = NULL;
// insert at head of in-core LRU list
- process->item.prev = &process_head_core;
- process->item.next = process_head_core.next;
- process->item.prev->next = &process->item;
- process->item.next->prev = &process->item;
+ process->lru_item.prev = &lru_head_core;
+ process->lru_item.next = lru_head_core.next;
+ process->lru_item.prev->next = &process->lru_item;
+ process->lru_item.next->prev = &process->lru_item;
// track total allocation
process->size = size;
int swap_out;
// must be already allocated
- assert(process->item.prev && process->item.next);
+ assert(process->lru_item.prev && process->lru_item.next);
// must be fully in core
assert(process->swap_item.prev == NULL);
int swap_in, swap_out;
// must be already allocated
- assert(process->item.prev && process->item.next);
+ assert(process->lru_item.prev && process->lru_item.next);
// remove from whichever LRU list it's in
- process->item.prev->next = process->item.next;
- process->item.next->prev = process->item.prev;
+ process->lru_item.prev->next = process->lru_item.next;
+ process->lru_item.next->prev = process->lru_item.prev;
// insert at head of in-core LRU list
- process->item.prev = &process_head_core;
- process->item.next = process_head_core.next;
- process->item.prev->next = &process->item;
- process->item.next->prev = &process->item;
+ process->lru_item.prev = &lru_head_core;
+ process->lru_item.next = lru_head_core.next;
+ process->lru_item.prev->next = &process->lru_item;
+ process->lru_item.next->prev = &process->lru_item;
// if removed from core pool for efficiency, put back in
// note: this can only happen if it came from in-swap LRU list
void process_free(struct process *process) {
// must be already allocated
- assert(process->item.prev && process->item.next);
+ assert(process->lru_item.prev && process->lru_item.next);
// remove from whichever LRU list it's in
- process->item.prev->next = process->item.next;
- process->item.next->prev = process->item.prev;
+ process->lru_item.prev->next = process->lru_item.next;
+ process->lru_item.next->prev = process->lru_item.prev;
#ifndef NDEBUG
- process->item.prev = NULL;
- process->item.next = NULL;
+ process->lru_item.prev = NULL;
+ process->lru_item.next = NULL;
#endif
// free from core and/or swap pools if there
rassert(process >= 0 && process < n_processes);
rassert(size >= 0 && size < core_size);
rassert(success >= 0 && success < 2);
- rassert(processes[process].item.prev == NULL);
+ rassert(processes[process].lru_item.prev == NULL);
bool result = process_alloc(processes + process, size);
printf(
"alloc %d %d %d: %s\n",
if (!success) {
printf("undo\n");
process_free(processes + process);
- processes[process].item.prev = NULL;
+ processes[process].lru_item.prev = NULL;
}
else {
int base = processes[process].core_item.base;
rassert(old_size >= 0 && old_size < core_size);
rassert(size >= 0 && size < core_size);
rassert(success >= 0 && success < 2);
- if (processes[process].item.prev == NULL)
+ if (processes[process].lru_item.prev == NULL)
printf(
"realloc %d %d %d %d: not allocated, ignore\n",
process,
int process;
rassert(scanf("%d", &process) == 1);
rassert(process >= 0 && process < n_processes);
- if (processes[process].item.prev == NULL)
+ if (processes[process].lru_item.prev == NULL)
printf("run %d: not allocated, ignore\n", process);
else {
process_run(processes + process);
rassert(scanf("%d %d", &process, &old_size) == 2);
rassert(process >= 0 && process < n_processes);
rassert(old_size >= 0 && old_size < core_size);
- if (processes[process].item.prev == NULL)
+ if (processes[process].lru_item.prev == NULL)
printf(
"free %d %d: not allocated, ignore\n",
process,
bool in_swap = processes[process].swap_item.prev != NULL;
rassert(processes[process].size <= old_size);
process_free(processes + process);
- processes[process].item.prev = NULL;
+ processes[process].lru_item.prev = NULL;
printf(
"free %d %d(%d): ok\n",
process,
done:
printf("final state:\n");
for (int i = 0; i < n_processes; ++i) {
- if (processes[i].item.prev == NULL)
+ if (processes[i].lru_item.prev == NULL)
printf("process %d: not allocated\n", i);
else {
bool in_core = processes[i].core_item.prev != NULL;