int process_avail;
-struct lru_item lru_head;
-
-struct process *victim;
+struct lru_item lru_head, *victim;
void process_init(int n, int spare) {
processes = calloc(n, sizeof(struct process));
lru_head.prev = &lru_head;
lru_head.next = &lru_head;
-
- victim = NULL;
+ victim = &lru_head;
}
// note: swap_out argument can be negative, indicates a no-op
static bool do_swap_out(int swap_out) {
- int victim_core_blocks;
+ struct process *process;
+ int core_blocks;
int blocks, swap_base, core_base;
int paras;
#ifndef INDIRECT_CORE
// loop entry code for the case of an existing victim
if (swap_out > 0) {
- if (victim) {
+ if (victim != &lru_head) {
+ process = (struct process *)(
+ (char *)victim - offsetof(struct process, lru_item)
+ );
+
// calculate amount to swap out
- victim_core_blocks =
+ core_blocks =
#ifndef INDIRECT_CORE
- victim->core_item.limit - victim->core_item.base;
+ process->core_item.limit - process->core_item.base;
#else
- victim->core_item.limit - victim->core_item.base - victim->swap_blocks;
+ process->core_item.limit - process->core_item.base - process->swap_blocks;
#endif
#ifndef INDIRECT_SWAP
- blocks = swap_out < victim_core_blocks ? swap_out : victim_core_blocks;
+ blocks = swap_out < core_blocks ? swap_out : core_blocks;
#else
blocks = swap_block_pool.avail;
if (blocks == 0)
return false;
if (blocks > swap_out)
blocks = swap_out;
- if (blocks > victim_core_blocks)
- blocks = victim_core_blocks;
+ if (blocks > core_blocks)
+ blocks = core_blocks;
#endif /* INDIRECT_SWAP */
- printf("existing victim %d, swap out %d of %d\n", (int)(victim - processes), blocks, victim_core_blocks);
+ printf("existing victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
// increase swap allocation
goto loop_entry;
// loop for the case of no existing victim
do {
- // calculate amount to swap out
- assert(lru_head.prev != &lru_head);
- victim = (struct process *)(
- (char *)lru_head.prev - offsetof(struct process, lru_item)
+ victim = lru_head.prev;
+ assert(victim != &lru_head);
+ process = (struct process *)(
+ (char *)victim - offsetof(struct process, lru_item)
);
- assert(victim->swap_blocks == 0);
- victim_core_blocks =
- victim->core_item.limit - victim->core_item.base;
+
+ // calculate amount to swap out
+ assert(process->swap_blocks == 0);
+ core_blocks =
+ process->core_item.limit - process->core_item.base;
#ifndef INDIRECT_SWAP
- blocks = swap_out < victim_core_blocks ? swap_out : victim_core_blocks;
+ blocks = swap_out < core_blocks ? swap_out : core_blocks;
#else /* INDIRECT_SWAP */
blocks = swap_block_pool.avail;
if (blocks == 0)
{
- victim = NULL;
+ victim = &lru_head;
return false;
}
if (blocks > swap_out)
blocks = swap_out;
- if (blocks > victim_core_blocks)
- blocks = victim_core_blocks;
+ if (blocks > core_blocks)
+ blocks = core_blocks;
#endif /* INDIRECT_SWAP */
- printf("new victim %d, swap out %d of %d\n", (int)(victim - processes), blocks, victim_core_blocks);
+ printf("new victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
// remove from LRU list
- victim->lru_item.prev->next = victim->lru_item.next;
- victim->lru_item.next->prev = victim->lru_item.prev;
- victim->lru_item.prev = NULL; // indicates not runnable
+ process->lru_item.prev->next = process->lru_item.next;
+ process->lru_item.next->prev = process->lru_item.prev;
+ process->lru_item.prev = NULL; // indicates not runnable
loop_entry:
// calculate transfer parameters
- victim_core_blocks -= blocks;
- victim->swap_blocks += blocks;
- swap_base = victim->swap_item.limit - victim->swap_blocks;
+ core_blocks -= blocks;
+ process->swap_blocks += blocks;
+ swap_base = process->swap_item.limit - process->swap_blocks;
#ifndef INDIRECT_CORE
- core_base = victim->core_item.limit - blocks;
+ core_base = process->core_item.limit - blocks;
#else /* INDIRECT_CORE */
- core_base = victim->core_item.limit - victim->swap_blocks;
+ core_base = process->core_item.limit - process->swap_blocks;
#endif /* INDIRECT_CORE */
paras = blocks << BLOCK_PARAS_SHIFT;
#endif /* INDIRECT_CORE */
// see if victim fully swapped out
- if (victim_core_blocks) {
+ if (core_blocks) {
#ifndef INDIRECT_CORE
// no, reduce core allocation
rassert(
pool_alloc(
&core_table,
- &victim->core_item,
- victim_core_blocks,
+ &process->core_item,
+ core_blocks,
POOL_ALLOC_MODE_MOVEABLE |
POOL_ALLOC_MODE_REALLOC
)
return swap_out == blocks;
}
assert(
- victim->swap_blocks ==
- victim->swap_item.limit - victim->swap_item.base
+ process->swap_blocks ==
+ process->swap_item.limit - process->swap_item.base
);
- printf("victimized %d\n", (int)(victim - processes));
+ printf("victimized %d\n", (int)(process - processes));
#ifndef INDIRECT_CORE
// remove from core pool
- pool_free(&core_table, &victim->core_item);
+ pool_free(&core_table, &process->core_item);
#endif /* ! INDIRECT_CORE */
- victim->flags &= ~PROCESS_FLAGS_CORE_ITEM;
- victim = NULL;
+ process->flags &= ~PROCESS_FLAGS_CORE_ITEM;
+ victim = &lru_head;
swap_out -= blocks;
} while (swap_out);
}
void process_run(struct process *process) {
- int blocks, process_core_blocks;
+ int blocks, core_blocks;
int swap_base, core_base;
int paras;
#ifndef INDIRECT_CORE
assert(process->swap_blocks == 0);
// yes, remove from LRU list
- assert(process != victim);
+ assert(victim != &process->lru_item);
process->lru_item.prev->next = process->lru_item.next;
process->lru_item.next->prev = process->lru_item.prev;
}
// no, need to swap some in
// loop entry code for case of fully in swap
- if (process != victim) {
+ if (victim != &process->lru_item) {
assert((process->flags & PROCESS_FLAGS_CORE_ITEM) == 0);
assert(
process->swap_blocks ==
blocks = process->swap_blocks;
// add to core pool
- process_core_blocks = 0;
+ core_blocks = 0;
#ifndef INDIRECT_CORE
rassert(
pool_alloc(
assert(process->swap_blocks);
// victim, take over the dedicated pool items
- process_core_blocks =
+ core_blocks =
#ifndef INDIRECT_CORE
- victim->core_item.limit - victim->core_item.base;
+ process->core_item.limit - process->core_item.base;
#else /* INDIRECT_CORE */
- victim->core_item.limit - victim->core_item.base - victim->swap_blocks;
+ process->core_item.limit -
+ process->core_item.base -
+ process->swap_blocks;
#endif /* INDIRECT_CORE */
- victim = NULL;
+ victim = &lru_head;
// loop for case of partially in core, partially in swap
do {
pool_alloc(
&core_table,
&process->core_item,
- process_core_blocks + blocks,
+ core_blocks + blocks,
POOL_ALLOC_MODE_MOVEABLE |
POOL_ALLOC_MODE_REALLOC
)
#else /* INDIRECT_CORE */
core_base = process->core_item.limit - process->swap_blocks;
#endif /* INDIRECT_CORE */
- process_core_blocks += blocks;
+ core_blocks += blocks;
process->swap_blocks -= blocks;
paras = blocks << BLOCK_PARAS_SHIFT;
assert(process->flags & PROCESS_FLAGS_ACTIVE);
// remove from LRU list
+ if (victim == &process->lru_item)
+ victim = &lru_head;
if (process->lru_item.prev != NULL) {
process->lru_item.prev->next = process->lru_item.next;
process->lru_item.next->prev = process->lru_item.prev;
#endif /* INDIRECT_SWAP */
pool_free(&swap_table, &process->swap_item);
- // fix this later
- if (process == victim)
- victim = NULL;
-
// track total allocation
process_avail += (process->paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
process->flags = 0;