// basically the inverse of the above, estimates size of files that could be
// created if space is divided into at most n files, but a bit conservatively
-static long estimate_free() {
+static long estimate_free(int n) {
int blocks;
// at most one partial indirect and double indirect block per file
- blocks = fs_tab[0].s_tfree - (n_processes << 1);
+ blocks = fs_tab[0].s_tfree - (n << 1);
// max number of FULL indirect blocks (ignore the 18 direct blocks)
blocks -= blocks / (DISK_INDIRECT_SIZE + 1);
return (long)blocks << DISK_BLOCK_SHIFT;
#ifdef INODE_SWAP
process_avail =
- ((long)(core_avail() - spare) << BLOCK_SHIFT) + estimate_free();
+ ((long)(CORE_AVAIL - spare) << BLOCK_SHIFT) +
+ estimate_free(n_processes);
#ifdef PREALLOCATE_CORE
core_table_avail = (long)core_table.avail << BLOCK_SHIFT;
if (process_avail > core_table_avail)
#endif
printf("process_avail %ld\n", process_avail);
#else
- process_avail = core_avail() + swap_avail() - spare;
+ process_avail = CORE_AVAIL + SWAP_AVAIL - spare;
#ifdef PREALLOCATE_CORE
if (process_avail > core_table.avail)
process_avail = core_table.avail;
victim = NULL;
}
-static void do_swap_out(int swap_out) {
+static bool do_swap_out(int swap_out) {
#ifndef PREALLOCATE_CORE
int victim_core_blocks;
#endif
if (swap_out > 0) {
if (victim) {
// calculate amount to swap out
+#if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
+#ifdef INODE_SWAP
+ blocks = (int)(estimate_free(1) >> BLOCK_SHIFT);
+#else
+ blocks = SWAP_AVAIL;
+#endif
+ if (blocks == 0)
+ return false;
+ if (blocks > swap_out)
+ blocks = swap_out;
+#endif
#ifndef PREALLOCATE_CORE
victim_core_blocks =
victim->core_item.limit - victim->core_item.base;
#endif
+#if defined(PREALLOCATE_SWAP) && !defined(INDIRECT_SWAP)
+ blocks = swap_out < victim_core_blocks ? swap_out : victim_core_blocks;
+#else
+ if (blocks > victim_core_blocks)
+ blocks = victim_core_blocks;
+#endif
+ printf("existing victim %d, swap out %d of %d\n", (int)(victim - processes), blocks, victim_core_blocks);
+
+ // increase swap allocation
#ifndef PREALLOCATE_SWAP
victim_swap_blocks =
#ifdef INODE_SWAP
victim->swap_item.limit - victim->swap_item.base;
#endif
#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
#if !defined(INODE_SWAP) && !defined(PREALLOCATE_SWAP)
rassert(
swap_table_realloc(&victim->swap_item, victim_swap_blocks + blocks)
// loop for the case of no existing victim
do {
- // take next least recently used process as victim
+ // calculate amount to swap out
+#if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
+#ifdef INODE_SWAP
+ blocks = (int)(estimate_free(1) >> BLOCK_SHIFT);
+#else
+ blocks = SWAP_AVAIL;
+#endif
+ if (blocks == 0)
+ return false;
+ if (blocks > swap_out)
+ blocks = swap_out;
+#endif
assert(lru_head.prev != &lru_head);
victim = (struct process *)lru_head.prev;
-
- // 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
-
- // fully in core, only the core item is meaningful
victim_core_blocks =
victim->core_item.limit - victim->core_item.base;
-
- // calculate amount to swap out
+#if defined(PREALLOCATE_SWAP) && !defined(INDIRECT_SWAP)
blocks = swap_out < victim_core_blocks ? swap_out : victim_core_blocks;
+#else
+ if (blocks > victim_core_blocks)
+ blocks = victim_core_blocks;
+#endif
printf("new victim %d, swap out %d of %d\n", (int)(victim - processes), blocks, victim_core_blocks);
// add to swap pool
rassert(swap_table_alloc(&victim->swap_item, blocks));
#endif
+ // 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
+
loop_entry:
// calculate transfer parameters
#ifndef INODE_SWAP
#endif
// in this case there can't be any further victim to swap
- assert(swap_out == blocks);
- return;
+ // report whether aborted due to swap space or user request
+ return swap_out == blocks;
}
printf("victimized %d\n", (int)(victim - processes));
// remove from core pool
core_table_free(&victim->core_item);
#endif
+ victim = NULL;
swap_out -= blocks;
} while (swap_out);
- victim = NULL;
-#ifdef PREALLOCATE_CORE
- assert(victim_core_blocks == 0);
-#endif
-#ifdef PREALLOCATE_SWAP
- victim_swap_blocks = 0;
-#endif
}
+ return true;
}
bool process_alloc(struct process *process, long size) {
long estimated_size;
int i;
#endif
- int blocks, swap_out;
+ int blocks;
// must not be already allocated
assert(process->size == -1L);
#endif
// free up as much core as we need to
- swap_out = blocks - core_avail();
- do_swap_out(swap_out);
+ rassert(do_swap_out(blocks - CORE_AVAIL));
// allocate core and possible swap
#ifdef MOVEABLE_CORE
#ifdef INODE_SWAP
long estimated_size, old_estimated_size, estimated_size_change;
#endif
- int blocks, old_blocks, blocks_change, swap_out;
+ int blocks, old_blocks, blocks_change;
// must be already allocated
assert(process->size != -1L);
#endif
// free up as much core as we need to
- swap_out = blocks_change - core_avail();
- do_swap_out(swap_out);
+ rassert(do_swap_out(blocks_change - CORE_AVAIL));
// reallocate core and possible swap
#ifdef MOVEABLE_CORE
}
void process_run(struct process *process) {
- int blocks, swap_out;
-#if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
- int excess;
-#endif
- int process_core_blocks, process_swap_blocks;
+ int blocks, process_core_blocks, process_swap_blocks;
#ifdef INODE_SWAP
int core_base;
#else
process->swap_item.limit - process->swap_item.base;
#endif
- // calculate amounts to swap out then in
- blocks = process_swap_blocks;
- swap_out = blocks - core_avail();
-#if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
-#ifdef INODE_SWAP
- printf("estimate_free %ld blocks %d\n", estimate_free(), (int)(estimate_free() >> BLOCK_SHIFT));
- excess = swap_out - (int)(estimate_free() >> BLOCK_SHIFT);
-#else
- excess = swap_out - swap_avail();
-#endif
- if (excess > 0) {
- blocks -= excess;
- swap_out -= excess;
- }
-#endif
-
// free up as much core as we can
- do_swap_out(swap_out);
+ do_swap_out(process_swap_blocks - CORE_AVAIL);
+ blocks = CORE_AVAIL;
+ if (blocks > process_swap_blocks)
+ blocks = process_swap_blocks;
// add to core pool
process_core_blocks = 0;
loop_entry_partial:
#endif
- // calculate amounts to swap out then in
- blocks = process_swap_blocks;
- swap_out = blocks - core_avail();
-#if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
-#ifdef INODE_SWAP
- printf("estimate_free %ld blocks %d\n", estimate_free(), (int)(estimate_free() >> BLOCK_SHIFT));
- excess = swap_out - (int)(estimate_free() >> BLOCK_SHIFT);
-#else
- excess = swap_out - swap_avail();
-#endif
- if (excess > 0) {
- blocks -= excess;
- swap_out -= excess;
- }
-#endif
-
// free up as much core as we can
- do_swap_out(swap_out);
+ do_swap_out(process_swap_blocks - CORE_AVAIL);
+ blocks = CORE_AVAIL;
+ if (blocks > process_swap_blocks)
+ blocks = process_swap_blocks;
// increase core allocation
#ifndef PREALLOCATE_CORE