Implement PREALLOCATE_CORE and PREALLOCATE_SWAP compile time options
authorNick Downing <nick@ndcode.org>
Sun, 17 Mar 2019 02:24:46 +0000 (13:24 +1100)
committerNick Downing <nick@ndcode.org>
Sun, 17 Mar 2019 03:24:11 +0000 (14:24 +1100)
o.sh
process.c
process.h
process_test_run.c

diff --git a/o.sh b/o.sh
index 95e207f..dde4b61 100755 (executable)
--- a/o.sh
+++ b/o.sh
@@ -1,7 +1,12 @@
 #!/bin/sh
 
 echo "generate test script"
-./process_test_gen 16 224 65536 32 >process_test.txt
+# preallocated core, possible preallocated swap:
+#./process_test_gen 16 48 65536 32 >process_test.txt
+# non preallocated core, preallocated swap:
+#./process_test_gen 16 176 65536 32 >process_test.txt
+# non preallocated core, non preallocated swap:
+./process_test_gen 16 240 65536 32 >process_test.txt
 
 echo "run test"
-./process_test_run 16 64 4 192 12 16 <process_test.txt
+./process_test_run 16 64 0 192 0 16 <process_test.txt
index 8dc0337..9e04ef5 100644 (file)
--- a/process.c
+++ b/process.c
@@ -16,51 +16,144 @@ int process_avail, process_spare;
 struct lru_item lru_head;
 
 struct process *victim;
