Move swap space tests into do_swap_out(), re-evaluate for each victim to be less...
authorNick Downing <nick@ndcode.org>
Mon, 22 Apr 2019 05:26:09 +0000 (15:26 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 22 Apr 2019 06:19:42 +0000 (16:19 +1000)
core.h
process.c
process_test_run.c
swap.h

diff --git a/core.h b/core.h
index 2bc3d74..d7edcdf 100644 (file)
--- a/core.h
+++ b/core.h
@@ -26,9 +26,9 @@
 #define core_table_free(item) pool_free(&core_table, item)
 
 #ifdef INDIRECT_CORE
-#define core_avail() core_block_avail
+#define CORE_AVAIL core_block_avail
 #else
-#define core_avail() core_table.avail
+#define CORE_AVAIL core_table.avail
 #endif
 
 extern struct pool_head core_table;
index 08e64d4..ea90df5 100644 (file)
--- a/process.c
+++ b/process.c
@@ -57,11 +57,11 @@ static long estimate_size(long size) {
 
 // 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;
@@ -86,7 +86,8 @@ void process_init(int n, int spare) {
 
 #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)
@@ -94,7 +95,7 @@ void process_init(int n, int spare) {
 #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;
@@ -112,7 +113,7 @@ void process_init(int n, int spare) {
   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
@@ -137,10 +138,30 @@ static void do_swap_out(int swap_out) {
   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
@@ -149,10 +170,6 @@ static void do_swap_out(int swap_out) {
         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)
@@ -163,21 +180,28 @@ static void do_swap_out(int swap_out) {
 
     // 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
@@ -186,6 +210,11 @@ static void do_swap_out(int swap_out) {
       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
@@ -314,8 +343,8 @@ static void do_swap_out(int swap_out) {
 #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));
 
@@ -323,17 +352,12 @@ static void do_swap_out(int swap_out) {
       // 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) {
@@ -341,7 +365,7 @@ 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);
@@ -380,8 +404,7 @@ bool process_alloc(struct process *process, long size) {
 #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
@@ -431,7 +454,7 @@ bool process_realloc(struct process *process, long size) {
 #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);
@@ -467,8 +490,7 @@ bool process_realloc(struct process *process, long size) {
 #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
@@ -514,11 +536,7 @@ bool process_realloc(struct process *process, long size) {
 }
 
 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
@@ -555,24 +573,11 @@ void process_run(struct process *process) {
         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;
@@ -617,24 +622,11 @@ void process_run(struct process *process) {
 
     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
index 2e78354..d498169 100644 (file)
@@ -362,7 +362,7 @@ int main(int argc, char **argv) {
     processes[i].size = -1L;
 
   while (true) {
- //printf("avail %d %d(%d) %d(%d)\n", process_avail, core_avail(), core_table.avail, swap_avail(), swap_table.avail);
+ //printf("avail %d %d(%d) %d(%d)\n", process_avail, CORE_AVAIL, core_table.avail, SWAP_AVAIL, swap_table.avail);
     switch (scanf("%s", buf)) {
     case -1:
       goto done;
diff --git a/swap.h b/swap.h
index 15352ff..0505c60 100644 (file)
--- a/swap.h
+++ b/swap.h
@@ -26,9 +26,9 @@
 #define swap_table_free(item) pool_free(&swap_table, item)
 
 #ifdef INDIRECT_SWAP
-#define swap_avail() swap_block_avail
+#define SWAP_AVAIL swap_block_avail
 #else
-#define swap_avail() swap_table.avail
+#define SWAP_AVAIL swap_table.avail
 #endif
 
 extern struct pool_head swap_table;