// note: swap_out argument can be negative, indicates a no-op
static bool do_swap_out(int swap_out) {
struct process *process;
- int core_blocks, swap_blocks, blocks;
- int swap_base, core_base;
+ int block, blocks;
for (; swap_out > 0; swap_out -= blocks) {
assert(victim->prev != &lru_head);
// calculate amount to swap out
#ifndef INDIRECT_CORE
- core_blocks = process->core_item.limit - process->core_item.base;
+ block = process->core_item.limit - process->core_item.base;
#else /* INDIRECT_CORE */
- core_blocks = process->core_blocks;
+ block = process->core_blocks;
#endif /* INDIRECT_CORE */
- swap_blocks =
- process->swap_item.limit - process->swap_item.base - core_blocks;
#ifndef INDIRECT_SWAP
- blocks = swap_out < core_blocks ? swap_out : core_blocks;
+ blocks = swap_out < block ? swap_out : block;
#else /* INDIRECT_SWAP */
blocks = swap_block_pool.avail;
if (blocks == 0)
return false;
if (blocks > swap_out)
blocks = swap_out;
- if (blocks > core_blocks)
- blocks = core_blocks;
+ if (blocks > block)
+ blocks = block;
#endif /* INDIRECT_SWAP */
- printf("victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
+ printf("victim %d, swap out %d of %d\n", (int)(process - processes), blocks, block);
- // calculate transfer parameters
- core_blocks -= blocks;
+ // adjust swap pointer
+ block -= blocks;
#ifdef INDIRECT_CORE
- process->core_blocks = core_blocks;
+ process->core_blocks = block;
#endif
- swap_blocks += blocks;
- swap_base = process->swap_item.limit - swap_blocks;
-#ifndef INDIRECT_CORE
- core_base = process->core_item.limit - blocks;
-#else /* INDIRECT_CORE */
- core_base = process->core_item.limit - swap_blocks;
-#endif /* INDIRECT_CORE */
// transfer data to swap
#ifdef INDIRECT_SWAP
rassert(
- block_pool_alloc(&swap_block_pool, swap_table_mem + swap_base, blocks)
+ block_pool_alloc(
+ &swap_block_pool,
+ swap_table_mem + process->swap_item.base + block,
+ blocks
+ )
);
#endif /* INDIRECT_SWAP */
- printf("write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + blocks, swap_base, swap_base + blocks);
- do_swap_read_write(core_base, swap_base, blocks, true);
+ printf("write core [%d,%d) to swap [%d,%d)\n", process->core_item.base + block, process->core_item.base + block + blocks, process->swap_item.base + block, process->swap_item.base + block + blocks);
+ do_swap_read_write(
+ process->core_item.base + block,
+ process->swap_item.base + block,
+ blocks,
+ true
+ );
#ifdef INDIRECT_CORE
- block_pool_free(&core_block_pool, core_table_mem + core_base, blocks);
+ block_pool_free(
+ &core_block_pool,
+ core_table_mem + process->core_item.base + block,
+ blocks
+ );
#endif /* INDIRECT_CORE */
// see if victim fully swapped out
- if (core_blocks) {
+ if (block) {
#ifndef INDIRECT_CORE
// no, reduce core allocation
rassert(
pool_alloc(
&core_table,
&process->core_item,
- core_blocks,
+ block,
POOL_ALLOC_MODE_MOVEABLE | POOL_ALLOC_MODE_REALLOC
)
);
}
void process_run(struct process *process) {
- int core_blocks, swap_blocks, blocks;
- int swap_base, core_base;
+ int block, swap_in, blocks;
// must be already allocated
assert(process->flags & PROCESS_FLAGS_ACTIVE);
process->lru_item.prev->next = process->lru_item.next;
process->lru_item.next->prev = process->lru_item.prev;
- do {
+ // loop to swap out then swap in
#ifndef INDIRECT_CORE
- core_blocks =
- process->flags & PROCESS_FLAGS_CORE_ITEM ?
- process->core_item.limit - process->core_item.base :
- 0;
+ block =
+ process->flags & PROCESS_FLAGS_CORE_ITEM ?
+ process->core_item.limit - process->core_item.base :
+ 0;
#else /* INDIRECT_CORE */
- core_blocks = process->core_blocks;
+ block = process->core_blocks;
#endif /* INDIRECT_CORE */
- swap_blocks =
- process->swap_item.limit - process->swap_item.base - core_blocks;
-
+ for (
+ swap_in =
+ process->swap_item.limit - process->swap_item.base - block;
+#ifndef INDIRECT_CORE
+ (process->flags & PROCESS_FLAGS_CORE_ITEM) == 0 || swap_in > 0;
+#else
+ swap_in > 0;
+#endif
+ swap_in -= blocks
+ ) {
// free up as much core as we can
#ifndef INDIRECT_CORE
- do_swap_out(swap_blocks - core_table.avail);
+ do_swap_out(swap_in - core_table.avail);
blocks = core_table.avail;
#else /* INDIRECT_CORE */
- do_swap_out(swap_blocks - core_block_pool.avail);
+ do_swap_out(swap_in - core_block_pool.avail);
blocks = core_block_pool.avail;
#endif /* INDIRECT_CORE */
- if (blocks > swap_blocks)
- blocks = swap_blocks;
+ if (blocks > swap_in)
+ blocks = swap_in;
#ifndef INDIRECT_CORE
// increase core allocation
pool_alloc(
&core_table,
&process->core_item,
- core_blocks + blocks,
+ block + blocks,
process->flags & PROCESS_FLAGS_CORE_ITEM ?
POOL_ALLOC_MODE_MOVEABLE | POOL_ALLOC_MODE_REALLOC :
POOL_ALLOC_MODE_MOVEABLE
process->flags |= PROCESS_FLAGS_CORE_ITEM;
#endif /* ! INDIRECT_CORE */
- // calculate transfer parameters
- swap_base = process->swap_item.limit - swap_blocks;
-#ifndef INDIRECT_CORE
- core_base = process->core_item.limit - blocks;
-#else /* INDIRECT_CORE */
- core_base = process->core_item.limit - swap_blocks;
-#endif /* INDIRECT_CORE */
- core_blocks += blocks;
-#ifdef INDIRECT_CORE
- process->core_blocks = core_blocks;
-#endif
- swap_blocks -= blocks;
-
// transfer data to core
#ifdef INDIRECT_CORE
rassert(
- block_pool_alloc(&core_block_pool, core_table_mem + core_base, blocks)
+ block_pool_alloc(&core_block_pool, core_table_mem + process->core_item.base + block, blocks)
);
#endif /* INDIRECT_CORE */
- printf("read swap [%d,%d) to core [%d,%d)\n", swap_base, swap_base + blocks, core_base, core_base + blocks);
- do_swap_read_write(core_base, swap_base, blocks, false);
+ printf("read swap [%d,%d) to core [%d,%d)\n", process->swap_item.base + block, process->swap_item.base + block + blocks, process->core_item.base + block, process->core_item.base + block + blocks);
+ do_swap_read_write(
+ process->core_item.base + block,
+ process->swap_item.base + block,
+ blocks,
+ false
+ );
#ifdef INDIRECT_SWAP
- block_pool_free(&swap_block_pool, swap_table_mem + swap_base, blocks);
+ block_pool_free(
+ &swap_block_pool,
+ swap_table_mem + process->swap_item.base + block,
+ blocks
+ );
#endif /* INDIRECT_SWAP */
- } while (swap_blocks);
+
+ // adjust swap pointer
+ block += blocks;
+#ifdef INDIRECT_CORE
+ process->core_blocks = block;
+#endif /* INDIRECT_CORE */
+ }
// insert at head of LRU list
process->lru_item.prev = &lru_head;
void process_free(struct process *process) {
#ifdef INDIRECT_SWAP
- int core_blocks, swap_blocks;
+ int block, swap_in;
#endif /* INDIRECT_SWAP */
// must be already allocated
#ifdef INDIRECT_SWAP
// calculate blocks before freeing anything
#ifndef INDIRECT_CORE
- core_blocks =
+ block =
process->flags & PROCESS_FLAGS_CORE_ITEM ?
process->core_item.limit - process->core_item.base :
0;
#else /* INDIRECT_CORE */
- core_blocks = process->core_blocks;
+ block = process->core_blocks;
#endif /* INDIRECT_CORE */
- swap_blocks =
- process->swap_item.limit - process->swap_item.base - core_blocks;
+ swap_in =
+ process->swap_item.limit - process->swap_item.base - block;
#endif /* INDIRECT_SWAP */
// remove from core pool
&core_block_pool,
core_table_mem + process->core_item.base,
#ifdef INDIRECT_SWAP
- core_blocks
+ block
#else /* ! INDIRECT_SWAP */
process->core_blocks
#endif /* ! INDIRECT_SWAP */
#ifdef INDIRECT_SWAP
block_pool_free(
&swap_block_pool,
- swap_table_mem + process->swap_item.base + core_blocks,
- swap_blocks
+ swap_table_mem + process->swap_item.base + block,
+ swap_in
);
#endif /* INDIRECT_SWAP */
pool_free(&swap_table, &process->swap_item);