-struct pool_item victim_core_item, victim_swap_item;
+#ifdef PREALLOCATE_CORE
+int victim_core_size;
+#else
+struct pool_item victim_core_item;
+#endif
+#ifdef PREALLOCATE_SWAP
+int victim_swap_size;
+#else
+struct pool_item victim_swap_item;
+#endif
 
 #if 1
 // won't work when compiled with NDEBUG
 static void check_invariants() {
-  int avail =
+#if defined(PREALLOCATE_CORE) && defined(PREALLOCATE_SWAP)
+  int core_head_avail =
     core_head.item.base -
     core_head.item.limit -
-    core_head.spare +
+    core_head.spare;
+  int swap_head_avail =
     swap_head.item.base -
     swap_head.item.limit -
-    swap_head.spare -
-    process_spare;
-  if (victim) {
-    assert(victim_core_item.prev && victim_core_item.next);
-    assert(victim_swap_item.prev && victim_core_item.next);
-  }
-  else {
+    swap_head.spare;
+  int avail = (
+    core_head_avail < swap_head_avail ? core_head_avail : swap_head_avail
+  ) - process_spare;
+#elif defined(PREALLOCATE_CORE)
+  int core_head_avail =
+    core_head.item.base -
+    core_head.item.limit -
+    core_head.spare;
+  int avail = core_head_avail - process_spare;
+#elif defined(PREALLOCATE_SWAP)
+  int swap_head_avail =
+    swap_head.item.base -
+    swap_head.item.limit -
+    swap_head.spare;
+  int avail = swap_head_avail - process_spare;
+#else
+  int core_head_avail =
+    core_head.item.base -
+    core_head.item.limit -
+    core_head.spare;
+  int swap_head_avail =
+    swap_head.item.base -
+    swap_head.item.limit -
+    swap_head.spare;
+  int avail = core_head_avail + swap_head_avail - process_spare;
+#endif
+  if (victim == NULL) {
+#ifdef PREALLOCATE_CORE
+    assert(victim_core_size == 0);
+#else
     assert(victim_core_item.prev == NULL && victim_core_item.next == NULL);
+#endif
+#ifdef PREALLOCATE_SWAP
+    assert(victim_swap_size == 0);
+#else 
     assert(victim_swap_item.prev == NULL && victim_swap_item.prev == NULL);
+#endif
   }
   for (int i = 0; i < n_processes; ++i)
-    if (processes[i].size != -1) {
-      if (processes + i == victim) {
-        assert(processes[i].lru_item.prev == NULL);
+    if (processes[i].size == -1) {
+#ifdef PREALLOCATE_CORE
+      assert(
+        processes[i].core_item.prev == NULL &&
+        processes[i].core_item.next == NULL
+      );
+#endif
+#ifdef PREALLOCATE_SWAP
+      assert(
+        processes[i].swap_item.prev == NULL &&
+        processes[i].swap_item.next == NULL
+      );
+#endif
+    }
+    else {
+#ifdef PREALLOCATE_CORE
+      assert(processes[i].core_item.prev && processes[i].core_item.next);
+#endif
+#ifdef PREALLOCATE_SWAP
+      assert(processes[i].swap_item.prev && processes[i].swap_item.next);
+#endif
+      if (processes[i].lru_item.prev) {
+        assert(processes + i != victim);
+        assert(processes[i].lru_item.prev->next == &processes[i].lru_item);
+        assert(processes[i].lru_item.next->prev == &processes[i].lru_item);
+#ifdef PREALLOCATE_CORE
+#ifndef PREALLOCATE_SWAP
         assert(
           processes[i].pool_item.prev == NULL &&
           processes[i].pool_item.next == NULL
         );
-        int core_size = victim_core_item.limit - victim_core_item.base;
-        assert(core_size);
-        int swap_size = victim_swap_item.limit - victim_swap_item.base;
-        assert(swap_size);
-        assert(processes[i].size == core_size + swap_size);
+#endif
+#else
+        assert(processes[i].pool_item.prev && processes[i].pool_item.next);
+        assert(
+          processes[i].size ==
+            processes[i].pool_item.limit -
+            processes[i].pool_item.base
+        );
+#endif
+      } 
+      else if (processes + i == victim) {
+#if !defined(PREALLOCATE_CORE) || !defined(PREALLOCATE_SWAP)
+        assert(
+          processes[i].pool_item.prev == NULL &&
+          processes[i].pool_item.next == NULL
+        );
+#endif
+#ifndef PREALLOCATE_CORE
+        assert(victim_core_item.prev && victim_core_item.next);
+        int victim_core_size = victim_core_item.limit - victim_core_item.base;
+#endif
+        assert(victim_core_size);
+#ifndef PREALLOCATE_SWAP
+        assert(victim_swap_item.prev && victim_swap_item.next);
+        int victim_swap_size = victim_swap_item.limit - victim_swap_item.base;
+#endif
+        assert(victim_swap_size);
+        assert(processes[i].size == victim_core_size + victim_swap_size);
       }
       else {
-        if (processes[i].lru_item.prev) {
-          assert(processes[i].lru_item.prev->next == &processes[i].lru_item);
-          assert(processes[i].lru_item.next->prev == &processes[i].lru_item);
-        }
+#ifdef PREALLOCATE_SWAP
+#ifndef PREALLOCATE_CORE
+        assert(
+          processes[i].pool_item.prev == NULL &&
+          processes[i].pool_item.next == NULL
+        );
+#endif
+#else
+        assert(processes[i].pool_item.prev && processes[i].pool_item.next);
         assert(
           processes[i].size ==
             processes[i].pool_item.limit -
             processes[i].pool_item.base
         );
+#endif
       }
       avail -= processes[i].size;
     }
@@ -77,7 +170,17 @@ void process_init(int n, int spare) {
     processes[i].size = -1;
 #endif
 
+#if defined(PREALLOCATE_CORE) && defined(PREALLOCATE_SWAP)
+  process_avail = (
+    core_head.avail < swap_head.avail ? core_head.avail : swap_head.avail
+  ) - spare;
+#elif defined(PREALLOCATE_CORE)
+  process_avail = core_head.avail - spare;
+#elif defined(PREALLOCATE_SWAP)
+  process_avail = swap_head.avail - spare;
+#else
   process_avail = core_head.avail + swap_head.avail - spare;
+#endif
   process_spare = spare;
 
   lru_head.prev = &lru_head;
@@ -85,32 +188,49 @@ void process_init(int n, int spare) {
 
   victim = NULL;
 #ifndef NDEBUG
+#ifdef PREALLOCATE_CORE
+  victim_core_size = 0;
+#else
   memset(&victim_core_item, 0, sizeof(victim_core_item));
+#endif
+#ifdef PREALLOCATE_SWAP
+  victim_swap_size = 0;
+#else
   memset(&victim_swap_item, 0, sizeof(victim_swap_item));
+#endif
 #endif
  check_invariants();
 }
 
 static void do_swap_out(int swap_out) {
- printf("swap_out %d\n", swap_out);
-  int victim_size, size;
+#ifndef PREALLOCATE_CORE
+  int victim_core_size;
+#endif
+#ifndef PREALLOCATE_SWAP
+  int victim_swap_size;
+#endif
+  int size;
 
   // loop entry code for the case of an existing victim
   if (swap_out > 0) {
     if (victim) {
       // calculate amount to swap
-      victim_size = victim_core_item.limit - victim_core_item.base;
-      size = swap_out < victim_size ? swap_out : victim_size;
- printf("existing victim %d, swap out %d of %d\n", (int)(victim - processes), size, victim_size);
+#ifndef PREALLOCATE_CORE
+      victim_core_size = victim_core_item.limit - victim_core_item.base;
+#endif
+#ifndef PREALLOCATE_SWAP
+      victim_swap_size = victim_swap_item.limit - victim_swap_item.base;
+#endif
+      size = swap_out < victim_core_size ? swap_out : victim_core_size;
+ printf("existing victim %d, swap out %d of %d\n", (int)(victim - processes), size, victim_core_size);
 
       // increase swap allocation
+      victim_swap_size += size;
+#ifndef PREALLOCATE_SWAP
       rassert(
-        pool_realloc_moveable(
-          &swap_head,
-          &victim_swap_item,
-          size + victim_swap_item.limit - victim_swap_item.base
-        )
+        pool_realloc_moveable(&swap_head, &victim_swap_item, victim_swap_size)
       );
+#endif
       goto loop_entry;
     }
 
@@ -125,47 +245,74 @@ static void do_swap_out(int swap_out) {
       victim->lru_item.next->prev = victim->lru_item.prev;
       victim->lru_item.prev = NULL; // indicates not runnable
 
+#ifndef PREALLOCATE_CORE
       // move per-process to dedicated core item
       pool_move_item(&victim->pool_item, &victim_core_item);
+      victim_core_size = victim_core_item.limit - victim_core_item.base;
+#endif
 
       // calculate amount to swap
-      victim_size = victim_core_item.limit - victim_core_item.base;
-      size = swap_out < victim_size ? swap_out : victim_size;
- printf("new victim %d, swap out %d of %d\n", (int)(victim - processes), size, victim_size);
+      size = swap_out < victim_core_size ? swap_out : victim_core_size;
+ printf("new victim %d, swap out %d of %d\n", (int)(victim - processes), size, victim_core_size);
 
       // add to swap pool, using dedicated swap item
-      rassert(pool_alloc_moveable(&swap_head, &victim_swap_item, size));
+      victim_swap_size = size;
+#ifndef PREALLOCATE_SWAP
+      rassert(
+        pool_alloc_moveable(&swap_head, &victim_swap_item, victim_swap_size)
+      );
+#endif
 
     loop_entry:
       // transfer data to swap
       swap_write(
+#ifdef PREALLOCATE_SWAP
+        ~(victim->swap_item.base + victim_swap_size),
+#else
         ~victim_swap_item.limit,
+#endif
+#ifdef PREALLOCATE_CORE
+        victim->core_item.base + victim_core_size - size,
+#else
         victim_core_item.limit - size,
+#endif
         size
       );
 
       // see if victim fully swapped out
-      victim_size -= size;
-      if (victim_size) {
+      victim_core_size -= size;
+      if (victim_core_size) {
+#ifndef PREALLOCATE_CORE
         // no, reduce core allocation, using dedicated core item
         rassert(
-          pool_realloc_moveable(&core_head, &victim_core_item, victim_size)
+          pool_realloc_moveable(&core_head, &victim_core_item, victim_core_size)
         );
+#endif
 
         // as an optimization, skip the calculation of swap_out -= size
         return;
       }
 
  printf("victimized %d\n", (int)(victim - processes));
+#ifndef PREALLOCATE_CORE
       // remove from core pool, using dedicated core item
       pool_free(&core_head, &victim_core_item);
+#endif
 
+#ifndef PREALLOCATE_SWAP
       // move dedicated to per-process swap item
       pool_move_item(&victim_swap_item, &victim->pool_item);
+#endif
 
       swap_out -= size;
     } while (swap_out);
     victim = NULL;
+#ifdef PREALLOCATE_CORE
+    assert(victim_core_size == 0);
+#endif
+#ifdef PREALLOCATE_SWAP
+    victim_swap_size = 0;
+#endif
   }
 }
 
@@ -185,7 +332,14 @@ bool process_alloc(struct process *process, int size) {
   do_swap_out(swap_out);
 
   // allocate core, can't fail
+#ifdef PREALLOCATE_CORE
+  rassert(pool_alloc_moveable(&core_head, &process->core_item, size));
+#else
   rassert(pool_alloc_moveable(&core_head, &process->pool_item, size));
+#endif
+#ifdef PREALLOCATE_SWAP
+  rassert(pool_alloc_moveable(&swap_head, &process->swap_item, size));
+#endif
 
   // insert at head of LRU list
   process->lru_item.prev = &lru_head;
@@ -220,8 +374,14 @@ bool process_realloc(struct process *process, int size) {
   do_swap_out(swap_out);
 
   // reallocate core, can't fail
+#ifdef PREALLOCATE_CORE
+  rassert(pool_realloc_moveable(&core_head, &process->core_item, size));
+#else
   rassert(pool_realloc_moveable(&core_head, &process->pool_item, size));
-  process->size = size;
+#endif
+#ifdef PREALLOCATE_SWAP
+  rassert(pool_realloc_moveable(&swap_head, &process->swap_item, size));
+#endif
 
   // track total allocation
   process->size = size;
@@ -231,8 +391,15 @@ bool process_realloc(struct process *process, int size) {
 }
 
 void process_run(struct process *process) {
-  int swap_in, size, swap_out;
-  struct pool_item process_core_item, process_swap_item;
+  int size, swap_out;
+  int process_core_size;
+#ifndef PREALLOCATE_CORE
+  struct pool_item process_core_item;
+#endif
+  int process_swap_size;
+#ifndef PREALLOCATE_SWAP
+  struct pool_item process_swap_item;
+#endif
 
   // must be already allocated
   assert(process->size != -1);
@@ -247,18 +414,26 @@ void process_run(struct process *process) {
   else {
     // no, need to swap some in
 #ifndef NDEBUG
+#ifndef PREALLOCATE_CORE
     memset(&process_core_item, 0, sizeof(process_core_item));
+#endif
+#ifndef PREALLOCATE_SWAP
     memset(&process_swap_item, 0, sizeof(process_swap_item));
+#endif
 #endif
 
     // loop entry code for case of fully in swap
     if (process != victim) {
       // fully in swap, take over only the per-process swap item
+#ifdef PREALLOCATE_SWAP
+      process_swap_size = process->size;
+#else
       pool_move_item(&process->pool_item, &process_swap_item);
-      swap_in = process_swap_item.limit - process_swap_item.base;
+      process_swap_size = process_swap_item.limit - process_swap_item.base;
+#endif
 
       // calculate amount to swap
-      size = swap_in;
+      size = process_swap_size;
       swap_out = size - core_head.avail;
       if (swap_out > swap_head.avail) {
         size += swap_head.avail - swap_out;
@@ -269,31 +444,49 @@ void process_run(struct process *process) {
       do_swap_out(swap_out);
 
       // add to core pool, using dedicated core item
-      rassert(pool_alloc_moveable(&core_head, &process_core_item, size));
+      process_core_size = size;
+#ifndef PREALLOCATE_CORE
+      rassert(
+        pool_alloc_moveable(&core_head, &process_core_item, process_core_size)
+      );
+#endif
       goto loop_entry_full;
     }
 
     // victim, take over the dedicated pool items
     victim = NULL;
+#ifdef PREALLOCATE_CORE
+    process_core_size = victim_core_size;
+#ifndef NDEBUG
+    victim_core_size = 0;
+#endif
+#else
     pool_move_item(&victim_core_item, &process_core_item);
+    process_core_size = process_core_item.limit - process_core_item.base;
+#endif
+#ifdef PREALLOCATE_SWAP
+    process_swap_size = victim_swap_size;
+#ifndef NDEBUG
+    victim_swap_size = 0;
+#endif
+#else
     pool_move_item(&victim_swap_item, &process_swap_item);
-    swap_in = process_swap_item.limit - process_swap_item.base;
+    process_swap_size = process_swap_item.limit - process_swap_item.base;
     goto loop_entry_partial;
+#endif
 
     // loop for case of partially in core, partially in swap
     do {
+#ifndef PREALLOCATE_SWAP
       // reduce swap allocation
       rassert(
-        pool_realloc_moveable(
-          &swap_head,
-          &process_swap_item,
-          swap_in
-        )
+        pool_realloc_moveable(&swap_head, &process_swap_item, process_swap_size)
       );
 
     loop_entry_partial:
+#endif
       // calculate how much to swap
-      size = swap_in;
+      size = process_swap_size;
       swap_out = size - core_head.avail;
       if (swap_out > swap_head.avail) {
         size += swap_head.avail - swap_out;
@@ -304,30 +497,41 @@ void process_run(struct process *process) {
       do_swap_out(swap_out);
 
       // increase core allocation
+      process_core_size += size;
+#ifndef PREALLOCATE_CORE
       rassert(
-        pool_realloc_moveable(
-          &core_head,
-          &process_core_item,
-          process_core_item.limit - process_core_item.base + size
-        )
+        pool_realloc_moveable(&core_head, &process_core_item, process_core_size)
       );
+#endif
 
     loop_entry_full:
       // transfer data to core
       swap_read(
+#ifdef PREALLOCATE_SWAP
+        ~(process->swap_item.base + process_swap_size),
+#else
         ~process_swap_item.limit,
+#endif
+#ifdef PREALLOCATE_CORE
+        process->core_item.base + process_core_size - size,
+#else
         process_core_item.limit - size,
+#endif
         size
       );
 
-      swap_in -= size;
-    } while (swap_in);
+      process_swap_size -= size;
+    } while (process_swap_size);
 
+#ifndef PREALLOCATE_CORE
     // move dedicated to per-process core item
     pool_move_item(&process_core_item, &process->pool_item);
+#endif
 
+#ifndef PREALLOCATE_SWAP
     // remove from swap pool, using dedicated swap item
     pool_free(&swap_head, &process_swap_item);
+#endif
   }
 
   // insert at head of LRU list
@@ -342,6 +546,13 @@ void process_free(struct process *process) {
   // must be already allocated
   assert(process->size != -1);
 
+#ifdef PREALLOCATE_CORE
+  pool_free(&core_head, &process->core_item);
+#endif
+#ifdef PREALLOCATE_SWAP
+  pool_free(&swap_head, &process->swap_item);
+#endif
+
   // see whether fully in core, victim, or fully in swap
   if (process->lru_item.prev != NULL) {
     // fully in core, remove from LRU list and core pool
@@ -350,18 +561,30 @@ void process_free(struct process *process) {
     process->lru_item.prev->next = process->lru_item.next;
     process->lru_item.next->prev = process->lru_item.prev;
 
+#ifndef PREALLOCATE_CORE
     pool_free(&core_head, &process->pool_item);
+#endif
   }
   else if (process == victim) {
     // victim, free the dedicated pool items
     victim = NULL;
+#ifdef PREALLOCATE_CORE
+    victim_core_size = 0;
+#else
     pool_free(&core_head, &victim_core_item);
+#endif
+#ifdef PREALLOCATE_SWAP
+    victim_swap_size = 0;
+#else
     pool_free(&swap_head, &victim_swap_item);
+#endif
   }
+#ifndef PREALLOCATE_SWAP
   else {
     // fully in swap, remove from swap pool
     pool_free(&swap_head, &process->pool_item);
   }
+#endif
 
   // track total allocation
   process_avail += process->size;
index 3e5a58b..7893db3 100644 (file)
--- a/process.h
+++ b/process.h
@@ -3,6 +3,9 @@
 
 #include "pool.h"
 
+//#define PREALLOCATE_CORE 1
+//#define PREALLOCATE_SWAP 1
+
 struct lru_item {
   struct lru_item *prev;
   struct lru_item *next;
@@ -10,7 +13,15 @@ struct lru_item {
 
 extern struct process {
   struct lru_item lru_item; // must be first
+#ifdef PREALLOCATE_SWAP
+  struct pool_item swap_item;
+#endif
+#ifdef PREALLOCATE_CORE
+  struct pool_item core_item;
+#endif
+#if !defined(PREALLOCATE_SWAP) || !defined(PREALLOCATE_CORE)
   struct pool_item pool_item;
+#endif
   int size; // brk level
 } *processes;
 int n_processes;
@@ -20,7 +31,16 @@ extern int process_avail, process_spare;
 extern struct lru_item lru_head;
 
 extern struct process *victim;
-extern struct pool_item victim_core_item, victim_swap_item;
+#ifdef PREALLOCATE_CORE
+extern int victim_core_size;
+#else
+extern struct pool_item victim_core_item;
+#endif
+#ifdef PREALLOCATE_SWAP
+extern int victim_swap_size;
+#else
+extern struct pool_item victim_swap_item;
+#endif
 
 void process_init(int n, int spare);
 bool process_alloc(struct process *process, int size);
index d224016..215f53f 100644 (file)
@@ -60,16 +60,22 @@ int main(int argc, char **argv) {
           processes[process].size = -1;
         }
         else {
-          int base = processes[process].pool_item.base;
- printf("new core [%d,%d)\n", base, base + size);
- rassert(processes[process].pool_item.limit == base + size); 
+#ifdef PREALLOCATE_CORE
+          int core_base = processes[process].core_item.base;
+#else
+          int core_base = processes[process].pool_item.base;
+#endif
+ printf("new core [%d,%d)\n", core_base, core_base + size);
           for (int i = 0; i < size; ++i) {
-            rassert(core_mem[base + i] == 0xaaaaaaaa);
+            rassert(core_mem[core_base + i] == 0xaaaaaaaa);
             long long hash = process * 17 + i * 29;
             hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
             hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
-            core_mem[base + i] = (int)hash;
+            core_mem[core_base + i] = (int)hash;
           }
+#ifdef PREALLOCATE_SWAP
+ printf("new swap [%d,%d)\n", ~processes[process].swap_item.limit, ~processes[process].swap_item.base);
+#endif
         }
       }
     }
@@ -89,7 +95,14 @@ int main(int argc, char **argv) {
           success
         );
       else {
+#ifdef PREALLOCATE_CORE
+ printf("old core [%d,%d)\n", processes[process].core_item.base, processes[process].core_item.limit);
+#else
  printf("old core [%d,%d)\n", processes[process].pool_item.base, processes[process].pool_item.limit);
+#endif
+#ifdef PREALLOCATE_SWAP
+ printf("old swap [%d,%d)\n", ~processes[process].swap_item.limit, processes[process].swap_item.base);
+#endif
         int actual_old_size = processes[process].size;
         rassert(actual_old_size <= old_size);
         bool result = process_realloc(processes + process, size);
@@ -110,23 +123,29 @@ int main(int argc, char **argv) {
             rassert(process_realloc(processes + process, actual_old_size));
           }
           else {
-            int base = processes[process].pool_item.base;
- printf("new core [%d,%d)\n", base, base + size);
- rassert(processes[process].pool_item.limit == base + size); 
+#ifdef PREALLOCATE_CORE
+            int core_base = processes[process].core_item.base;
+#else
+            int core_base = processes[process].pool_item.base;
+#endif
+ printf("new core [%d,%d)\n", core_base, core_base + size);
             for (int i = actual_old_size; i < size; ++i) {
-              rassert(core_mem[base + i] == 0xaaaaaaaa);
+              rassert(core_mem[core_base + i] == 0xaaaaaaaa);
               long long hash = process * 17 + i * 29;
               hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
               hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
-              core_mem[base + i] = (int)hash;
+              core_mem[core_base + i] = (int)hash;
             }
             for (int i = size; i < actual_old_size; ++i) {
               long long hash = process * 17 + i * 29;
               hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
               hash = (hash & 0xffffffffffffffffLL) + (hash >> 32);
-              rassert(core_mem[base + i] == (int)hash);
-              core_mem[base + i] = 0xaaaaaaaa;
+              rassert(core_mem[core_base + i] == (int)hash);
+              core_mem[core_base + i] = 0xaaaaaaaa;
             }
+#ifdef PREALLOCATE_SWAP
+ printf("new swap [%d,%d)\n", ~processes[process].swap_item.limit, ~processes[process].swap_item.base);
+#endif
           }
         }
       }
@@ -154,10 +173,25 @@ int main(int argc, char **argv) {
           old_size
         );
       else {
-        bool is_victim = processes + process == victim;
-        bool in_core = processes[process].lru_item.prev != NULL;
         int actual_old_size = processes[process].size;
         rassert(actual_old_size <= old_size);
+        bool is_victim = processes + process == victim;
+        bool in_core = processes[process].lru_item.prev != NULL;
+#ifdef PREALLOCATE_CORE
+        int core_size = is_victim ? victim_core_size : in_core ? processes[process].size : 0;
+        int core_base = processes[process].core_item.base;
+#else
+        int core_base = is_victim ? victim_core_item.base : in_core ? processes[process].pool_item.base : -1;
+        int core_size = is_victim ? victim_core_item.limit - core_base : in_core ? processes[process].pool_item.limit - core_base : 0;
+#endif
+#ifdef PREALLOCATE_SWAP
+        int swap_size = is_victim ? victim_swap_size : !in_core ? processes[process].size : 0;
+        int swap_limit = processes[process].swap_item.base + swap_size;
+#else
+        int swap_limit = is_victim ? victim_swap_item.limit : !in_core ? processes[process].pool_item.limit : 0;
+        int swap_size = is_victim ? swap_limit - victim_swap_item.base : !in_core ? swap_limit - processes[process].pool_item.base : 0;
+#endif
+        rassert(core_size + swap_size == actual_old_size);
         process_free(processes + process);
         processes[process].size = -1;
         printf(
@@ -166,11 +200,6 @@ int main(int argc, char **argv) {
           old_size,
           actual_old_size
         );
-        int core_base = is_victim ? victim_core_item.base : in_core ? processes[process].pool_item.base : -1;
-        int core_size = is_victim ? victim_core_item.limit - core_base : in_core ? processes[process].pool_item.limit - core_base : 0;
-        int swap_limit = is_victim ? victim_swap_item.limit : !in_core ? processes[process].pool_item.limit : 0;
-        int swap_size = is_victim ? swap_limit - victim_swap_item.base : !in_core ? swap_limit - processes[process].pool_item.base : 0;
-        rassert(core_size + swap_size == actual_old_size);
         int swap_base = ~swap_limit;
  printf("old core [%d,%d) swap [%d,%d)\n", core_base, core_base + core_size, swap_base, swap_base + swap_size);
         for (int i = 0; i < actual_old_size; ++i) {
@@ -200,10 +229,20 @@ done:
     else {
       bool is_victim = processes + i == victim;
       bool in_core = processes[i].lru_item.prev != NULL;
+#ifdef PREALLOCATE_CORE
+      int core_size = is_victim ? victim_core_size : in_core ? processes[i].size : 0;
+      int core_base = processes[i].core_item.base;
+#else
       int core_base = is_victim ? victim_core_item.base : in_core ? processes[i].pool_item.base : -1;
       int core_size = is_victim ? victim_core_item.limit - core_base : in_core ? processes[i].pool_item.limit - core_base : 0;
+#endif
+#ifdef PREALLOCATE_SWAP
+      int swap_size = is_victim ? victim_swap_size : !in_core ? processes[i].size : 0;
+      int swap_limit = processes[i].swap_item.base + swap_size;
+#else
       int swap_limit = is_victim ? victim_swap_item.limit : !in_core ? processes[i].pool_item.limit : 0;
       int swap_size = is_victim ? swap_limit - victim_swap_item.base : !in_core ? swap_limit - processes[i].pool_item.base : 0;
+#endif
       int swap_base = ~swap_limit;
       printf("process %d: core [%d,%d) swap [%d,%d)\n", i, core_base, core_base + core_size, swap_base, swap_base + swap_size);
       for (int j = 0; j < processes[i].size; ++j) {