struct process *victim;
#ifdef PREALLOCATE_CORE
int victim_core_blocks;
-#else
-struct pool_item victim_core_item;
#endif
#ifdef PREALLOCATE_SWAP
int victim_swap_blocks;
-#else
-struct pool_item victim_swap_item;
#endif
#if 1
if (victim == NULL) {
#ifdef PREALLOCATE_CORE
assert(victim_core_blocks == 0);
-#else
- assert(victim_core_item.prev == NULL && victim_core_item.next == NULL);
#endif
#ifdef PREALLOCATE_SWAP
assert(victim_swap_blocks == 0);
-#else
- assert(victim_swap_item.prev == NULL && victim_swap_item.prev == NULL);
#endif
}
for (int i = 0; i < n_processes; ++i)
if (processes[i].size == -1L) {
-#ifdef PREALLOCATE_CORE
assert(
processes[i].core_item.prev == NULL &&
processes[i].core_item.next == NULL
);
-#endif
-#ifdef PREALLOCATE_SWAP
assert(
processes[i].swap_item.prev == NULL &&
processes[i].swap_item.next == NULL
);
-#endif
}
else {
#ifdef PREALLOCATE_CORE
assert(processes + i != victim);
assert(processes[i].lru_item.prev->next == &processes[i].lru_item);
assert(processes[i].lru_item.next->prev == &processes[i].lru_item);
-#ifdef PREALLOCATE_CORE
-#ifndef PREALLOCATE_SWAP
+#ifndef PREALLOCATE_CORE
+ assert(processes[i].core_item.prev && processes[i].core_item.next);
assert(
- processes[i].pool_item.prev == NULL &&
- processes[i].pool_item.next == NULL
+ (int)((processes[i].size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT) ==
+ processes[i].core_item.limit - processes[i].core_item.base
);
#endif
-#else
- assert(processes[i].pool_item.prev && processes[i].pool_item.next);
+#ifndef PREALLOCATE_SWAP
assert(
- (int)((processes[i].size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT) ==
- processes[i].pool_item.limit - processes[i].pool_item.base
+ processes[i].swap_item.prev == NULL &&
+ processes[i].swap_item.next == NULL
);
#endif
}
else if (processes + i == victim) {
-#if !defined(PREALLOCATE_CORE) || !defined(PREALLOCATE_SWAP)
- assert(
- processes[i].pool_item.prev == NULL &&
- processes[i].pool_item.next == NULL
- );
-#endif
+ assert(victim->core_item.prev && victim->core_item.next);
#ifndef PREALLOCATE_CORE
- assert(victim_core_item.prev && victim_core_item.next);
- int victim_core_blocks = victim_core_item.limit - victim_core_item.base;
+ int victim_core_blocks =
+ victim->core_item.limit - victim->core_item.base;
#endif
assert(victim_core_blocks);
+ assert(victim->swap_item.prev && victim->swap_item.next);
#ifndef PREALLOCATE_SWAP
- assert(victim_swap_item.prev && victim_swap_item.next);
- int victim_swap_blocks = victim_swap_item.limit - victim_swap_item.base;
+ int victim_swap_blocks =
+ victim->swap_item.limit - victim->swap_item.base;
#endif
assert(victim_swap_blocks);
assert(
);
}
else {
-#ifdef PREALLOCATE_SWAP
#ifndef PREALLOCATE_CORE
assert(
- processes[i].pool_item.prev == NULL &&
- processes[i].pool_item.next == NULL
+ processes[i].core_item.prev == NULL &&
+ processes[i].core_item.next == NULL
);
#endif
-#else
- assert(processes[i].pool_item.prev && processes[i].pool_item.next);
+#ifndef PREALLOCATE_SWAP
+ assert(processes[i].swap_item.prev && processes[i].swap_item.next);
assert(
(int)((processes[i].size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT) ==
- processes[i].pool_item.limit - processes[i].pool_item.base
+ processes[i].swap_item.limit - processes[i].swap_item.base
);
#endif
}
#ifndef NDEBUG
#ifdef PREALLOCATE_CORE
victim_core_blocks = 0;
-#else
- memset(&victim_core_item, 0, sizeof(victim_core_item));
#endif
#ifdef PREALLOCATE_SWAP
victim_swap_blocks = 0;
-#else
- memset(&victim_swap_item, 0, sizeof(victim_swap_item));
#endif
#endif
check_invariants();
if (victim) {
// calculate amount to swap out
#ifndef PREALLOCATE_CORE
- victim_core_blocks = victim_core_item.limit - victim_core_item.base;
+ victim_core_blocks = victim->core_item.limit - victim->core_item.base;
#endif
#ifndef PREALLOCATE_SWAP
- victim_swap_blocks = victim_swap_item.limit - victim_swap_item.base;
+ victim_swap_blocks = victim->swap_item.limit - victim->swap_item.base;
#endif
blocks = swap_out < victim_core_blocks ? swap_out : victim_core_blocks;
printf("existing victim %d, swap out %d of %d\n", (int)(victim - processes), blocks, victim_core_blocks);
// increase swap allocation
victim_swap_blocks += blocks;
#ifndef PREALLOCATE_SWAP
- rassert(swap_table_realloc(&victim_swap_item, victim_swap_blocks));
+ rassert(swap_table_realloc(&victim->swap_item, victim_swap_blocks));
#endif
goto loop_entry;
}
victim->lru_item.next->prev = victim->lru_item.prev;
victim->lru_item.prev = NULL; // indicates not runnable
- // fully in core, take over only the per-process core item
-#ifdef PREALLOCATE_CORE
+ // fully in core, only the core item is meaningful
victim_core_blocks =
- (int)((victim->size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
-#else
- pool_move_item(&victim->pool_item, &victim_core_item);
- victim_core_blocks = victim_core_item.limit - victim_core_item.base;
- assert(
- victim_core_blocks ==
- (int)((victim->size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT)
- );
-#endif
+ victim->core_item.limit - victim->core_item.base;
// calculate amount to swap out
blocks = swap_out < victim_core_blocks ? swap_out : victim_core_blocks;
// add to swap pool, using dedicated swap item
victim_swap_blocks = blocks;
#ifndef PREALLOCATE_SWAP
- rassert(swap_table_alloc(&victim_swap_item, victim_swap_blocks));
+ rassert(swap_table_alloc(&victim->swap_item, victim_swap_blocks));
#endif
loop_entry:
if (victim_core_blocks) {
#ifndef PREALLOCATE_CORE
// no, reduce core allocation, using dedicated core item
- rassert(core_table_realloc_base(&victim_core_item, victim_core_blocks));
+ rassert(
+ core_table_realloc_base(&victim->core_item, victim_core_blocks)
+ );
#endif
// in this case there can't be any further victim to swap
printf("victimized %d\n", (int)(victim - processes));
#ifndef PREALLOCATE_CORE
- // remove from core pool, using dedicated core item
- core_table_free(&victim_core_item);
-#endif
-
-#ifndef PREALLOCATE_SWAP
- // move dedicated to per-process swap item
- pool_move_item(&victim_swap_item, &victim->pool_item);
+ // remove from core pool
+ core_table_free(&victim->core_item);
#endif
swap_out -= blocks;
// allocate core and possible swap
#ifdef MOVEABLE_CORE
- rassert(core_table_alloc(&PER_PROCESS_CORE_ITEM(process), blocks));
+ rassert(core_table_alloc(&process->core_item, blocks));
#else
- if (!core_table_alloc(&PER_PROCESS_CORE_ITEM(process), blocks)) {
+ if (!core_table_alloc(&process->core_item, blocks)) {
#if defined(PREALLOCATE_SWAP) && !defined(MOVEABLE_SWAP)
swap_table_free(&process->swap_item);
#endif
// populate new table with physical blocks
rassert(
core_block_alloc(
- core_table_mem + PER_PROCESS_CORE_ITEM(process).base,
+ core_table_mem + process->core_item.base,
blocks
)
);
// reallocate core and possible swap
#ifdef MOVEABLE_CORE
- rassert(core_table_realloc(&PER_PROCESS_CORE_ITEM(process), blocks));
+ rassert(core_table_realloc(&process->core_item, blocks));
#else
- if (!core_table_realloc(&PER_PROCESS_CORE_ITEM(process), blocks)) {
+ if (!core_table_realloc(&process->core_item, blocks)) {
#if defined(PREALLOCATE_SWAP) && !defined(MOVEABLE_SWAP)
swap_table_free(&process->swap_item);
rassert(swap_table_alloc(&process->swap_item, old_blocks));
if (blocks_change >= 0)
rassert(
core_block_alloc(
- core_table_mem + PER_PROCESS_CORE_ITEM(process).limit - blocks_change,
+ core_table_mem + process->core_item.limit - blocks_change,
blocks_change
)
);
else
core_block_free(
- core_table_mem + PER_PROCESS_CORE_ITEM(process).limit,
+ core_table_mem + process->core_item.limit,
-blocks_change
);
#endif
void process_run(struct process *process) {
int blocks, swap_out;
- int process_core_blocks;
-#ifndef PREALLOCATE_CORE
- struct pool_item process_core_item;
-#endif
- int process_swap_blocks;
-#ifndef PREALLOCATE_SWAP
- struct pool_item process_swap_item;
-#endif
+ int process_core_blocks, process_swap_blocks;
int swap_base, core_base;
long size;
}
else {
// no, need to swap some in
-#ifndef NDEBUG
-#ifndef PREALLOCATE_CORE
- memset(&process_core_item, 0, sizeof(process_core_item));
-#endif
-#ifndef PREALLOCATE_SWAP
- memset(&process_swap_item, 0, sizeof(process_swap_item));
-#endif
-#endif
// loop entry code for case of fully in swap
if (process != victim) {
- // fully in swap, take over only the per-process swap item
-#ifdef PREALLOCATE_SWAP
+ // fully in swap, only the swap item is meaningful
process_swap_blocks =
- (int)((process->size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
-#else
- pool_move_item(&process->pool_item, &process_swap_item);
- process_swap_blocks = process_swap_item.limit - process_swap_item.base;
- assert(
- process_swap_blocks ==
- (int)((process->size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT)
- );
-#endif
+ process->swap_item.limit - process->swap_item.base;
// calculate amounts to swap out then in
blocks = process_swap_blocks;
// add to core pool, using dedicated core item
process_core_blocks = blocks;
#ifndef PREALLOCATE_CORE
- rassert(core_table_alloc(&process_core_item, process_core_blocks));
+ rassert(core_table_alloc(&process->core_item, process_core_blocks));
#endif
goto loop_entry_full;
}
// victim, take over the dedicated pool items
- victim = NULL;
-#ifdef PREALLOCATE_CORE
- process_core_blocks = victim_core_blocks;
-#ifndef NDEBUG
+ process_core_blocks = DEDICATED_CORE_BLOCKS(victim);
+#if !defined(NDEBUG) && defined(PREALLOCATE_CORE)
victim_core_blocks = 0;
#endif
-#else
- pool_move_item(&victim_core_item, &process_core_item);
- process_core_blocks = process_core_item.limit - process_core_item.base;
-#endif
-#ifdef PREALLOCATE_SWAP
- process_swap_blocks = victim_swap_blocks;
-#ifndef NDEBUG
+ process_swap_blocks = DEDICATED_SWAP_BLOCKS(victim);
+#if !defined(NDEBUG) && defined(PREALLOCATE_SWAP)
victim_swap_blocks = 0;
#endif
-#else
- pool_move_item(&victim_swap_item, &process_swap_item);
- process_swap_blocks = process_swap_item.limit - process_swap_item.base;
+ victim = NULL;
+#ifndef PREALLOCATE_SWAP
goto loop_entry_partial;
#endif
do {
#ifndef PREALLOCATE_SWAP
// reduce swap allocation
- rassert(swap_table_realloc(&process_swap_item, process_swap_blocks));
+ rassert(swap_table_realloc(&process->swap_item, process_swap_blocks));
loop_entry_partial:
#endif
// increase core allocation
process_core_blocks += blocks;
#ifndef PREALLOCATE_CORE
- rassert(core_table_realloc_base(&process_core_item, process_core_blocks));
+ rassert(
+ core_table_realloc_base(&process->core_item, process_core_blocks)
+ );
#endif
loop_entry_full:
process_swap_blocks -= blocks;
} while (process_swap_blocks);
-#ifndef PREALLOCATE_CORE
- // move dedicated to per-process core item
- pool_move_item(&process_core_item, &process->pool_item);
-#endif
-
#ifndef PREALLOCATE_SWAP
- // remove from swap pool, using dedicated swap item
- swap_table_free(&process_swap_item);
+ // remove from swap pool
+ swap_table_free(&process->swap_item);
#endif
}
process->lru_item.next->prev = process->lru_item.prev;
#ifdef INDIRECT_CORE
- int core_base = PER_PROCESS_CORE_ITEM(process).base;
+ int core_base = process->core_item.base;
core_block_free(
core_table_mem + core_base,
- PER_PROCESS_CORE_ITEM(process).limit - core_base
+ process->core_item.limit - core_base
);
#endif
#ifndef PREALLOCATE_CORE
- core_table_free(&process->pool_item);
+ core_table_free(&process->core_item);
#endif
}
else if (process == victim) {
#ifdef PREALLOCATE_CORE
victim_core_blocks = 0;
#else
- core_table_free(&victim_core_item);
+ core_table_free(&victim->core_item);
#endif
#ifdef INDIRECT_SWAP
swap_block_free(
- swap_table_mem + DEDICATED_SWAP_ITEM(victim).base,
+ swap_table_mem + victim->swap_item.base,
DEDICATED_SWAP_BLOCKS(victim)
);
#endif
#ifdef PREALLOCATE_SWAP
victim_swap_blocks = 0;
#else
- swap_table_free(&victim_swap_item);
+ swap_table_free(&victim->swap_item);
#endif
victim = NULL;
}
else {
// fully in swap, remove from swap pool
#ifdef INDIRECT_SWAP
- int swap_base = PER_PROCESS_SWAP_ITEM(process).base;
+ int swap_base = process->swap_item.base;
swap_block_free(
swap_table_mem + swap_base,
- PER_PROCESS_SWAP_ITEM(process).limit - swap_base
+ process->swap_item.limit - swap_base
);
#endif
#ifndef PREALLOCATE_SWAP
- swap_table_free(&process->pool_item);
+ swap_table_free(&process->swap_item);
#endif
}
processes[process].size = -1L;
}
else {
- int core_base = PER_PROCESS_CORE_ITEM(processes + process).base;
+ int core_base = processes[process].core_item.base;
int blocks = (int)((size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
assert(
- PER_PROCESS_CORE_ITEM(processes + process).limit ==
+ processes[process].core_item.limit ==
core_base + blocks
);
printf("new core [%d,%d)\n", core_base, core_base + blocks);
0L
);
#ifdef PREALLOCATE_SWAP
- printf("new swap [%d,%d)\n", PER_PROCESS_SWAP_ITEM(processes + process).base, PER_PROCESS_SWAP_ITEM(processes + process).limit);
+ printf("new swap [%d,%d)\n", processes[process].swap_item.base, processes[process].swap_item.limit);
#endif
}
}
if (processes[process].size == -1L)
printf("... not allocated, ignore\n");
else {
- int core_base = PER_PROCESS_CORE_ITEM(processes + process).base;
+ int core_base = processes[process].core_item.base;
int actual_old_size = processes[process].size;
int actual_old_blocks =
(int)((actual_old_size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
rassert(
- PER_PROCESS_CORE_ITEM(processes + process).limit ==
+ processes[process].core_item.limit ==
core_base + actual_old_blocks
);
int old_blocks = (int)((old_size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
rassert(actual_old_blocks <= old_blocks);
}
#ifdef PREALLOCATE_SWAP
- printf("old core [%d,%d) swap [%d,%d)\n", core_base, core_base + actual_old_blocks, PER_PROCESS_SWAP_ITEM(processes + process).base, PER_PROCESS_SWAP_ITEM(processes + process).limit);
+ printf("old core [%d,%d) swap [%d,%d)\n", core_base, core_base + actual_old_blocks, processes[process].swap_item.base, processes[process].swap_item.limit);
#else
printf("old core [%d,%d)\n", core_base, core_base + actual_old_blocks);
#endif
rassert(process_realloc(processes + process, actual_old_blocks));
}
else {
- core_base = PER_PROCESS_CORE_ITEM(processes + process).base;
+ core_base = processes[process].core_item.base;
int blocks = (int)((size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
rassert(
- PER_PROCESS_CORE_ITEM(processes + process).limit ==
+ processes[process].core_item.limit ==
core_base + blocks
);
#ifdef PREALLOCATE_SWAP
- printf("new core [%d,%d) swap [%d,%d)\n", core_base, core_base + blocks, PER_PROCESS_SWAP_ITEM(processes + process).base, PER_PROCESS_SWAP_ITEM(processes + process).limit);
+ printf("new core [%d,%d) swap [%d,%d)\n", core_base, core_base + blocks, processes[process].swap_item.base, processes[process].swap_item.limit);
#else
printf("new core [%d,%d)\n", core_base, core_base + blocks);
#endif
swap_base = -1;
swap_blocks = 0;
swap_size = 0L;
- core_base =
- PER_PROCESS_CORE_ITEM(processes + process).base;
- core_blocks =
- PER_PROCESS_CORE_ITEM(processes + process).limit - core_base;
+ core_base = processes[process].core_item.base;
+ core_blocks = processes[process].core_item.limit - core_base;
core_size = processes[process].size;
}
else if (processes + process == victim) { // victim
- swap_base = DEDICATED_SWAP_ITEM(victim).base;
+ swap_base = victim->swap_item.base;
swap_blocks = DEDICATED_SWAP_BLOCKS(victim);
swap_size = swap_blocks << BLOCK_SHIFT;
core_base = DEDICATED_CORE_BASE(victim, swap_blocks);
core_blocks = DEDICATED_CORE_BLOCKS(victim);
- core_size = processes[process].size - swap_size;
+ core_size = victim->size - swap_size;
}
else { // fully in swap
- swap_base =
- PER_PROCESS_SWAP_ITEM(processes + process).base;
- swap_blocks =
- PER_PROCESS_SWAP_ITEM(processes + process).limit - swap_base;
+ swap_base = processes[process].swap_item.base;
+ swap_blocks = processes[process].swap_item.limit - swap_base;
swap_size = processes[process].size;
core_base = -1;
core_blocks = 0;
swap_base = -1;
swap_blocks = 0;
swap_size = 0L;
- core_base =
- PER_PROCESS_CORE_ITEM(processes + i).base;
- core_blocks =
- PER_PROCESS_CORE_ITEM(processes + i).limit - core_base;
+ core_base = processes[i].core_item.base;
+ core_blocks = processes[i].core_item.limit - core_base;
core_size = processes[i].size;
}
else if (processes + i == victim) { // victim
- swap_base = DEDICATED_SWAP_ITEM(victim).base;
+ swap_base = victim->swap_item.base;
swap_blocks = DEDICATED_SWAP_BLOCKS(victim);
swap_size = swap_blocks << BLOCK_SHIFT;
core_base = DEDICATED_CORE_BASE(victim, swap_blocks);
core_blocks = DEDICATED_CORE_BLOCKS(victim);
- core_size = processes[i].size - swap_size;
+ core_size = victim->size - swap_size;
}
else { // fully in swap
- swap_base =
- PER_PROCESS_SWAP_ITEM(processes + i).base;
- swap_blocks =
- PER_PROCESS_SWAP_ITEM(processes + i).limit - swap_base;
+ swap_base = processes[i].swap_item.base;
+ swap_blocks = processes[i].swap_item.limit - swap_base;
swap_size = processes[i].size;
core_base = -1;
core_blocks = 0;