Implement process->para so that start of data is independent of block boundary, imple...
authorNick Downing <nick@ndcode.org>
Sat, 1 Jun 2019 11:14:20 +0000 (21:14 +1000)
committerNick Downing <nick@ndcode.org>
Sat, 1 Jun 2019 11:14:20 +0000 (21:14 +1000)
core.c
o.sh
pool_test_gen.c
process.c
process.h
process_test.h
process_test_gen.c
process_test_run.c

diff --git a/core.c b/core.c
index 9fe3377..9cf74cb 100644 (file)
--- a/core.c
+++ b/core.c
@@ -17,7 +17,8 @@ static void core_move(struct pool_item *item, int new_base) {
   int base, blocks;
 #ifndef INDIRECT_CORE
   struct process *process;
-  int paras;
+  struct process_state state;
+  int para;
 #else /* INDIRECT_CORE */
   int i;
 #endif /* INDIRECT_CORE */
@@ -26,53 +27,79 @@ static void core_move(struct pool_item *item, int new_base) {
   blocks = item->limit - base;
  printf("core_move [%d,%d) to [%d,%d)\n", base, base + blocks, new_base, new_base + blocks);
   assert(new_base <= base || new_base >= base + blocks);
+
 #ifndef INDIRECT_CORE
-  // see if incomplete last block, if so don't copy extra part
-  process =
-    (struct process *)((char *)item - offsetof(struct process, core_item));
-  paras = blocks << BLOCK_PARAS_SHIFT;
-  if (paras > process->paras)
-    paras = process->paras;
+#if 0 // debugging
+ core_copy(
+  base << BLOCK_PARAS_SHIFT,
+  new_base << BLOCK_PARAS_SHIFT,
+  blocks << BLOCK_PARAS_SHIFT
+ );
+#else
+  // figure out how much of item is valid
+  process = (struct process *)(
+    (char *)item - offsetof(struct process, core_item)
+  );
+  process_get_state(process, &state);
+ printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_base, state.core_base + state.core_blocks, state.swap_base, state.swap_base + state.swap_blocks);
 
-  // copy by abstract routine
-  core_copy(base << BLOCK_PARAS_SHIFT, new_base << BLOCK_PARAS_SHIFT, paras);
+  // copy valid part by abstract routine
+  para =
+    (state.core_base << BLOCK_PARAS_SHIFT) +
+    state.core_para;
+  core_copy(
+    para,  
+    para + ((new_base - base) << BLOCK_PARAS_SHIFT),
+    state.core_paras
+  );
+#endif
+#else /* INDIRECT_CORE */
+  for (i = 0; i < blocks; ++i) {
+    core_table_mem[new_base + i] = core_table_mem[base + i];
+    core_table_mem[base + i] = 0x55555555;
+  }
+#endif
 }
 
+#ifndef INDIRECT_CORE
 static void core_move_up(struct pool_item *item, int new_limit) {
   int limit, blocks;
-  int limit1, new_limit1, paras;
   struct process *process;
-  int trim;
+  struct process_state state;
+  int para;
 
   limit = item->limit;
   blocks = limit - item->base;
  printf("core_move_up [%d,%d) to [%d,%d)\n", limit - blocks, limit, new_limit - blocks, new_limit);
   assert(new_limit >= limit || new_limit <= limit - blocks);
-  // set up transfer parameters
-  limit1 = limit << BLOCK_PARAS_SHIFT;
-  new_limit1 = new_limit << BLOCK_PARAS_SHIFT;
-  paras = blocks << BLOCK_PARAS_SHIFT;
 
-  // see if incomplete last block, if so don't copy extra part
-  process =
-    (struct process *)((char *)item - offsetof(struct process, core_item));
-  trim = paras - process->paras;
-  if (trim > 0) {
-    limit1 -= trim;
-    new_limit1 -= trim;
-    paras = process->paras;
-#else /* INDIRECT_CORE */
-  for (i = 0; i < blocks; ++i) {
-    core_table_mem[new_base + i] = core_table_mem[base + i];
-    core_table_mem[base + i] = 0x55555555;
-#endif /* INDIRECT_CORE */
-  }
+#if 0 // debugging
+ core_copy_up(
+  limit << BLOCK_PARAS_SHIFT,
+  new_limit << BLOCK_PARAS_SHIFT,
+  blocks << BLOCK_PARAS_SHIFT
+ );
+#else
+  // figure out how much of item is valid
+  process = (struct process *)(
+    (char *)item - offsetof(struct process, core_item)
+  );
+  process_get_state(process, &state);
+ printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_base, state.core_base + state.core_blocks, state.swap_base, state.swap_base + state.swap_blocks);
 
-#ifndef INDIRECT_CORE
-  // copy by abstract routine
-  core_copy_up(limit1, new_limit1, paras);
-#endif /* ! INDIRECT_CORE */
+  // copy valid part by abstract routine
+  para =
+    (state.core_base << BLOCK_PARAS_SHIFT) +
+    state.core_para +
+    state.core_paras;
+  core_copy_up(
+    para,  
+    para + ((new_limit - limit) << BLOCK_PARAS_SHIFT),
+    state.core_paras
+  );
+#endif
 }
+#endif /* ! INDIRECT_CORE */
 
 #ifndef INDIRECT_CORE
 void core_init(int n_blocks)
