Make victim be LRU not process pointer, and use &lru_head instead of NULL
authorNick Downing <nick@ndcode.org>
Sun, 2 Jun 2019 03:39:27 +0000 (13:39 +1000)
committerNick Downing <nick@ndcode.org>
Sun, 2 Jun 2019 03:39:27 +0000 (13:39 +1000)
process.c
process.h

index 9868619..f332672 100644 (file)
--- a/process.c
+++ b/process.c
@@ -13,9 +13,7 @@ int n_processes;
 
 int process_avail;
 
-struct lru_item lru_head;
-
-struct process *victim;
+struct lru_item lru_head, *victim;
 
 void process_init(int n, int spare) {
   processes = calloc(n, sizeof(struct process));
@@ -43,13 +41,13 @@ void process_init(int n, int spare) {
 
   lru_head.prev = &lru_head;
   lru_head.next = &lru_head;
-
-  victim = NULL;
+  victim = &lru_head;
 }
 
 // note: swap_out argument can be negative, indicates a no-op
 static bool do_swap_out(int swap_out) {
-  int victim_core_blocks;
+  struct process *process;
+  int core_blocks;
   int blocks, swap_base, core_base;
   int paras;
 #ifndef INDIRECT_CORE
@@ -62,26 +60,30 @@ static bool do_swap_out(int swap_out) {
 
   // loop entry code for the case of an existing victim
   if (swap_out > 0) {
-    if (victim) {
+    if (victim != &lru_head) {
+      process = (struct process *)(
+        (char *)victim - offsetof(struct process, lru_item)
+      );
+
       // calculate amount to swap out
-      victim_core_blocks =
+      core_blocks =
 #ifndef INDIRECT_CORE
-       victim->core_item.limit - victim->core_item.base;
+       process->core_item.limit - process->core_item.base;
 #else
-       victim->core_item.limit - victim->core_item.base - victim->swap_blocks;
+       process->core_item.limit - process->core_item.base - process->swap_blocks;
 #endif
 #ifndef INDIRECT_SWAP
-      blocks = swap_out < victim_core_blocks ? swap_out : victim_core_blocks;
+      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 > victim_core_blocks)
-        blocks = victim_core_blocks;
+      if (blocks > core_blocks)
+        blocks = core_blocks;
 #endif /* INDIRECT_SWAP */
- printf("existing victim %d, swap out %d of %d\n", (int)(victim - processes), blocks, victim_core_blocks);
+ printf("existing victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
 
       // increase swap allocation
       goto loop_entry;
@@ -89,44 +91,46 @@ static bool do_swap_out(int swap_out) {
 
     // loop for the case of no existing victim
     do {
-      // calculate amount to swap out
-      assert(lru_head.prev != &lru_head);
-      victim = (struct process *)(
-        (char *)lru_head.prev - offsetof(struct process, lru_item)
+      victim = lru_head.prev;
+      assert(victim != &lru_head);
+      process = (struct process *)(
+        (char *)victim - offsetof(struct process, lru_item)
       );
-      assert(victim->swap_blocks == 0);
-      victim_core_blocks =
-        victim->core_item.limit - victim->core_item.base;
+
+      // 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 < victim_core_blocks ? swap_out : victim_core_blocks;
+      blocks = swap_out < core_blocks ? swap_out : core_blocks;
 #else /* INDIRECT_SWAP */
       blocks = swap_block_pool.avail;
       if (blocks == 0)
  {
-  victim = NULL;
+  victim = &lru_head;
         return false;
  }
       if (blocks > swap_out)
         blocks = swap_out;
-      if (blocks > victim_core_blocks)
-        blocks = victim_core_blocks;
+      if (blocks > core_blocks)
+        blocks = core_blocks;
 #endif /* INDIRECT_SWAP */
- printf("new victim %d, swap out %d of %d\n", (int)(victim - processes), blocks, victim_core_blocks);
+ printf("new victim %d, swap out %d of %d\n", (int)(process - processes), blocks, core_blocks);
 
       // 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
+      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
-      victim_core_blocks -= blocks;
-      victim->swap_blocks += blocks;
-      swap_base = victim->swap_item.limit - victim->swap_blocks;
+      core_blocks -= blocks;
+      process->swap_blocks += blocks;
+      swap_base = process->swap_item.limit - process->swap_blocks;
 #ifndef INDIRECT_CORE
-      core_base = victim->core_item.limit - blocks;
+      core_base = process->core_item.limit - blocks;
 #else /* INDIRECT_CORE */
-      core_base = victim->core_item.limit - victim->swap_blocks;
+      core_base = process->core_item.limit - process->swap_blocks;
 #endif /* INDIRECT_CORE */
       paras = blocks << BLOCK_PARAS_SHIFT;
 
@@ -219,14 +223,14 @@ static bool do_swap_out(int swap_out) {
 #endif /* INDIRECT_CORE */
 
       // see if victim fully swapped out
-      if (victim_core_blocks) {
+      if (core_blocks) {
 #ifndef INDIRECT_CORE
         // no, reduce core allocation
         rassert(
           pool_alloc(
             &core_table,
-            &victim->core_item,
-            victim_core_blocks,
+            &process->core_item,
+            core_blocks,
               POOL_ALLOC_MODE_MOVEABLE |
               POOL_ALLOC_MODE_REALLOC
           )
@@ -238,17 +242,17 @@ static bool do_swap_out(int swap_out) {
         return swap_out == blocks;
       }
       assert(
-        victim->swap_blocks ==
-          victim->swap_item.limit - victim->swap_item.base
+        process->swap_blocks ==
+          process->swap_item.limit - process->swap_item.base
       );
- printf("victimized %d\n", (int)(victim - processes));
+ printf("victimized %d\n", (int)(process - processes));
 
 #ifndef INDIRECT_CORE
       // remove from core pool
-      pool_free(&core_table, &victim->core_item);
+      pool_free(&core_table, &process->core_item);
 #endif /* ! INDIRECT_CORE */
-      victim->flags &= ~PROCESS_FLAGS_CORE_ITEM;
-      victim = NULL;
+      process->flags &= ~PROCESS_FLAGS_CORE_ITEM;
+      victim = &lru_head;
 
       swap_out -= blocks;
     } while (swap_out);
@@ -445,7 +449,7 @@ bool process_realloc(struct process *process, int paras, bool dir) {
 }
 
 void process_run(struct process *process) {
-  int blocks, process_core_blocks;
+  int blocks, core_blocks;
   int swap_base, core_base;
   int paras;
 #ifndef INDIRECT_CORE
@@ -465,7 +469,7 @@ void process_run(struct process *process) {
     assert(process->swap_blocks == 0);
 
     // yes, remove from LRU list
-    assert(process != victim);
+    assert(victim != &process->lru_item);
     process->lru_item.prev->next = process->lru_item.next;
     process->lru_item.next->prev = process->lru_item.prev;
   }
@@ -473,7 +477,7 @@ void process_run(struct process *process) {
     // no, need to swap some in
 
     // loop entry code for case of fully in swap
-    if (process != victim) {
+    if (victim != &process->lru_item) {
       assert((process->flags & PROCESS_FLAGS_CORE_ITEM) == 0);
       assert(
         process->swap_blocks ==
@@ -492,7 +496,7 @@ void process_run(struct process *process) {
         blocks = process->swap_blocks;
 
       // add to core pool
-      process_core_blocks = 0;
+      core_blocks = 0;
 #ifndef INDIRECT_CORE
       rassert(
         pool_alloc(
@@ -509,13 +513,15 @@ void process_run(struct process *process) {
     assert(process->swap_blocks);
 
     // victim, take over the dedicated pool items
-    process_core_blocks =
+    core_blocks =
 #ifndef INDIRECT_CORE
-      victim->core_item.limit - victim->core_item.base;
+      process->core_item.limit - process->core_item.base;
 #else /* INDIRECT_CORE */
-      victim->core_item.limit - victim->core_item.base - victim->swap_blocks;
+      process->core_item.limit -
+        process->core_item.base -
+        process->swap_blocks;
 #endif /* INDIRECT_CORE */
-    victim = NULL;
+    victim = &lru_head;
 
     // loop for case of partially in core, partially in swap
     do {
@@ -536,7 +542,7 @@ void process_run(struct process *process) {
         pool_alloc(
           &core_table,
           &process->core_item,
-          process_core_blocks + blocks,
+          core_blocks + blocks,
             POOL_ALLOC_MODE_MOVEABLE |
             POOL_ALLOC_MODE_REALLOC
         )
@@ -551,7 +557,7 @@ void process_run(struct process *process) {
 #else /* INDIRECT_CORE */
       core_base = process->core_item.limit - process->swap_blocks;
 #endif /* INDIRECT_CORE */
-      process_core_blocks += blocks;
+      core_blocks += blocks;
       process->swap_blocks -= blocks;
       paras = blocks << BLOCK_PARAS_SHIFT;
 
@@ -650,6 +656,8 @@ void process_free(struct process *process) {
   assert(process->flags & PROCESS_FLAGS_ACTIVE);
 
   // remove from LRU list
+  if (victim == &process->lru_item)
+    victim = &lru_head;
   if (process->lru_item.prev != NULL) {
     process->lru_item.prev->next = process->lru_item.next;
     process->lru_item.next->prev = process->lru_item.prev;
@@ -680,10 +688,6 @@ void process_free(struct process *process) {
 #endif /* INDIRECT_SWAP */
   pool_free(&swap_table, &process->swap_item);
 
-  // fix this later
-  if (process == victim)
-    victim = NULL;
-
   // track total allocation
   process_avail += (process->paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
   process->flags = 0;
index 59df5e3..8ea04ed 100644 (file)
--- a/process.h
+++ b/process.h
@@ -51,9 +51,7 @@ extern int n_processes;
 
 extern int process_avail;
 
-extern struct lru_item lru_head;
-
-extern struct process *victim;
+extern struct lru_item lru_head, *victim;
 
 void process_init(int n, int spare);
 bool process_alloc(struct process *process, int para, int paras);