Make all processes be in LRU list, with victim pointer separating fully in core proce...
authorNick Downing <nick@ndcode.org>
Sun, 2 Jun 2019 04:34:05 +0000 (14:34 +1000)
committerNick Downing <nick@ndcode.org>
Sun, 2 Jun 2019 04:47:07 +0000 (14:47 +1000)
process.c

index 91d2247..84a4366 100644 (file)
--- a/process.c
+++ b/process.c
@@ -60,41 +60,42 @@ static bool do_swap_out(int swap_out) {
 
   // loop entry code for the case of an existing victim
   if (swap_out > 0) {
-    if (victim != &lru_head) {
-      process = (struct process *)(
-        (char *)victim - offsetof(struct process, lru_item)
-      );
+    assert(victim->prev != &lru_head);
+    process = (struct process *)(
+      (char *)victim->prev - offsetof(struct process, lru_item)
+    );
 
-      // calculate amount to swap out
-      core_blocks =
+    // calculate amount to swap out
 #ifndef INDIRECT_CORE
-       process->core_item.limit - process->core_item.base;
-#else
-       process->core_item.limit - process->core_item.base - process->swap_blocks;
-#endif
+    core_blocks =
+      process->core_item.limit - process->core_item.base;
+#else /* INDIRECT_CORE */
+    core_blocks =
+      process->core_item.limit -
+        process->core_item.base -
+        process->swap_blocks;
+#endif /* INDIRECT_CORE */
 #ifndef INDIRECT_SWAP
-      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 > core_blocks)
-        blocks = core_blocks;
+    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("existing victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
 
-      // increase swap allocation
-      goto loop_entry;
-    }
+    // increase swap allocation
+    goto loop_entry;
 
     // loop for the case of no existing victim
     do {
-      victim = lru_head.prev;
-      assert(victim != &lru_head);
+      assert(victim->prev != &lru_head);
       process = (struct process *)(
-        (char *)victim - offsetof(struct process, lru_item)
+        (char *)victim->prev - offsetof(struct process, lru_item)
       );
 
       // calculate amount to swap out
@@ -106,10 +107,7 @@ static bool do_swap_out(int swap_out) {
 #else /* INDIRECT_SWAP */
       blocks = swap_block_pool.avail;
       if (blocks == 0)
- {
-  victim = &lru_head;
         return false;
- }
       if (blocks > swap_out)
         blocks = swap_out;
       if (blocks > core_blocks)
@@ -117,11 +115,6 @@ static bool do_swap_out(int swap_out) {
 #endif /* INDIRECT_SWAP */
  printf("new victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
 
-      // remove from LRU list
-      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
       core_blocks -= blocks;
@@ -252,7 +245,7 @@ static bool do_swap_out(int swap_out) {
       pool_free(&core_table, &process->core_item);
       process->flags &= ~PROCESS_FLAGS_CORE_ITEM;
 #endif /* ! INDIRECT_CORE */
-      victim = &lru_head;
+      victim = &process->lru_item;
 
       swap_out -= blocks;
     } while (swap_out);
@@ -469,45 +462,35 @@ void process_run(struct process *process) {
   // must be already allocated
   assert(process->flags & PROCESS_FLAGS_ACTIVE);
 
+  // remove from LRU list
+  if (victim == &process->lru_item)
+    victim = process->lru_item.next;
+  process->lru_item.prev->next = process->lru_item.next;
+  process->lru_item.next->prev = process->lru_item.prev;
+
   // see whether fully in core
-  if (process->lru_item.prev != NULL) {
 #ifndef INDIRECT_CORE
-    assert(process->flags & PROCESS_FLAGS_CORE_ITEM);
-#endif /* INDIRECT_CORE */
-    assert(process->swap_blocks == 0);
-
-    // yes, remove from LRU list
-    assert(victim != &process->lru_item);
-    process->lru_item.prev->next = process->lru_item.next;
-    process->lru_item.next->prev = process->lru_item.prev;
-  }
-  else {
+  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 (victim != &process->lru_item) {
-#ifndef INDIRECT_CORE
-      assert((process->flags & PROCESS_FLAGS_CORE_ITEM) == 0);
-#endif /* ! INDIRECT_CORE */
+    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
-#ifndef INDIRECT_CORE
       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;
-#endif /* INDIRECT_CORE */
       if (blocks > process->swap_blocks)
         blocks = process->swap_blocks;
 
       // add to core pool
       core_blocks = 0;
-#ifndef INDIRECT_CORE
       rassert(
         pool_alloc(
           &core_table,
@@ -517,21 +500,19 @@ void process_run(struct process *process) {
         )
       );
       process->flags |= PROCESS_FLAGS_CORE_ITEM;
-#endif /* ! INDIRECT_CORE */
       goto loop_entry_full;
     }
     assert(process->swap_blocks);
 
-    // victim, take over the dedicated pool items
-    core_blocks =
-#ifndef INDIRECT_CORE
-      process->core_item.limit - process->core_item.base;
+    core_blocks = process->core_item.limit - process->core_item.base;
 #else /* INDIRECT_CORE */
+  if (process->swap_blocks) {
+    // no, need to swap some in
+    core_blocks =
       process->core_item.limit -
         process->core_item.base -
         process->swap_blocks;
 #endif /* INDIRECT_CORE */
-    victim = &lru_head;
 
     // loop for case of partially in core, partially in swap
     do {
@@ -546,8 +527,8 @@ void process_run(struct process *process) {
       if (blocks > process->swap_blocks)
         blocks = process->swap_blocks;
 
-      // increase core allocation
 #ifndef INDIRECT_CORE
+      // increase core allocation
       rassert(
         pool_alloc(
           &core_table,
@@ -557,9 +538,9 @@ void process_run(struct process *process) {
             POOL_ALLOC_MODE_REALLOC
         )
       );
+    loop_entry_full:
 #endif /* ! INDIRECT_CORE */
 
-    loop_entry_full:
       // calculate transfer parameters
       swap_base = process->swap_item.limit - process->swap_blocks;
 #ifndef INDIRECT_CORE
@@ -667,11 +648,9 @@ void process_free(struct process *process) {
 
   // remove from LRU list
   if (victim == &process->lru_item)
-    victim = &lru_head;
-  if (process->lru_item.prev) {
-    process->lru_item.prev->next = process->lru_item.next;
-    process->lru_item.next->prev = process->lru_item.prev;
-  }
+    victim = process->lru_item.next;
+  process->lru_item.prev->next = process->lru_item.next;
+  process->lru_item.next->prev = process->lru_item.prev;
 
   // remove from core pool
 #ifndef INDIRECT_CORE