diff --git a/o.sh b/o.sh
index 88524fa..f9a7a7f 100755 (executable)
--- a/o.sh
+++ b/o.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 echo "generate test script"
-./process_test_gen 16 248 1024 32 >process_test.txt
+./process_test_gen 16 248 1024 32 true true >process_test.txt
 
 echo "run test script"
 ./process_test_run 16 64 192 8 384 384 <process_test.txt
index c459ced..9128efc 100644 (file)
@@ -12,14 +12,14 @@ int rand_int(int n) {
 
 int main(int argc, char **argv) {
   if (argc < 5) {
-    printf("usage: %s n_items pool_size n_events item_size [base [seed]]\n", argv[0]);
+    printf("usage: %s n_items pool_size n_events item_size [do_base [seed]]\n", argv[0]);
     exit(EXIT_FAILURE);
   }
   int n_items = atoi(argv[1]);
   int pool_size = atoi(argv[2]);
   int n_events = atoi(argv[3]);
   int item_size = atoi(argv[4]);
-  bool base = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
+  bool do_base = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
   int seed = argc >= 7 ? atoi(argv[6]) : 1;
 
   int *items = malloc(n_items * sizeof(int));
@@ -50,7 +50,7 @@ int main(int argc, char **argv) {
       bool success = pool_used + size - old_size <= pool_size;
       printf(
         "realloc%s %d %d %d %s\n",
-        base && rand_int(3) == 0 ? "_base" : "",
+        do_base && rand_int(3) == 0 ? "_base" : "",
         item,
         old_size,
         size,
index 7f3edf4..c122e11 100644 (file)
--- a/process.c
+++ b/process.c
@@ -14,6 +14,9 @@ int process_avail;
 
 struct lru_item lru_head;
 
+struct process *runner;
+int runner_swap_blocks;
+
 struct process *victim;
 int victim_swap_blocks;
 
@@ -252,14 +255,14 @@ static bool do_swap_out(int swap_out) {
   return true;
 }
 
-bool process_alloc(struct process *process, int paras) {
+bool process_alloc(struct process *process, int para, int paras) {
   int blocks;
 
   // must not be already allocated
   assert(process->paras == -1);
 
   // check blocks
-  blocks = (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+  blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
   if (
     process_avail < blocks ||
     !pool_alloc(
@@ -316,13 +319,14 @@ bool process_alloc(struct process *process, int paras) {
   process->lru_item.next->prev = &process->lru_item;
 
   // track total allocation
+  process->para = para;
   process->paras = paras;
   process_avail -= blocks;
   return true;
 }
 
-bool process_realloc(struct process *process, int paras) {
-  int old_blocks, blocks, blocks_change;
+bool process_realloc(struct process *process, int paras, bool dir) {
+  int old_blocks, para, blocks, blocks_change;
 
   // must be already allocated
   assert(process->paras != -1);
@@ -332,7 +336,10 @@ bool process_realloc(struct process *process, int paras) {
 
   // check blocks
   old_blocks = process->swap_item.limit - process->swap_item.base;
-  blocks = (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+  para = process->para;
+  if (dir)
+    para = (old_blocks << BLOCK_PARAS_SHIFT) - para - process->paras;
+  blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
   blocks_change = blocks - old_blocks;
   if (process_avail < blocks_change)
     return false;
@@ -378,10 +385,9 @@ bool process_realloc(struct process *process, int paras) {
       &process->core_item,
       blocks,
 #ifndef INDIRECT_CORE
-      POOL_ALLOC_MODE_MOVEABLE |
-        POOL_ALLOC_MODE_REALLOC
+      dir | (POOL_ALLOC_MODE_MOVEABLE | POOL_ALLOC_MODE_REALLOC)
 #else /* INDIRECT_CORE */
-      POOL_ALLOC_MODE_REALLOC
+      dir | POOL_ALLOC_MODE_REALLOC
 #endif /* INDIRECT_CORE */
     )
 #ifndef INDIRECT_CORE
@@ -418,13 +424,15 @@ bool process_realloc(struct process *process, int paras) {
 #endif /* INDIRECT_CORE */
 
   // track total allocation
+  if (dir)
+    process->para = (blocks << BLOCK_PARAS_SHIFT) - para - paras;
   process->paras = paras;
   process_avail -= blocks_change;
   return true;
 }
 
 void process_run(struct process *process) {
-  int blocks, process_core_blocks, process_swap_blocks;
+  int blocks, runner_core_blocks, runner_swap_blocks;
   int swap_base, core_base;
   int paras;
 #ifndef INDIRECT_CORE
@@ -451,22 +459,23 @@ void process_run(struct process *process) {
     // loop entry code for case of fully in swap
     if (process != victim) {
       // fully in swap, only the swap item is meaningful
-      process_swap_blocks =
+      runner_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);
+      do_swap_out(runner_swap_blocks - core_table.avail);
       blocks = core_table.avail;
 #else /* INDIRECT_CORE */
-      do_swap_out(process_swap_blocks - core_block_pool.avail);
+      do_swap_out(runner_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 > runner_swap_blocks)
+        blocks = runner_swap_blocks;
 
       // add to core pool
-      process_core_blocks = 0;
+      runner = process;
+      runner_core_blocks = 0;
 #ifndef INDIRECT_CORE
       rassert(
         pool_alloc(
@@ -481,27 +490,28 @@ void process_run(struct process *process) {
     }
 
     // victim, take over the dedicated pool items
-    process_core_blocks =
+    runner = victim;
+    runner_core_blocks =
 #ifndef INDIRECT_CORE
       victim->core_item.limit - victim->core_item.base;
 #else /* INDIRECT_CORE */
       victim->core_item.limit - victim->core_item.base - victim_swap_blocks;
 #endif /* INDIRECT_CORE */
-    process_swap_blocks = victim_swap_blocks;
+    runner_swap_blocks = victim_swap_blocks;
     victim = NULL;
 
     // loop for case of partially in core, partially in swap
     do {
       // free up as much core as we can
 #ifndef INDIRECT_CORE
-      do_swap_out(process_swap_blocks - core_table.avail);
+      do_swap_out(runner_swap_blocks - core_table.avail);
       blocks = core_table.avail;
 #else /* INDIRECT_CORE */
-      do_swap_out(process_swap_blocks - core_block_pool.avail);
+      do_swap_out(runner_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 > runner_swap_blocks)
+        blocks = runner_swap_blocks;
 
       // increase core allocation
 #ifndef INDIRECT_CORE
@@ -509,7 +519,7 @@ void process_run(struct process *process) {
         pool_alloc(
           &core_table,
           &process->core_item,
-          process_core_blocks + blocks,
+          runner_core_blocks + blocks,
             POOL_ALLOC_MODE_MOVEABLE |
             POOL_ALLOC_MODE_REALLOC
         )
@@ -518,14 +528,14 @@ void process_run(struct process *process) {
 
     loop_entry_full:
       // calculate transfer parameters
-      swap_base = process->swap_item.limit - process_swap_blocks;
+      swap_base = process->swap_item.limit - runner_swap_blocks;
 #ifndef INDIRECT_CORE
       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 - runner_swap_blocks;
 #endif /* INDIRECT_CORE */
-      process_core_blocks += blocks;
-      process_swap_blocks -= blocks;
+      runner_core_blocks += blocks;
+      runner_swap_blocks -= blocks;
       paras = blocks << BLOCK_PARAS_SHIFT;
 
       // transfer data to core
@@ -608,8 +618,9 @@ void process_run(struct process *process) {
       block_pool_free(&swap_block_pool, swap_table_mem + swap_base, blocks);
 #endif /* INDIRECT_SWAP */
 #endif /* INDIRECT_CORE */
-    } while (process_swap_blocks);
+    } while (runner_swap_blocks);
   }
+  runner = NULL;
 
   // insert at head of LRU list
   process->lru_item.prev = &lru_head;
@@ -697,3 +708,68 @@ void process_free(struct process *process) {
   process_avail += (process->paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
   process->paras = -1;
 }
+
+// improve this later
+void process_get_state(struct process *process, struct process_state *state) {
+  if (process->lru_item.prev != NULL) { // fully in core
+    assert(process != runner);
+    assert(process != victim);
+    state->core_base = process->core_item.base;
+    state->core_blocks = process->core_item.limit - process->core_item.base;
+    state->core_para = process->para;
+    state->core_paras = process->paras;
+    state->swap_base = -1;
+    state->swap_blocks = 0;
+    state->swap_para = 0;
+    state->swap_paras = 0;
+  }
+  else {
+    if (process == runner) { // partially in core, partially in swap
+      assert(process != victim);
+      state->core_base = process->core_item.base;
+      state->core_blocks =
+#ifndef INDIRECT_CORE
+        process->core_item.limit - process->core_item.base;
+#else /* INDIRECT_CORE */
+        process->core_item.limit -
+          process->core_item.base -
+          runner_swap_blocks;
+#endif /* INDIRECT_CORE */
+      state->core_para = process->para;
+      state->core_paras =
+        (state->core_blocks << BLOCK_PARAS_SHIFT) - process->para;
+      state->swap_base = process->swap_item.limit - runner_swap_blocks;
+      state->swap_blocks = runner_swap_blocks;
+      state->swap_para = 0;
+      state->swap_paras = process->paras - state->core_paras;
+    }
+    else if (process == victim) { // partially in core, partially in swap
+      state->core_base = process->core_item.base;
+      state->core_blocks =
+#ifndef INDIRECT_CORE
+        process->core_item.limit - process->core_item.base;
+#else /* INDIRECT_CORE */
+        process->core_item.limit -
+          process->core_item.base -
+          victim_swap_blocks;
+#endif /* INDIRECT_CORE */
+      state->core_para = process->para;
+      state->core_paras =
+        (state->core_blocks << BLOCK_PARAS_SHIFT) - process->para;
+      state->swap_base = process->swap_item.limit - victim_swap_blocks;
+      state->swap_blocks = victim_swap_blocks;
+      state->swap_para = 0;
+      state->swap_paras = process->paras - state->core_paras;
+    }
+    else { // fully in swap
+      state->core_base = -1;
+      state->core_blocks = 0;
+      state->core_para = 0;
+      state->core_paras = 0;
+      state->swap_base = process->swap_item.base;
+      state->swap_blocks = process->swap_item.limit - process->swap_item.base;
+      state->swap_para = process->para;
+      state->swap_paras = process->paras;
+    }
+  }
+}
index b934ce2..f181532 100644 (file)
--- a/process.h
+++ b/process.h
@@ -21,27 +21,46 @@ struct lru_item {
   struct lru_item *next;
 };
 
-extern struct process {
+struct process {
   struct lru_item lru_item; // must be first
   struct pool_item core_item;
   struct pool_item swap_item;
+  int para; // wasted space in first block due to prior use of expand-down
   int paras; // brk level
-} *processes;
-int n_processes;
+};
+
+// improve this later
+struct process_state {
+  int core_base;
+  int core_blocks;
+  int core_para;
+  int core_paras;
+  int swap_base;
+  int swap_blocks;
+  int swap_para;
+  int swap_paras;
+};
+
+extern struct process *processes;
+extern int n_processes;
 
 extern int process_avail;
 
 extern struct lru_item lru_head;
 
+extern struct process *runner;
+extern int runner_swap_blocks;
+
 extern struct process *victim;
 extern int victim_swap_blocks;
 
 void process_init(int n, int spare);
-bool process_alloc(struct process *process, int paras);
-bool process_realloc(struct process *process, int paras);
+bool process_alloc(struct process *process, int para, int paras);
+bool process_realloc(struct process *process, int paras, bool dir);
 void process_run(struct process *process);
 void process_free(struct process *process);
-
+void process_get_state(struct process *process, struct process_state *state);
 // abstract
 void core_to_swap_copy(int src_base, int dest_base, int paras);
 void swap_to_core_copy(int src_base, int dest_base, int paras);
index 9a0045a..ab2e770 100644 (file)
@@ -5,14 +5,17 @@
 
 #define PROCESS_TEST_TYPE_ALLOC 0
 #define PROCESS_TEST_TYPE_REALLOC 1
-#define PROCESS_TEST_TYPE_RUN 2
-#define PROCESS_TEST_TYPE_FREE 3
+#define PROCESS_TEST_TYPE_REALLOC_BASE 2
+#define PROCESS_TEST_TYPE_RUN 3
+#define PROCESS_TEST_TYPE_FREE 4
 
 struct process_test {
   int type;
   int process;
+  int old_para; // for checking only
   int old_paras; // for checking only
   int old_blocks; // for checking only
+  int para;
   int paras;
   int blocks; // for checking only
   bool success;
index 8c4e881..7867b9d 100644 (file)
@@ -21,22 +21,29 @@ int rand_int(int n) {
   return (int)((long)rand() * n / (RAND_MAX + 1L));
 }
 
+struct process {
+  int para;
+  int paras;
+};
+
 int main(int argc, char **argv) {
   if (argc < 5) {
-    printf("usage: %s n_processes pool_blocks n_events process_blocks [seed]\n", argv[0]);
+    printf("usage: %s n_processes pool_blocks n_events process_blocks [do_para [do_base [seed]]]\n", argv[0]);
     exit(EXIT_FAILURE);
   }
   int n_processes = atoi(argv[1]);
   int pool_blocks = atoi(argv[2]);
   int n_events = atoi(argv[3]);
   int process_blocks = atoi(argv[4]);
-  int seed = argc >= 6 ? atoi(argv[5]) : 1;
+  bool do_para = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
+  bool do_base = argc >= 7 ? strcmp(argv[6], "false") != 0 : false;
+  int seed = argc >= 8 ? atoi(argv[7]) : 1;
 
   int process_paras = process_blocks << BLOCK_PARAS_SHIFT;
 
-  int *processes = malloc(n_processes * sizeof(int));
+  struct process *processes = malloc(n_processes * sizeof(struct process));
   rassert(processes);
-  memset(processes, -1, n_processes * sizeof(int));
+  memset(processes, -1, n_processes * sizeof(struct process));
 
   srand(seed);
   int pool_used = 0;
@@ -47,11 +54,14 @@ int main(int argc, char **argv) {
 #endif
 
     test.process = rand_int(n_processes);
-    test.old_paras = processes[test.process];
+    test.old_para = processes[test.process].para;
+    test.old_paras = processes[test.process].paras;
     if (test.old_paras == -1) {
       test.old_blocks = -1;
+      test.para = do_para ? rand_int(BLOCK_PARAS) : 0;
       test.paras = rand_int(process_paras + 1);
-      test.blocks = (test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+      test.blocks =
+        (test.para + test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
       test.success = pool_used + test.blocks <= pool_blocks;
 
 #ifdef __FUZIX__
@@ -59,8 +69,9 @@ int main(int argc, char **argv) {
       write(1, &test, sizeof(test));
 #else
       printf(
-        "alloc %d %d %d %s\n",
+        "alloc %d %d %d %d %s\n",
         test.process,
+        test.para,
         test.paras,
         test.blocks,
         test.success ? "true" : "false"
@@ -68,13 +79,17 @@ int main(int argc, char **argv) {
 #endif
 
       if (test.success) {
-        processes[test.process] = test.paras;
+        processes[test.process].para = test.para;
+        processes[test.process].paras = test.paras;
         pool_used += test.blocks;
       }
     }
     else {
-      test.old_blocks =
-        (test.old_paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+      test.old_blocks = (
+        test.old_para +
+        test.old_paras +
+        (BLOCK_PARAS - 1)
+      ) >> BLOCK_PARAS_SHIFT;
       if (rand_int(64)) {
 #ifdef __FUZIX__
         test.type = PROCESS_TEST_TYPE_RUN;
@@ -84,22 +99,46 @@ int main(int argc, char **argv) {
 #endif
 
         if (rand_int(8) == 0) {
+          bool base = do_base && rand_int(3) == 0;
+
+          test.para = test.old_para;
+          if (base)
+            test.para =
+              (test.old_blocks << BLOCK_PARAS_SHIFT) -
+              test.para -
+              test.old_paras;
+
           test.paras =
             rand_int(process_paras + 1);
-          test.blocks =
-            (test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+          test.blocks = (
+            test.para +
+            test.paras +
+            (BLOCK_PARAS - 1)
+          ) >> BLOCK_PARAS_SHIFT;
           test.success =
              pool_used + test.blocks - test.old_blocks <= pool_blocks;
 
+          if (base)
+            test.para =
+              (test.blocks << BLOCK_PARAS_SHIFT) -
+              test.para -
+              test.paras;
+
 #ifdef __FUZIX__
-          test.type = PROCESS_TEST_TYPE_REALLOC;
+          test.type =
+            base ?
+              PROCESS_TEST_TYPE_REALLOC_BASE :
+              PROCESS_TEST_TYPE_REALLOC;
           write(1, &test, sizeof(test));
 #else
           printf(
-            "realloc %d %d %d %d %d %s\n",
+            "realloc%s %d %d %d %d %d %d %d %s\n",
+            base ? "_base" : "",
             test.process,
+            test.old_para,
             test.old_paras,
             test.old_blocks,
+            test.para,
             test.paras,
             test.blocks,
             test.success ? "true" : "false"
@@ -107,7 +146,8 @@ int main(int argc, char **argv) {
 #endif
 
           if (test.success) {
-            processes[test.process] = test.paras;
+            processes[test.process].para = test.para;
+            processes[test.process].paras = test.paras;
             pool_used += test.blocks - test.old_blocks;
           }
         }
@@ -118,13 +158,15 @@ int main(int argc, char **argv) {
         write(1, &test, sizeof(test));
 #else
         printf(
-          "free %d %d %d\n",
+          "free %d %d %d %d\n",
           test.process,
+          test.old_para,
           test.old_paras,
           test.old_blocks
         );
 #endif
-        processes[test.process] = -1;
+        //processes[test.process].para = -1;
+        processes[test.process].paras = -1;
         pool_used -= test.old_blocks;
       }
     }
index 2f8af0e..474e81d 100644 (file)
@@ -70,7 +70,7 @@ void swap_hash_verify(int process, int base, int paras, int offset) {
 void core_copy(int src_base, int dest_base, int paras) {
   int i;
 
- printf("core_copy %d(%d) %d(%d) %d(%d)\n", src_base, src_base >> BLOCK_PARAS_SHIFT, dest_base, dest_base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
//printf("core_copy %d(%d) %d(%d) %d(%d)\n", src_base, src_base >> BLOCK_PARAS_SHIFT, dest_base, dest_base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
   for (i = 0; i < paras; ++i) {
     core_block_mem[dest_base + i] = core_block_mem[src_base + i];
     core_block_mem[src_base + i] = 0xaaaaaaaa;
@@ -80,7 +80,7 @@ void core_copy(int src_base, int dest_base, int paras) {
 void core_copy_up(int src_limit, int dest_limit, int paras) {
   int i;
 
- printf("core_copy_up %d(%d) %d(%d) %d(%d)\n", src_limit, src_limit >> BLOCK_PARAS_SHIFT, dest_limit, dest_limit >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
//printf("core_copy_up %d(%d) %d(%d) %d(%d)\n", src_limit, src_limit >> BLOCK_PARAS_SHIFT, dest_limit, dest_limit >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
   paras = -paras;
   for (i = -1; i >= paras; --i) {
     core_block_mem[dest_limit + i] = core_block_mem[src_limit + i];
@@ -164,11 +164,9 @@ int main(int argc, char **argv) {
   char buf[256];
 #endif
   bool result;
-  int old_paras, old_blocks;
-  int swap_base, swap_blocks;
-  int swap_paras;
-  int core_base, core_blocks;
-  int core_paras;
+  int old_para, old_paras, old_blocks;
+  int new_para, new_paras, new_blocks;
+  struct process_state state;
 
   if (argc < 5) {
     printf(
@@ -246,14 +244,16 @@ int main(int argc, char **argv) {
       test.type = PROCESS_TEST_TYPE_ALLOC;
       rassert(
         scanf(
-          "%d %d %d %s",
+          "%d %d %d %d %s",
           &test.process,
+          &test.para,
           &test.paras,
           &test.blocks,
           buf
-        ) == 4
+        ) == 5
       );
       rassert(test.process >= 0 && test.process < n_processes);
+      rassert(test.para >= 0);
       rassert(test.paras >= 0);
       rassert(test.blocks >= 0);
       if (strcmp(buf, "false") == 0)
@@ -267,18 +267,51 @@ int main(int argc, char **argv) {
       test.type = PROCESS_TEST_TYPE_REALLOC;
       rassert(
         scanf(
-          "%d %d %d %d %d %s",
+          "%d %d %d %d %d %d %d %s",
+          &test.process,
+          &test.old_para,
+          &test.old_paras,
+          &test.old_blocks,
+          &test.para,
+          &test.paras,
+          &test.blocks,
+          buf
+        ) == 8
+      );
+      rassert(test.process >= 0 && test.process < n_processes);
+      rassert(test.old_para >= 0);
+      rassert(test.old_paras >= 0);
+      rassert(test.old_blocks >= 0);
+      rassert(test.para >= 0);
+      rassert(test.paras >= 0);
+      rassert(test.blocks >= 0);
+      if (strcmp(buf, "false") == 0)
+        test.success = false;
+      else if (strcmp(buf, "true") == 0)
+        test.success = true;
+      else
+        rassert(false);
+    }
+    else if (strcmp(buf, "realloc_base") == 0) {
+      test.type = PROCESS_TEST_TYPE_REALLOC_BASE;
+      rassert(
+        scanf(
+          "%d %d %d %d %d %d %d %s",
           &test.process,
+          &test.old_para,
           &test.old_paras,
           &test.old_blocks,
+          &test.para,
           &test.paras,
           &test.blocks,
           buf
-        ) == 6
+        ) == 8
       );
       rassert(test.process >= 0 && test.process < n_processes);
+      rassert(test.old_para >= 0);
       rassert(test.old_paras >= 0);
       rassert(test.old_blocks >= 0);
+      rassert(test.para >= 0);
       rassert(test.paras >= 0);
       rassert(test.blocks >= 0);
       if (strcmp(buf, "false") == 0)
@@ -297,13 +330,15 @@ int main(int argc, char **argv) {
       test.type = PROCESS_TEST_TYPE_FREE;
       rassert(
         scanf(
-          "%d %d %d",
+          "%d %d %d %d",
           &test.process,
+          &test.old_para,
           &test.old_paras,
           &test.old_blocks
-        ) == 3
+        ) == 4
       );
       rassert(test.process >= 0 && test.process < n_processes);
+      rassert(test.old_para >= 0);
       rassert(test.old_paras >= 0);
       rassert(test.old_blocks >= 0);
     }
@@ -313,14 +348,19 @@ int main(int argc, char **argv) {
     switch (test.type) {
     case PROCESS_TEST_TYPE_ALLOC:
       printf(
-        "alloc %d %d %d %s\n",
+        "alloc %d %d %d %d %s\n",
         test.process,
+        test.para,
         test.paras,
         test.blocks,
         test.success ? "true" : "false"
       );
       rassert(processes[test.process].paras == -1);
-      result = process_alloc(processes + test.process, test.paras);
+      result = process_alloc(
+        processes + test.process,
+        test.para,
+        test.paras
+      );
       printf(
         "... %s\n",
         result == test.success ?
@@ -335,6 +375,8 @@ int main(int argc, char **argv) {
         }
         else {
  printf("new core [%d,%d) swap reservation [%d, %d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+          rassert(processes[test.process].para == test.para);
+          rassert(processes[test.process].paras == test.paras);
           rassert(
             processes[test.process].swap_item.limit -
               processes[test.process].swap_item.base ==
@@ -342,7 +384,8 @@ int main(int argc, char **argv) {
           );
           core_hash_init(
             test.process,
-            processes[test.process].core_item.base << BLOCK_PARAS_SHIFT,
+            (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+              test.para,
             test.paras,
             0
           );
@@ -351,10 +394,12 @@ int main(int argc, char **argv) {
       break;
     case PROCESS_TEST_TYPE_REALLOC:
       printf(
-        "realloc %d %d %d %d %d %s\n",
+        "realloc %d %d %d %d %d %d %d %s\n",
         test.process,
+        test.old_para,
         test.old_paras,
         test.old_blocks,
+        test.para,
         test.paras,
         test.blocks,
         test.success ? "true" : "false"
@@ -363,6 +408,14 @@ int main(int argc, char **argv) {
         printf("... not allocated, ignore\n");
       else {
  printf("old core [%d,%d) swap reservation [%d,%d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+        old_para = processes[test.process].para;
+        if (old_para != test.old_para) {
+          printf(
+            "... old para %d, should be %d\n",
+            old_para,
+            test.old_para
+          );
+        }
         old_paras = processes[test.process].paras;
         if (old_paras != test.old_paras) {
           printf(
@@ -370,7 +423,6 @@ int main(int argc, char **argv) {
             old_paras,
             test.old_paras
           );
-          rassert(old_paras <= test.old_paras);
         }
         old_blocks =
           processes[test.process].swap_item.limit - 
@@ -381,16 +433,20 @@ int main(int argc, char **argv) {
             old_blocks,
             test.old_blocks
           );
-          rassert(old_blocks <= test.old_blocks);
         }
         core_hash_verify(
           test.process,
           (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+            old_para +
             test.paras,
           old_paras - test.paras,
           test.paras
         );
-        result = process_realloc(processes + test.process, test.paras);
+        result = process_realloc(
+          processes + test.process,
+          test.paras,
+          false
+        );
         printf(
           "... %s\n",
           result == test.success ?
@@ -401,22 +457,190 @@ int main(int argc, char **argv) {
           if (!test.success) {
             printf("... undo\n");
             rassert(
-              process_realloc(processes + test.process, old_paras)
+              process_realloc(
+                processes + test.process,
+                old_paras,
+                false
+              )
+            );
+            rassert(processes[test.process].para == old_para);
+            rassert(processes[test.process].paras == old_paras);
+            rassert(
+              processes[test.process].swap_item.limit -
+                processes[test.process].swap_item.base ==
+              old_blocks
             );
           }
           else {
  printf("new core [%d,%d) swap reservation [%d, %d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+            new_para = processes[test.process].para;
+            if (new_para != test.para) {
+              printf(
+                "... new para %d, should be %d\n",
+                new_para,
+                test.para
+              );
+            }
+            new_paras = processes[test.process].paras;
+            if (new_paras != test.paras) {
+              printf(
+                "... new paras %d, should be %d\n",
+                new_paras,
+                test.paras
+              );
+            }
+            new_blocks =
+              processes[test.process].swap_item.limit - 
+              processes[test.process].swap_item.base;
+            if (new_blocks != test.blocks) {
+              printf(
+                "... new blocks %d, should be %d\n",
+                new_blocks,
+                test.blocks
+              );
+            }
+            core_hash_init(
+              test.process,
+              (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+                new_para +
+                old_paras,
+              new_paras - old_paras,
+              old_paras
+            );
+          }
+        }
+      }
+      break;
+    case PROCESS_TEST_TYPE_REALLOC_BASE:
+      printf(
+        "realloc_base %d %d %d %d %d %d %d %s\n",
+        test.process,
+        test.old_para,
+        test.old_paras,
+        test.old_blocks,
+        test.para,
+        test.paras,
+        test.blocks,
+        test.success ? "true" : "false"
+      );
+      if (processes[test.process].paras == -1)
+        printf("... not allocated, ignore\n");
+      else {
+ printf("old core [%d,%d) swap reservation [%d,%d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+        old_para = processes[test.process].para;
+        if (old_para != test.old_para) {
+          printf(
+            "... old para %d, should be %d\n",
+            old_para,
+            test.old_para
+          );
+        }
+        old_paras = processes[test.process].paras;
+        if (old_paras != test.old_paras) {
+          printf(
+            "... old paras %d, should be %d\n",
+            old_paras,
+            test.old_paras
+          );
+        }
+        old_blocks =
+          processes[test.process].swap_item.limit - 
+          processes[test.process].swap_item.base;
+        if (old_blocks != test.old_blocks) {
+          printf(
+            "... old blocks %d, should be %d\n",
+            old_blocks,
+            test.old_blocks
+          );
+        }
+        core_hash_verify(
+          test.process,
+          (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+            old_para,
+          old_paras - test.paras,
+          0
+        );
+        result = process_realloc(
+          processes + test.process,
+          test.paras,
+          true
+        );
+        printf(
+          "... %s\n",
+          result == test.success ?
+            "ok" :
+            result ? "succeeded, should fail" : "failed, should succeed"
+        );
+        if (result) {
+          if (!test.success) {
+            printf("... undo\n");
+            rassert(
+              process_realloc(
+                processes + test.process,
+                old_paras,
+                true
+              )
+            );
+            rassert(processes[test.process].para == old_para);
+            rassert(processes[test.process].paras == old_paras);
             rassert(
               processes[test.process].swap_item.limit -
                 processes[test.process].swap_item.base ==
-              test.blocks
+              old_blocks
             );
+          }
+          else {
+ printf("new core [%d,%d) swap reservation [%d,%d)\n", processes[test.process].core_item.base, processes[test.process].core_item.limit, processes[test.process].swap_item.base, processes[test.process].swap_item.limit);
+            new_para = processes[test.process].para;
+            if (new_para != test.para) {
+              printf(
+                "... new para %d, should be %d\n",
+                new_para,
+                test.para
+              );
+            }
+            new_paras = processes[test.process].paras;
+            if (new_paras != test.paras) {
+              printf(
+                "... new paras %d, should be %d\n",
+                new_paras,
+                test.paras
+              );
+            }
+            new_blocks =
+              processes[test.process].swap_item.limit - 
+              processes[test.process].swap_item.base;
+            if (new_blocks != test.blocks) {
+              printf(
+                "... new blocks %d, should be %d\n",
+                new_blocks,
+                test.blocks
+              );
+            }
+            if (new_paras >= old_paras)
+              core_hash_verify(
+                test.process,
+                (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+                  new_para +
+                  new_paras -
+                  old_paras,
+                old_paras,
+                0
+              );
+            else
+              core_hash_verify(
+                test.process,
+                (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
+                  new_para,
+                new_paras,
+                old_paras - new_paras
+              );
             core_hash_init(
               test.process,
               (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
-                old_paras,
-              test.paras - old_paras,
-              old_paras
+                new_para,
+              new_paras,
+              0
             );
           }
         }
@@ -433,14 +657,23 @@ int main(int argc, char **argv) {
       break;
     case PROCESS_TEST_TYPE_FREE:
       printf(
-        "free %d %d %d\n",
+        "free %d %d %d %d\n",
         test.process,
+        test.old_para,
         test.old_paras,
         test.old_blocks
       );
       if (processes[test.process].paras == -1)
         printf("... not allocated, ignore\n");
       else {
+        old_para = processes[test.process].para;
+        if (old_para != test.old_para) {
+          printf(
+            "... old para %d, should be %d\n",
+            old_para,
+            test.old_para
+          );
+        }
         old_paras = processes[test.process].paras;
         if (old_paras != test.old_paras) {
           printf(
@@ -448,7 +681,6 @@ int main(int argc, char **argv) {
             old_paras,
             test.old_paras
           );
-          rassert(old_paras <= test.old_paras);
         }
         old_blocks =
           processes[test.process].swap_item.limit - 
@@ -459,52 +691,20 @@ int main(int argc, char **argv) {
             old_blocks,
             test.old_blocks
           );
-          rassert(old_blocks <= test.old_blocks);
-        }
-        if (processes[test.process].lru_item.prev != NULL) { // fully in core
-          assert(processes + test.process != victim);
-          core_base = processes[test.process].core_item.base;
-          core_blocks = processes[test.process].core_item.limit - core_base;
-          core_paras = processes[test.process].paras;
-          swap_base = -1;
-          swap_blocks = 0;
-          swap_paras = 0;
-        }
-        else {
-          if (processes + test.process == victim) { // victim
-            core_base = victim->core_item.base;
-#ifndef INDIRECT_CORE
-            core_blocks = victim->core_item.limit - core_base;
-#else /* INDIRECT_CORE */
-            core_blocks = victim->core_item.limit - core_base - victim_swap_blocks;
-#endif /* INDIRECT_CORE */
-            core_paras = core_blocks << BLOCK_PARAS_SHIFT;
-            swap_base = victim->swap_item.limit - victim_swap_blocks;
-            swap_blocks = victim_swap_blocks;
-            swap_paras = victim->paras - core_paras;
-          }
-          else { // fully in swap
-            core_base = -1;
-            core_blocks = 0;
-            core_paras = 0;
-            swap_base = processes[test.process].swap_item.base;
-            swap_blocks = processes[test.process].swap_item.limit - swap_base;
-            swap_paras = processes[test.process].paras;
-          }
         }
printf("old core [%d,%d) swap occupation [%d,%d)\n", core_base, core_base + core_blocks, swap_base, swap_base + swap_blocks);
fflush(stdout);
       process_get_state(processes + test.process, &state);
printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_base, state.core_base + state.core_blocks, state.swap_base, state.swap_base + state.swap_blocks);
         core_hash_verify(
           test.process,
-          core_base << BLOCK_PARAS_SHIFT,
-          core_paras,
+          (state.core_base << BLOCK_PARAS_SHIFT) + state.core_para,
+          state.core_paras,
           0 
         );
         swap_hash_verify(
           test.process,
-          swap_base << BLOCK_PARAS_SHIFT,
-          swap_paras,
-          core_paras
+          (state.swap_base << BLOCK_PARAS_SHIFT) + state.swap_para,
+          state.swap_paras,
+          state.core_paras
         );
         process_free(processes + test.process);
         processes[test.process].paras = -1;
@@ -522,73 +722,39 @@ done:
     if (processes[i].paras == -1)
       printf("process %d: not allocated\n", i);
     else {
-      if (processes[i].lru_item.prev != NULL) { // fully in core
-        assert(processes + i != victim);
-        core_base = processes[i].core_item.base;
-        core_blocks = processes[i].core_item.limit - core_base;
-        core_paras = processes[i].paras;
-        swap_base = -1;
-        swap_blocks = 0;
-        swap_paras = 0;
-      }
-      else {
-        if (processes + i == victim) { // victim
-          core_base = victim->core_item.base;
-#ifndef INDIRECT_CORE
-          core_blocks = victim->core_item.limit - core_base;
-#else /* INDIRECT_CORE */
-          core_blocks = victim->core_item.limit - core_base - victim_swap_blocks;
-#endif /* INDIRECT_CORE */
-          core_paras = core_blocks << BLOCK_PARAS_SHIFT;
-          swap_base = victim->swap_item.limit - victim_swap_blocks;
-          swap_blocks = victim_swap_blocks;
-          swap_paras = victim->paras - core_paras;
-        }
-        else { // fully in swap
-          core_base = -1;
-          core_blocks = 0;
-          core_paras = 0;
-          swap_base = processes[i].swap_item.base;
-          swap_blocks = processes[i].swap_item.limit - swap_base;
-          swap_paras = processes[i].paras;
-        }
-      }
-      rassert(
-        core_blocks + swap_blocks ==
-          (processes[i].paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT
-      );
+      process_get_state(processes + i, &state);
       printf(
         "process %d: core [%d,%d) swap occupation [%d,%d)\n",
         i,
-        core_base,
-        core_base + core_blocks,
-        swap_base,
-        swap_base + swap_blocks
+        state.core_base,
+        state.core_base + state.core_blocks,
+        state.swap_base,
+        state.swap_base + state.swap_blocks
       );
       core_hash_verify(
         i,
-        core_base << BLOCK_PARAS_SHIFT,
-        core_paras,
+        (state.core_base << BLOCK_PARAS_SHIFT) + state.core_para,
+        state.core_paras,
         0
       );
 #ifdef INDIRECT_CORE
       block_pool_free(
         &core_block_pool,
-        core_table_mem + core_base,
-        core_blocks
+        core_table_mem + state.core_base,
+        state.core_blocks
       );
 #endif /* INDIRECT_CORE */
       swap_hash_verify(
         i,
-        swap_base << BLOCK_PARAS_SHIFT,
-        swap_paras,
-        core_paras
+        (state.swap_base << BLOCK_PARAS_SHIFT) + state.swap_para,
+        state.swap_paras,
+        state.core_paras
       );
 #ifdef INDIRECT_SWAP
       block_pool_free(
         &swap_block_pool,
-        swap_table_mem + swap_base,
-        swap_blocks
+        swap_table_mem + state.swap_base,
+        state.swap_blocks
       );
 #endif /* INDIRECT_SWAP */
     }