Simplify the swap-in and swap-out loops, since have enough status information in...
authorNick Downing <nick@ndcode.org>
Sun, 2 Jun 2019 06:29:29 +0000 (16:29 +1000)
committerNick Downing <nick@ndcode.org>
Sun, 2 Jun 2019 06:29:29 +0000 (16:29 +1000)
process.c

index 84a4366..159900e 100644 (file)
--- a/process.c
+++ b/process.c
@@ -58,8 +58,7 @@ static bool do_swap_out(int swap_out) {
   int i, j, core_block, swap_block;
 #endif /* INDIRECT_CORE */
 
-  // loop entry code for the case of an existing victim
-  if (swap_out > 0) {
+  for (; swap_out > 0; swap_out -= blocks) {
     assert(victim->prev != &lru_head);
     process = (struct process *)(
       (char *)victim->prev - offsetof(struct process, lru_item)
@@ -86,169 +85,138 @@ static bool do_swap_out(int swap_out) {
     if (blocks > core_blocks)
       blocks = core_blocks;
 #endif /* INDIRECT_SWAP */
- printf("existing 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, core_blocks);
 
-    // increase swap allocation
-    goto loop_entry;
-
-    // loop for the case of no existing victim
-    do {
-      assert(victim->prev != &lru_head);
-      process = (struct process *)(
-        (char *)victim->prev - offsetof(struct process, lru_item)
-      );
-
-      // 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 < core_blocks ? swap_out : core_blocks;
-#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;
-#endif /* INDIRECT_SWAP */
- printf("new victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
-
-    loop_entry:
-      // calculate transfer parameters
-      core_blocks -= blocks;
-      process->swap_blocks += blocks;
-      swap_base = process->swap_item.limit - process->swap_blocks;
+    // calculate transfer parameters
+    core_blocks -= blocks;
+    process->swap_blocks += blocks;
+    swap_base = process->swap_item.limit - process->swap_blocks;
 #ifndef INDIRECT_CORE
-      core_base = process->core_item.limit - blocks;
+    core_base = process->core_item.limit - blocks;
 #else /* INDIRECT_CORE */
-      core_base = process->core_item.limit - process->swap_blocks;
+    core_base = process->core_item.limit - process->swap_blocks;
 #endif /* INDIRECT_CORE */
-      paras = blocks << BLOCK_PARAS_SHIFT;
+    paras = blocks << BLOCK_PARAS_SHIFT;
 
-      // transfer data to swap
+    // transfer data to swap
 #ifndef INDIRECT_CORE
 #ifndef INDIRECT_SWAP
  printf("write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + blocks, swap_base, swap_base + blocks);
-      core_to_swap_copy(
-        core_base << BLOCK_PARAS_SHIFT,
-        swap_base << BLOCK_PARAS_SHIFT,
-        paras
+    core_to_swap_copy(
+      core_base << BLOCK_PARAS_SHIFT,
+      swap_base << BLOCK_PARAS_SHIFT,
+      paras
 #else /* INDIRECT_SWAP */
-      rassert(
-        block_pool_alloc(&swap_block_pool, swap_table_mem + swap_base, blocks)
+    rassert(
+      block_pool_alloc(&swap_block_pool, swap_table_mem + swap_base, blocks)
 #endif /* INDIRECT_SWAP */
-      );
+    );
 #ifdef INDIRECT_SWAP
  printf("write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + blocks, swap_base, swap_base + blocks);
-      j = paras >> BLOCK_PARAS_SHIFT;
+    j = paras >> BLOCK_PARAS_SHIFT;
  printf("blocks");
-      for (i = 0; i < j; ++i) {
-        core_block = core_base + i;
-        swap_block = swap_base + i;
-        swap_block = swap_table_mem[swap_block];
+    for (i = 0; i < j; ++i) {
+      core_block = core_base + i;
+      swap_block = swap_base + i;
+      swap_block = swap_table_mem[swap_block];
  printf(" %d", swap_block);
-        core_to_swap_copy(
-          core_block << BLOCK_PARAS_SHIFT,
-          swap_block << BLOCK_PARAS_SHIFT,
-          BLOCK_PARAS
-        );
-      }
-      j = (int)paras & (BLOCK_PARAS - 1);
-      if (j) {
-        core_block = core_base + i;
-        swap_block = swap_base + i;
-        swap_block = swap_table_mem[swap_block];
+      core_to_swap_copy(
+        core_block << BLOCK_PARAS_SHIFT,
+        swap_block << BLOCK_PARAS_SHIFT,
+        BLOCK_PARAS
+      );
+    }
+    j = (int)paras & (BLOCK_PARAS - 1);
+    if (j) {
+      core_block = core_base + i;
+      swap_block = swap_base + i;
+      swap_block = swap_table_mem[swap_block];
  printf(" %d", swap_block);
  //putchar('*');
-        core_to_swap_copy(
-          core_block << BLOCK_PARAS_SHIFT,
-          swap_block << BLOCK_PARAS_SHIFT,
-          j
-        );
-      }
+      core_to_swap_copy(
+        core_block << BLOCK_PARAS_SHIFT,
+        swap_block << BLOCK_PARAS_SHIFT,
+        j
+      );
+    }
  printf("\n");
 #endif /* INDIRECT_SWAP */
 #else /* INDIRECT_CORE */
 #ifdef INDIRECT_SWAP
-      rassert(
-        block_pool_alloc(&swap_block_pool, swap_table_mem + swap_base, blocks)
-      );
+    rassert(
+      block_pool_alloc(&swap_block_pool, swap_table_mem + swap_base, blocks)
+    );
 #endif /* INDIRECT_SWAP */
  printf("write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + blocks, swap_base, swap_base + blocks);
-      j = paras >> BLOCK_PARAS_SHIFT;
+    j = paras >> BLOCK_PARAS_SHIFT;
  printf("blocks");
-      for (i = 0; i < j; ++i) {
-        core_block = core_base + i;
-        core_block = core_table_mem[core_block];
+    for (i = 0; i < j; ++i) {
+      core_block = core_base + i;
+      core_block = core_table_mem[core_block];
  printf(" %d", core_block);
-        swap_block = swap_base + i;
+      swap_block = swap_base + i;
 #ifdef INDIRECT_SWAP
-        swap_block = swap_table_mem[swap_block];
+      swap_block = swap_table_mem[swap_block];
  printf(",%d", swap_block);
 #endif /* INDIRECT_SWAP */
-        core_to_swap_copy(
-          core_block << BLOCK_PARAS_SHIFT,
-          swap_block << BLOCK_PARAS_SHIFT,
-          BLOCK_PARAS
-        );
-      }
-      j = (int)paras & (BLOCK_PARAS - 1);
-      if (j) {
-        core_block = core_base + i;
-        core_block = core_table_mem[core_block];
+      core_to_swap_copy(
+        core_block << BLOCK_PARAS_SHIFT,
+        swap_block << BLOCK_PARAS_SHIFT,
+        BLOCK_PARAS
+      );
+    }
+    j = (int)paras & (BLOCK_PARAS - 1);
+    if (j) {
+      core_block = core_base + i;
+      core_block = core_table_mem[core_block];
  printf(" %d", core_block);
-        swap_block = swap_base + i;
+      swap_block = swap_base + i;
 #ifdef INDIRECT_SWAP
-        swap_block = swap_table_mem[swap_block];
+      swap_block = swap_table_mem[swap_block];
  printf(",%d", swap_block);
 #endif /* INDIRECT_SWAP */
  //putchar('*');
-        core_to_swap_copy(
-          core_block << BLOCK_PARAS_SHIFT,
-          swap_block << BLOCK_PARAS_SHIFT,
-          j
-        );
-      }
+      core_to_swap_copy(
+        core_block << BLOCK_PARAS_SHIFT,
+        swap_block << BLOCK_PARAS_SHIFT,
+        j
+      );
+    }
  printf("\n");
-      block_pool_free(&core_block_pool, core_table_mem + core_base, blocks);
+    block_pool_free(&core_block_pool, core_table_mem + core_base, blocks);
 #endif /* INDIRECT_CORE */
 
-      // see if victim fully swapped out
-      if (core_blocks) {
+    // see if victim fully swapped out
+    if (core_blocks) {
 #ifndef INDIRECT_CORE
-        // no, reduce core allocation
-        rassert(
-          pool_alloc(
-            &core_table,
-            &process->core_item,
-            core_blocks,
-              POOL_ALLOC_MODE_MOVEABLE |
-              POOL_ALLOC_MODE_REALLOC
-          )
-        );
+      // no, reduce core allocation
+      rassert(
+        pool_alloc(
+          &core_table,
+          &process->core_item,
+          core_blocks,
+            POOL_ALLOC_MODE_MOVEABLE |
+            POOL_ALLOC_MODE_REALLOC
+        )
+      );
 #endif /* ! INDIRECT_CORE */
 
-        // in this case there can't be any further victim to swap
-        // report whether aborted due to swap space or user request
-        return swap_out == blocks;
-      }
-      assert(
-        process->swap_blocks ==
-          process->swap_item.limit - process->swap_item.base
-      );
+      // in this case there can't be any further victim to swap
+      // report whether aborted due to swap space or user request
+      return swap_out == blocks;
+    }
+    assert(
+      process->swap_blocks ==
+        process->swap_item.limit - process->swap_item.base
+    );
  printf("victimized %d\n", (int)(process - processes));
 
 #ifndef INDIRECT_CORE
-      // remove from core pool
-      pool_free(&core_table, &process->core_item);
-      process->flags &= ~PROCESS_FLAGS_CORE_ITEM;
+    // remove from core pool
+    pool_free(&core_table, &process->core_item);
+    process->flags &= ~PROCESS_FLAGS_CORE_ITEM;
 #endif /* ! INDIRECT_CORE */
-      victim = &process->lru_item;
-
-      swap_out -= blocks;
-    } while (swap_out);
+    victim = &process->lru_item;
   }
   return true;
 }
@@ -468,172 +436,139 @@ void process_run(struct process *process) {
   process->lru_item.prev->next = process->lru_item.next;
   process->lru_item.next->prev = process->lru_item.prev;
 
-  // see whether fully in core
 #ifndef INDIRECT_CORE
-  if (
-    (process->flags & PROCESS_FLAGS_CORE_ITEM) == 0 ||
-    process->swap_blocks
-  ) {
-    // no, need to swap some in
-
-    // loop entry code for case of fully in swap
-    if ((process->flags & PROCESS_FLAGS_CORE_ITEM) == 0) {
-      assert(
-        process->swap_blocks ==
-          process->swap_item.limit - process->swap_item.base
-      );
-
-      // free up as much core as we can
-      do_swap_out(process->swap_blocks - core_table.avail);
-      blocks = core_table.avail;
-      if (blocks > process->swap_blocks)
-        blocks = process->swap_blocks;
-
-      // add to core pool
-      core_blocks = 0;
-      rassert(
-        pool_alloc(
-          &core_table,
-          &process->core_item,
-          blocks,
-          POOL_ALLOC_MODE_MOVEABLE
-        )
-      );
-      process->flags |= PROCESS_FLAGS_CORE_ITEM;
-      goto loop_entry_full;
-    }
-    assert(process->swap_blocks);
-
-    core_blocks = process->core_item.limit - process->core_item.base;
+  do {
+    core_blocks =
+      process->flags & PROCESS_FLAGS_CORE_ITEM ?
+        process->core_item.limit - process->core_item.base :
+        0;
 #else /* INDIRECT_CORE */
-  if (process->swap_blocks) {
-    // no, need to swap some in
+  while (process->swap_blocks) {
     core_blocks =
       process->core_item.limit -
         process->core_item.base -
         process->swap_blocks;
 #endif /* INDIRECT_CORE */
 
-    // loop for case of partially in core, partially in swap
-    do {
-      // free up as much core as we can
+    // free up as much core as we can
 #ifndef INDIRECT_CORE
-      do_swap_out(process->swap_blocks - core_table.avail);
-      blocks = core_table.avail;
+    do_swap_out(process->swap_blocks - core_table.avail);
+    blocks = core_table.avail;
 #else /* INDIRECT_CORE */
-      do_swap_out(process->swap_blocks - core_block_pool.avail);
-      blocks = core_block_pool.avail;
+    do_swap_out(process->swap_blocks - core_block_pool.avail);
+    blocks = core_block_pool.avail;
 #endif /* INDIRECT_CORE */
-      if (blocks > process->swap_blocks)
-        blocks = process->swap_blocks;
+    if (blocks > process->swap_blocks)
+      blocks = process->swap_blocks;
 
 #ifndef INDIRECT_CORE
-      // increase core allocation
-      rassert(
-        pool_alloc(
-          &core_table,
-          &process->core_item,
-          core_blocks + blocks,
-            POOL_ALLOC_MODE_MOVEABLE |
-            POOL_ALLOC_MODE_REALLOC
-        )
-      );
-    loop_entry_full:
+    // increase core allocation
+    rassert(
+      pool_alloc(
+        &core_table,
+        &process->core_item,
+        core_blocks + 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 - process->swap_blocks;
+    // calculate transfer parameters
+    swap_base = process->swap_item.limit - process->swap_blocks;
 #ifndef INDIRECT_CORE
-      core_base = process->core_item.limit - blocks;
+    core_base = process->core_item.limit - blocks;
 #else /* INDIRECT_CORE */
-      core_base = process->core_item.limit - process->swap_blocks;
+    core_base = process->core_item.limit - process->swap_blocks;
 #endif /* INDIRECT_CORE */
-      core_blocks += blocks;
-      process->swap_blocks -= blocks;
-      paras = blocks << BLOCK_PARAS_SHIFT;
+    core_blocks += blocks;
+    process->swap_blocks -= blocks;
+    paras = blocks << BLOCK_PARAS_SHIFT;
 
-      // transfer data to core
+    // transfer data to core
 #ifdef INDIRECT_CORE
-      block_pool_alloc(&core_block_pool, core_table_mem + core_base, blocks);
+    block_pool_alloc(&core_block_pool, core_table_mem + core_base, blocks);
 #endif /* INDIRECT_CORE */
  printf("read swap [%d,%d) to core [%d,%d)\n", swap_base, swap_base + blocks, core_base, core_base + blocks);
 #ifndef INDIRECT_CORE
 #ifndef INDIRECT_SWAP
-      swap_to_core_copy(
-        swap_base << BLOCK_PARAS_SHIFT,
-        core_base << BLOCK_PARAS_SHIFT,
-        paras
-      );
+    swap_to_core_copy(
+      swap_base << BLOCK_PARAS_SHIFT,
+      core_base << BLOCK_PARAS_SHIFT,
+      paras
+    );
 #else /* INDIRECT_SWAP */
-      j = paras >> BLOCK_PARAS_SHIFT;
+    j = paras >> BLOCK_PARAS_SHIFT;
  printf("blocks");
-      for (i = 0; i < j; ++i) {
-        int core_block = core_base + i;
-        int swap_block = swap_base + i;
-        swap_block = swap_table_mem[swap_block];
+    for (i = 0; i < j; ++i) {
+      int core_block = core_base + i;
+      int swap_block = swap_base + i;
+      swap_block = swap_table_mem[swap_block];
  printf(" %d", swap_block);
-        swap_to_core_copy(
-          swap_block << BLOCK_PARAS_SHIFT,
-          core_block << BLOCK_PARAS_SHIFT,
-          BLOCK_PARAS
-        );
-      }
-      j = (int)paras & (BLOCK_PARAS - 1);
-      if (j) {
-        int core_block = core_base + i;
-        int swap_block = swap_base + i;
-        swap_block = swap_table_mem[swap_block];
+      swap_to_core_copy(
+        swap_block << BLOCK_PARAS_SHIFT,
+        core_block << BLOCK_PARAS_SHIFT,
+        BLOCK_PARAS
+      );
+    }
+    j = (int)paras & (BLOCK_PARAS - 1);
+    if (j) {
+      int core_block = core_base + i;
+      int swap_block = swap_base + i;
+      swap_block = swap_table_mem[swap_block];
  printf(" %d", swap_block);
-        swap_to_core_copy(
-          swap_block << BLOCK_PARAS_SHIFT,
-          core_block << BLOCK_PARAS_SHIFT,
-          j
-        );
-      }
+      swap_to_core_copy(
+        swap_block << BLOCK_PARAS_SHIFT,
+        core_block << BLOCK_PARAS_SHIFT,
+        j
+      );
+    }
  printf("\n");
-      block_pool_free(&swap_block_pool, swap_table_mem + swap_base, blocks);
+    block_pool_free(&swap_block_pool, swap_table_mem + swap_base, blocks);
 #endif /* INDIRECT_SWAP */
+  } while (process->swap_blocks);
 #else /* INDIRECT_CORE */
-      j = paras >> BLOCK_PARAS_SHIFT;
+    j = paras >> BLOCK_PARAS_SHIFT;
  printf("blocks");
-      for (i = 0; i < j; ++i) {
-        int core_block = core_base + i;
-        core_block = core_table_mem[core_block];
+    for (i = 0; i < j; ++i) {
+      int core_block = core_base + i;
+      core_block = core_table_mem[core_block];
  printf(" %d", core_block);
-        int swap_block = swap_base + i;
+      int swap_block = swap_base + i;
 #ifdef INDIRECT_SWAP
-        swap_block = swap_table_mem[swap_block];
+      swap_block = swap_table_mem[swap_block];
  printf(",%d", swap_block);
 #endif /* INDIRECT_SWAP */
-        swap_to_core_copy(
-          swap_block << BLOCK_PARAS_SHIFT,
-          core_block << BLOCK_PARAS_SHIFT,
-          BLOCK_PARAS
-        );
-      }
-      j = (int)paras & (BLOCK_PARAS - 1);
-      if (j) {
-        int core_block = core_base + i;
-        core_block = core_table_mem[core_block];
+      swap_to_core_copy(
+        swap_block << BLOCK_PARAS_SHIFT,
+        core_block << BLOCK_PARAS_SHIFT,
+        BLOCK_PARAS
+      );
+    }
+    j = (int)paras & (BLOCK_PARAS - 1);
+    if (j) {
+      int core_block = core_base + i;
+      core_block = core_table_mem[core_block];
  printf(" %d", core_block);
-        int swap_block = swap_base + i;
+      int swap_block = swap_base + i;
 #ifdef INDIRECT_SWAP
-        swap_block = swap_table_mem[swap_block];
+      swap_block = swap_table_mem[swap_block];
  printf(",%d", swap_block);
 #endif /* INDIRECT_SWAP */
-        swap_to_core_copy(
-          swap_block << BLOCK_PARAS_SHIFT,
-          core_block << BLOCK_PARAS_SHIFT,
-          j
-        );
-      }
+      swap_to_core_copy(
+        swap_block << BLOCK_PARAS_SHIFT,
+        core_block << BLOCK_PARAS_SHIFT,
+        j
+      );
+    }
  printf("\n");
 #ifdef INDIRECT_SWAP
-      block_pool_free(&swap_block_pool, swap_table_mem + swap_base, blocks);
+    block_pool_free(&swap_block_pool, swap_table_mem + swap_base, blocks);
 #endif /* INDIRECT_SWAP */
-#endif /* INDIRECT_CORE */
-    } while (process->swap_blocks);
   }
+#endif /* INDIRECT_CORE */
 
   // insert at head of LRU list
   process->lru_item.prev = &lru_head;