Replace process->para, process->paras with process->para_base, process->para_limit...
authorNick Downing <nick@ndcode.org>
Tue, 4 Jun 2019 14:17:09 +0000 (00:17 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 4 Jun 2019 14:17:09 +0000 (00:17 +1000)
core.c
indirect_core_contiguous_swap/o.sh
indirect_core_indirect_swap/o.sh
moveable_core_contiguous_swap/o.sh
moveable_core_indirect_swap/o.sh
o.sh
process.c
process.h
process_test.h
process_test_gen.c
process_test_run.c

diff --git a/core.c b/core.c
index 4a937af..0891b0a 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;
-  struct process_state state;
+  struct process_calc calc;
+  int in_core_para, para_base;
 #else /* INDIRECT_CORE */
   int i;
 #endif /* INDIRECT_CORE */
@@ -39,13 +40,19 @@ static void core_move(struct pool_item *item, int new_base) {
   process = (struct process *)(
     (char *)item - offsetof(struct process, core_item)
   );
-  process_get_state(process, &state);
+  process_calc(process, &calc);
+  in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+  if (in_core_para < process->para_base)
+    in_core_para = process->para_base;
+  else if (in_core_para > process->para_limit)
+    in_core_para = process->para_limit;
 
   // copy valid part by abstract routine
+  para_base = (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base;
   core_copy(
-    state.core_para,
-    state.core_para + ((new_base - base) << BLOCK_PARAS_SHIFT),
-    state.core_paras
+    para_base,
+    para_base + ((new_base - base) << BLOCK_PARAS_SHIFT),
+    in_core_para - process->para_base
   );
 #endif
 #else /* INDIRECT_CORE */
@@ -60,8 +67,8 @@ static void core_move_up(struct pool_item *item, int new_limit) {
   int limit, blocks;
 #ifndef INDIRECT_CORE
   struct process *process;
-  struct process_state state;
-  int para;
+  struct process_calc calc;
+  int in_core_para, para_limit;
 #else /* INDIRECT_CORE */
   int i;
 #endif /* INDIRECT_CORE */
@@ -83,14 +90,19 @@ static void core_move_up(struct pool_item *item, int new_limit) {
   process = (struct process *)(
     (char *)item - offsetof(struct process, core_item)
   );
-  process_get_state(process, &state);
+  process_calc(process, &calc);
+  in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+  if (in_core_para < process->para_base)
+    in_core_para = process->para_base;
+  else if (in_core_para > process->para_limit)
+    in_core_para = process->para_limit;
 
   // copy valid part by abstract routine
-  para = state.core_para + state.core_paras;
+  para_limit = (calc.core_origin << BLOCK_PARAS_SHIFT) + in_core_para;
   core_copy_up(
-    para,
-    para + ((new_limit - limit) << BLOCK_PARAS_SHIFT),
-    state.core_paras
+    para_limit,
+    para_limit + ((new_limit - limit) << BLOCK_PARAS_SHIFT),
+    in_core_para - process->para_base
   );
 #endif
 #else /* INDIRECT_CORE */
index 35dc09e..33e7a59 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
 
 echo "run test script"
 ./process_test_run 16 64 192 8 384 384 <process_test.txt
index 35dc09e..33e7a59 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
 
 echo "run test script"
 ./process_test_run 16 64 192 8 384 384 <process_test.txt
index 88e3b80..7e54213 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
 
 echo "run test script"
 ./process_test_run 16 64 192 8 384 <process_test.txt
index 88e3b80..7e54213 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
 
 echo "run test script"
 ./process_test_run 16 64 192 8 384 <process_test.txt
diff --git a/o.sh b/o.sh
index 5cec47d..b2cd32c 100755 (executable)
--- a/o.sh
+++ b/o.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 echo "generate test script"
-./process_test_gen 16 248 4096 32 true true >process_test.txt
+./process_test_gen 16 248 4096 -16 16 true >process_test.txt
 
 echo "run test script"
 ./process_test_run 16 64 192 8 384 384 <process_test.txt
index b9b639d..267c062 100644 (file)
--- a/process.c
+++ b/process.c
@@ -119,7 +119,7 @@ static bool do_swap_out(int swap_out) {
 #ifndef INDIRECT_CORE
     block = process->core_item.limit - process->core_item.base;
 #else /* INDIRECT_CORE */
-    block = process->core_blocks;
+    block = process->in_core_blocks;
 #endif /* INDIRECT_CORE */
 #ifndef INDIRECT_SWAP
     blocks = swap_out < block ? swap_out : block;
@@ -137,7 +137,7 @@ static bool do_swap_out(int swap_out) {
     // adjust swap pointer
     block -= blocks;
 #ifdef INDIRECT_CORE
-    process->core_blocks = block;
+    process->in_core_blocks = block;
 #endif
 
     // transfer data to swap
@@ -190,22 +190,23 @@ static bool do_swap_out(int swap_out) {
   return true;
 }
 
-bool process_alloc(struct process *process, int para, int paras) {
+static int calc_blocks(int para_base, int para_limit) {
+  return
+    ((para_limit + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT) -
+      (para_base >> BLOCK_PARAS_SHIFT);
+}
+
+bool process_alloc(struct process *process, int para_base, int para_limit) {
   int blocks;
 
   // must not be already allocated
   assert((process->flags & PROCESS_FLAGS_ACTIVE) == 0);
 
   // check blocks
-  blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+  blocks = calc_blocks(para_base, para_limit);
   if (
     process_avail < blocks ||
-    !pool_alloc(
-      &swap_table,
-      &process->swap_item,
-      blocks,
-      0
-    )
+    !pool_alloc(&swap_table, &process->swap_item, blocks, 0)
   )
     return false;
 
@@ -224,14 +225,7 @@ bool process_alloc(struct process *process, int para, int paras) {
   );
 #else /* INDIRECT_CORE */
   // allocate core and possible swap
-  if (
-    !pool_alloc(
-      &core_table,
-      &process->core_item,
-      blocks,
-      0
-    )
-  ) {
+  if (!pool_alloc(&core_table, &process->core_item, blocks, 0)) {
     pool_free(&swap_table, &process->swap_item);
     return false;
   }
@@ -261,17 +255,17 @@ bool process_alloc(struct process *process, int para, int paras) {
 #else /* INDIRECT_CORE */
   process->flags = PROCESS_FLAGS_ACTIVE;
 #endif /* INDIRECT_CORE */
-  process->para = para;
-  process->paras = paras;
+  process->para_base = para_base;
+  process->para_limit = para_limit;
 #ifdef INDIRECT_CORE
-  process->core_blocks = blocks;
+  process->in_core_blocks = blocks;
 #endif
   process_avail -= blocks;
   return true;
 }
 
-bool process_realloc(struct process *process, int paras, bool dir) {
-  int old_blocks, para, blocks, blocks_change;
+bool process_realloc(struct process *process, int para_base_limit, bool dir) {
+  int old_blocks, blocks, blocks_change;
 
   // must be already allocated
   assert(process->flags & PROCESS_FLAGS_ACTIVE);
@@ -285,17 +279,17 @@ bool process_realloc(struct process *process, int paras, bool dir) {
   );
 #else
   assert(
-    process->core_blocks ==
+    process->in_core_blocks ==
       process->swap_item.limit - process->swap_item.base
   );
 #endif /* ! INDIRECT_CORE */
 
   // check blocks
-  old_blocks = process->swap_item.limit - process->swap_item.base;
-  para = process->para;
-  if (dir)
-    para = (old_blocks << BLOCK_PARAS_SHIFT) - para - process->paras;
-  blocks = (para + paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+  old_blocks = calc_blocks(process->para_base, process->para_limit);
+  blocks =
+    dir ?
+      calc_blocks(para_base_limit, process->para_limit) :
+      calc_blocks(process->para_base, para_base_limit);
   blocks_change = blocks - old_blocks;
   if (process_avail < blocks_change)
     return false;
@@ -303,22 +297,8 @@ bool process_realloc(struct process *process, int paras, bool dir) {
   // this is a bit clunky, we want realloc without copying old contents,
   // so we free, try to allocate larger, if that fails, allocate original
   pool_free(&swap_table, &process->swap_item);
-  if (
-    !pool_alloc(
-      &swap_table,
-      &process->swap_item,
-      blocks,
-      0
-    )
-  ) {
-    rassert(
-      pool_alloc(
-        &swap_table,
-        &process->swap_item,
-        old_blocks,
-        0
-      )
-    );
+  if (!pool_alloc(&swap_table, &process->swap_item, blocks, 0)) {
+    rassert(pool_alloc(&swap_table, &process->swap_item, old_blocks, 0));
     return false;
   }
 
@@ -326,7 +306,7 @@ bool process_realloc(struct process *process, int paras, bool dir) {
   // free up as much core as we need to
   rassert(do_swap_out(blocks_change - core_table.avail));
 
-  // reallocate core and possible swap
+  // reallocate core
   rassert(
     pool_alloc(
       &core_table,
@@ -347,7 +327,7 @@ bool process_realloc(struct process *process, int paras, bool dir) {
     -blocks_change
   );
 
-  // reallocate core and possible swap
+  // reallocate core
   if (
     !pool_alloc(
       &core_table,
@@ -387,11 +367,9 @@ bool process_realloc(struct process *process, int paras, bool dir) {
 #endif /* INDIRECT_CORE */
 
   // track total allocation
-  if (dir)
-    process->para = (blocks << BLOCK_PARAS_SHIFT) - para - paras;
-  process->paras = paras;
+  *(dir ? &process->para_base : &process->para_limit) = para_base_limit;
 #ifdef INDIRECT_CORE
-  process->core_blocks = blocks;
+  process->in_core_blocks = blocks;
 #endif
   process_avail -= blocks_change;
   return true;
@@ -416,7 +394,7 @@ void process_run(struct process *process) {
       process->core_item.limit - process->core_item.base :
       0;
 #else /* INDIRECT_CORE */
-  block = process->core_blocks;
+  block = process->in_core_blocks;
 #endif /* INDIRECT_CORE */
   for (
     swap_in =
@@ -473,7 +451,7 @@ void process_run(struct process *process) {
     // adjust swap pointer
     block += blocks;
 #ifdef INDIRECT_CORE
-    process->core_blocks = block;
+    process->in_core_blocks = block;
 #endif /* INDIRECT_CORE */
   }
 
@@ -506,7 +484,7 @@ void process_free(struct process *process) {
       process->core_item.limit - process->core_item.base :
       0;
 #else /* INDIRECT_CORE */
-  block = process->core_blocks;
+  block = process->in_core_blocks;
 #endif /* INDIRECT_CORE */
   swap_in =
     process->swap_item.limit - process->swap_item.base - block;
@@ -523,7 +501,7 @@ void process_free(struct process *process) {
 #ifdef INDIRECT_SWAP
     block
 #else /* ! INDIRECT_SWAP */
-    process->core_blocks
+    process->in_core_blocks
 #endif /* ! INDIRECT_SWAP */
   );
   pool_free(&core_table, &process->core_item);
@@ -540,56 +518,46 @@ void process_free(struct process *process) {
   pool_free(&swap_table, &process->swap_item);
 
   // track total allocation
-  process_avail += (process->paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+  process_avail += calc_blocks(process->para_base, process->para_limit);
   process->flags = 0;
 }
 
-// ugh. improve this later
-void process_get_state(struct process *process, struct process_state *state) {
-  int para;
+void process_calc(struct process *process, struct process_calc *calc) {
+  calc->block_base =
+    process->para_base >> BLOCK_PARAS_SHIFT;
+  calc->block_limit =
+    (process->para_limit + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
+#ifdef INDIRECT_CORE
+  assert(
+    process->core_item.limit - process->core_item.base ==
+      calc->block_limit - calc->block_base
+  );
+#endif /* INDIRECT_CORE */
+  // note: following can fail during realloc because swap reallocated first:
+  //assert(
+  //  process->swap_item.limit - process->swap_item.base ==
+  //    calc->block_limit - calc->block_base
+  //);
 
 #ifndef INDIRECT_CORE
-  if (process->flags & PROCESS_FLAGS_CORE_ITEM) {
-    state->core_block = process->core_item.base;
-    state->core_blocks = process->core_item.limit - process->core_item.base;
-  }
-  else {
-    state->core_block = -1;
-    state->core_blocks = 0;
-  }
+  calc->core_origin = (
+    process->flags & PROCESS_FLAGS_CORE_ITEM ? process->core_item.base : 0
+  ) - calc->block_base;
 #else /* INDIRECT_CORE */
-  state->core_block = process->core_item.base;
-  state->core_blocks = process->core_blocks;
-#endif /* INDIRECT_CORE */
-  state->core_para =
-    (state->core_block << BLOCK_PARAS_SHIFT) + process->para;
-  state->core_paras =
-    (state->core_blocks << BLOCK_PARAS_SHIFT) - process->para;
-  if (state->core_paras < 0)
-    state->core_paras = 0;
-  if (state->core_paras > process->paras)
-    state->core_paras = process->paras;
-
-  state->swap_block =
-    process->swap_item.base + state->core_blocks;
-  state->swap_blocks =
-    process->swap_item.limit - process->swap_item.base - state->core_blocks;
-  para = 
-    (
-      (process->swap_item.limit - process->swap_item.base) <<
-      BLOCK_PARAS_SHIFT
-    ) - process->para - process->paras;
- //printf("a %d+%d+%d=%d*%d\n", process->para, process->paras, para, process->swap_item.limit - process->swap_item.base, BLOCK_PARAS);
-  state->swap_paras =
-    (state->swap_blocks << BLOCK_PARAS_SHIFT) - para;
-  if (state->swap_paras < 0)
-    state->swap_paras = 0;
-  if (state->swap_paras > process->paras)
-    state->swap_paras = process->paras;
-  state->swap_para =
-    (state->swap_block << BLOCK_PARAS_SHIFT) +
-    (state->swap_blocks << BLOCK_PARAS_SHIFT) -
-    para -
-    state->swap_paras;
- //printf("b %d+%d+%d=%d*%d\n", state->swap_para, state->swap_paras, para, process->swap_blocks, BLOCK_PARAS);
+  calc->core_origin = process->core_item.base - calc->block_base;
+  assert(calc->core_origin == process->core_item.limit - calc->block_limit);
+#endif
+  // note: following can fail during realloc because swap reallocated first:
+  calc->swap_origin = process->swap_item.base - calc->block_base;
+  //assert(calc->swap_origin == process->swap_item.limit - calc->block_limit);
+
+#ifndef INDIRECT_CORE
+  calc->in_core_block = (
+    process->flags & PROCESS_FLAGS_CORE_ITEM ? process->core_item.limit : 0
+  ) - calc->core_origin;
+ //printf("para [%d,%d) in_core_blocks %d block [%d,%d) core_origin %d swap_origin %d in_core_block %d\n", process->para_base, process->para_limit, process->flags & PROCESS_FLAGS_CORE_ITEM ? process->core_item.limit - process->core_item.base : 0, calc->block_base, calc->block_limit, calc->core_origin, calc->swap_origin, calc->in_core_block);
+#else
+  calc->in_core_block = calc->block_base + process->in_core_blocks;
+ //printf("para [%d,%d) in_core_blocks %d block [%d,%d) core_origin %d swap_origin %d in_core_block %d\n", process->para_base, process->para_limit, process->in_core_blocks, calc->block_base, calc->block_limit, calc->core_origin, calc->swap_origin, calc->in_core_block);
+#endif
 }
index f93f3d4..1d14601 100644 (file)
--- a/process.h
+++ b/process.h
@@ -32,23 +32,20 @@ struct process {
   struct lru_item lru_item;
   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
+  int para_base;
+  int para_limit;
 #ifdef INDIRECT_CORE
-  int core_blocks;
+  int in_core_blocks;
 #endif
 };
 
-// improve this later
-struct process_state {
-  int core_block;
-  int core_blocks;
-  int core_para;
-  int core_paras;
-  int swap_block;
-  int swap_blocks;
-  int swap_para;
-  int swap_paras;
+// derived variables, not stored in process to save space
+struct process_calc {
+  int block_base;
+  int block_limit;
+  int core_origin;
+  int swap_origin;
+  int in_core_block;
 };
 
 extern struct process *processes;
@@ -63,7 +60,7 @@ 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);
+void process_calc(struct process *process, struct process_calc *calc);
  
 // abstract
 void swap_read_write(int core_block, int swap_block, int blocks, bool dir);
index ab2e770..3af601a 100644 (file)
 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
+  int old_para_base;
+  int old_para_limit;
+  int para_base;
+  int para_limit;
   bool success;
 };
 
index 7867b9d..0c86302 100644 (file)
@@ -11,7 +11,6 @@
 
 #define PARA_SHIFT 8
 #define BLOCK_SHIFT 9
-//#define PAGE_SHIFT 12
 
 #define BLOCK_PARAS_SHIFT (BLOCK_SHIFT - PARA_SHIFT)
 #define BLOCK_PARAS (1 << BLOCK_PARAS_SHIFT)
@@ -21,29 +20,36 @@ int rand_int(int n) {
   return (int)((long)rand() * n / (RAND_MAX + 1L));
 }
 
+int calc_blocks(int para_base, int para_limit) {
+  return
+    ((para_limit + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT) -
+      (para_base >> BLOCK_PARAS_SHIFT);
+}
+
 struct process {
-  int para;
-  int paras;
+  bool active;
+  int para_base;
+  int para_limit;
 };
 
 int main(int argc, char **argv) {
   if (argc < 5) {
-    printf("usage: %s n_processes pool_blocks n_events process_blocks [do_para [do_base [seed]]]\n", argv[0]);
+    printf("usage: %s n_processes pool_blocks n_events para_base para_limit [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]);
-  bool do_para = argc >= 6 ? strcmp(argv[5], "false") != 0 : false;
+  int para_base = atoi(argv[4]);
+  int para_limit = atoi(argv[5]);
   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;
+  rassert(para_limit >= para_base);
 
   struct process *processes = malloc(n_processes * sizeof(struct process));
   rassert(processes);
-  memset(processes, -1, n_processes * sizeof(struct process));
+  memset(processes, 0, n_processes * sizeof(struct process));
 
   srand(seed);
   int pool_used = 0;
@@ -54,42 +60,45 @@ int main(int argc, char **argv) {
 #endif
 
     test.process = rand_int(n_processes);
-    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.para + test.paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT;
-      test.success = pool_used + test.blocks <= pool_blocks;
+    struct process *process = processes + test.process;
+
+    test.old_para_base = process->para_base;
+    test.old_para_limit = process->para_limit;
+    if (!process->active) {
+      test.para_base =
+        (do_base ? rand_int(para_limit - para_base + 1) : 0) + para_base;
+      test.para_limit =
+        rand_int(para_limit - para_base + 1) + para_base;
+      if (test.para_base > test.para_limit) {
+        int i = test.para_base;
+        test.para_base = test.para_limit;
+        test.para_limit = i;
+      }
+      int blocks = calc_blocks(test.para_base, test.para_limit);
+      test.success = pool_used + blocks <= pool_blocks;
 
 #ifdef __FUZIX__
       test.type = PROCESS_TEST_TYPE_ALLOC;
       write(1, &test, sizeof(test));
 #else
       printf(
-        "alloc %d %d %d %d %s\n",
+        "alloc %d %d %d %s\n",
         test.process,
-        test.para,
-        test.paras,
-        test.blocks,
+        test.para_base,
+        test.para_limit,
         test.success ? "true" : "false"
       );
 #endif
 
       if (test.success) {
-        processes[test.process].para = test.para;
-        processes[test.process].paras = test.paras;
-        pool_used += test.blocks;
+        process->active = true;
+        process->para_base = test.para_base;
+        process->para_limit = test.para_limit;
+        pool_used += blocks;
       }
     }
     else {
-      test.old_blocks = (
-        test.old_para +
-        test.old_paras +
-        (BLOCK_PARAS - 1)
-      ) >> BLOCK_PARAS_SHIFT;
+      int old_blocks = calc_blocks(process->para_base, process->para_limit);
       if (rand_int(64)) {
 #ifdef __FUZIX__
         test.type = PROCESS_TEST_TYPE_RUN;
@@ -99,56 +108,55 @@ 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.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;
+          if (do_base && rand_int(3) == 0) {
+            test.para_base =
+              rand_int(process->para_limit - para_base + 1) +
+                para_base;
+            int blocks = calc_blocks(test.para_base, process->para_limit);
+            test.success = pool_used + blocks - old_blocks <= pool_blocks;
+
+#ifdef __FUZIX__
+            test.type = PROCESS_TEST_TYPE_REALLOC_BASE;
+            write(1, &test, sizeof(test));
+#else
+            printf(
+              "realloc_base %d %d %d %s\n",
+              test.process,
+              test.old_para_base,
+              test.para_base,
+              test.success ? "true" : "false"
+            );
+#endif
+
+            if (test.success) {
+              process->para_base = test.para_base;
+              pool_used += blocks - old_blocks;
+            }
+          }
+          else {
+            test.para_limit =
+              rand_int(para_limit - process->para_base + 1) +
+                process->para_base;
+            int blocks = calc_blocks(process->para_base, test.para_limit);
+            test.success = pool_used + blocks - old_blocks <= pool_blocks;
 
 #ifdef __FUZIX__
-          test.type =
-            base ?
-              PROCESS_TEST_TYPE_REALLOC_BASE :
-              PROCESS_TEST_TYPE_REALLOC;
-          write(1, &test, sizeof(test));
+            test.type = PROCESS_TEST_TYPE_REALLOC;
+            write(1, &test, sizeof(test));
 #else
-          printf(
-            "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"
-          );
+            printf(
+              "realloc %d %d %d %s\n",
+              test.process,
+              test.old_para_limit,
+              test.para_limit,
+              test.success ? "true" : "false"
+            );
 #endif
 
-          if (test.success) {
-            processes[test.process].para = test.para;
-            processes[test.process].paras = test.paras;
-            pool_used += test.blocks - test.old_blocks;
+            if (test.success) {
+              process->para_limit = test.para_limit;
+              pool_used += blocks - old_blocks;
+            }
           }
         }
       }
@@ -158,16 +166,14 @@ int main(int argc, char **argv) {
         write(1, &test, sizeof(test));
 #else
         printf(
-          "free %d %d %d %d\n",
+          "free %d %d %d\n",
           test.process,
-          test.old_para,
-          test.old_paras,
-          test.old_blocks
+          test.old_para_base,
+          test.old_para_limit
         );
 #endif
-        //processes[test.process].para = -1;
-        processes[test.process].paras = -1;
-        pool_used -= test.old_blocks;
+        process->active = false;
+        pool_used -= old_blocks;
       }
     }
   }
index 72881c4..660fc04 100644 (file)
@@ -144,10 +144,11 @@ int main(int argc, char **argv) {
 #ifndef __FUZIX__
   char buf[256];
 #endif
+  struct process *process;
   bool result;
-  int old_para, old_paras, old_blocks;
-  int new_para, new_paras, new_blocks;
-  struct process_state state;
+  int old_para_base, old_para_limit;
+  struct process_calc calc;
+  int in_core_para;
 
   if (argc < 5) {
     printf(
@@ -204,8 +205,6 @@ int main(int argc, char **argv) {
   memset(swap_block_mem, 0xaa, n_swap_blocks * (BLOCK_PARAS * sizeof(int)));
 
   process_init(n_processes, spare);
-  for (i = 0; i < n_processes; ++i)
-    processes[i].paras = -1;
 
   while (true) {
  //printf("avail %d %d(%d) %d(%d)\n", process_avail, CORE_AVAIL, core_table.avail, SWAP_AVAIL, swap_table.avail);
@@ -225,18 +224,15 @@ int main(int argc, char **argv) {
       test.type = PROCESS_TEST_TYPE_ALLOC;
       rassert(
         scanf(
-          "%d %d %d %d %s",
+          "%d %d %d %s",
           &test.process,
-          &test.para,
-          &test.paras,
-          &test.blocks,
+          &test.para_base,
+          &test.para_limit,
           buf
-        ) == 5
+        ) == 4
       );
       rassert(test.process >= 0 && test.process < n_processes);
-      rassert(test.para >= 0);
-      rassert(test.paras >= 0);
-      rassert(test.blocks >= 0);
+      rassert(test.para_limit >= test.para_base);
       if (strcmp(buf, "false") == 0)
         test.success = false;
       else if (strcmp(buf, "true") == 0)
@@ -248,24 +244,14 @@ int main(int argc, char **argv) {
       test.type = PROCESS_TEST_TYPE_REALLOC;
       rassert(
         scanf(
-          "%d %d %d %d %d %d %d %s",
+          "%d %d %d %s",
           &test.process,
-          &test.old_para,
-          &test.old_paras,
-          &test.old_blocks,
-          &test.para,
-          &test.paras,
-          &test.blocks,
+          &test.old_para_limit,
+          &test.para_limit,
           buf
-        ) == 8
+        ) == 4
       );
       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)
@@ -277,24 +263,14 @@ int main(int argc, char **argv) {
       test.type = PROCESS_TEST_TYPE_REALLOC_BASE;
       rassert(
         scanf(
-          "%d %d %d %d %d %d %d %s",
+          "%d %d %d %s",
           &test.process,
-          &test.old_para,
-          &test.old_paras,
-          &test.old_blocks,
-          &test.para,
-          &test.paras,
-          &test.blocks,
+          &test.old_para_base,
+          &test.para_base,
           buf
-        ) == 8
+        ) == 4
       );
       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)
@@ -311,37 +287,30 @@ 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
-        ) == 4
+          &test.old_para_base,
+          &test.old_para_limit
+        ) == 3
       );
       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.old_para_limit >= test.old_para_base);
     }
     else
       rassert(false);
 #endif
+    process = processes + test.process;
     switch (test.type) {
     case PROCESS_TEST_TYPE_ALLOC:
       printf(
-        "alloc %d %d %d %d %s\n",
+        "alloc %d %d %d %s\n",
         test.process,
-        test.para,
-        test.paras,
-        test.blocks,
+        test.para_base,
+        test.para_limit,
         test.success ? "true" : "false"
       );
-      rassert(processes[test.process].paras == -1);
-      result = process_alloc(
-        processes + test.process,
-        test.para,
-        test.paras
-      );
+      rassert((process->flags & PROCESS_FLAGS_ACTIVE) == 0);
+      result = process_alloc(process, test.para_base, test.para_limit);
       printf(
         "... %s\n",
         result == test.success ?
@@ -351,23 +320,15 @@ int main(int argc, char **argv) {
       if (result) {
         if (!test.success) {
           printf("... undo\n");
-          process_free(processes + test.process);
-          processes[test.process].paras = -1;
+          process_free(process);
         }
         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 ==
-            test.blocks
-          );
+          process_calc(process, &calc);
+ printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
           core_hash_init(
             test.process,
-            (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
-              test.para,
-            test.paras,
+            (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
+            test.para_limit - test.para_base,
             0
           );
         }
@@ -375,59 +336,33 @@ int main(int argc, char **argv) {
       break;
     case PROCESS_TEST_TYPE_REALLOC:
       printf(
-        "realloc %d %d %d %d %d %d %d %s\n",
+        "realloc %d %d %d %s\n",
         test.process,
-        test.old_para,
-        test.old_paras,
-        test.old_blocks,
-        test.para,
-        test.paras,
-        test.blocks,
+        test.old_para_limit,
+        test.para_limit,
         test.success ? "true" : "false"
       );
-      if (processes[test.process].paras == -1)
+      if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
         printf("... not allocated, ignore\n");
+      else if (test.para_limit < process->para_base)
+        printf("... new limit < base, 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) {
+        old_para_limit = process->para_limit;
+        if (old_para_limit != test.old_para_limit)
           printf(
-            "... old blocks %d, should be %d\n",
-            old_blocks,
-            test.old_blocks
+            "... old para limit %d, should be %d\n",
+            old_para_limit,
+            test.para_limit
           );
-        }
+        process_calc(process, &calc);
+ printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
         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,
-          false
+          (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_limit,
+          old_para_limit - test.para_limit,
+          test.para_limit - process->para_base
         );
+        result = process_realloc(process, test.para_limit, false);
         printf(
           "... %s\n",
           result == test.success ?
@@ -437,56 +372,16 @@ int main(int argc, char **argv) {
         if (result) {
           if (!test.success) {
             printf("... undo\n");
-            rassert(
-              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
-            );
+            rassert(process_realloc(process, old_para_limit, false));
           }
           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
-              );
-            }
+            process_calc(process, &calc);
+ printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
             core_hash_init(
               test.process,
-              (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
-                new_para +
-                old_paras,
-              new_paras - old_paras,
-              old_paras
+              (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_limit,
+              test.para_limit - old_para_limit,
+              old_para_limit - process->para_base
             );
           }
         }
@@ -494,58 +389,33 @@ int main(int argc, char **argv) {
       break;
     case PROCESS_TEST_TYPE_REALLOC_BASE:
       printf(
-        "realloc_base %d %d %d %d %d %d %d %s\n",
+        "realloc_base %d %d %d %s\n",
         test.process,
-        test.old_para,
-        test.old_paras,
-        test.old_blocks,
-        test.para,
-        test.paras,
-        test.blocks,
+        test.old_para_base,
+        test.para_base,
         test.success ? "true" : "false"
       );
-      if (processes[test.process].paras == -1)
+      if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
         printf("... not allocated, ignore\n");
+      else if (test.para_base > process->para_limit)
+        printf("... new base > limit, 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) {
+        old_para_base = process->para_base;
+        if (old_para_base != test.old_para_base)
           printf(
-            "... old paras %d, should be %d\n",
-            old_paras,
-            test.old_paras
+            "... old para base %d, should be %d\n",
+            old_para_base,
+            test.para_base
           );
-        }
-        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
-          );
-        }
+        process_calc(process, &calc);
+ printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
         core_hash_verify(
           test.process,
-          (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
-            old_para,
-          old_paras - test.paras,
+          (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_base,
+          test.para_base - old_para_base,
           0
         );
-        result = process_realloc(
-          processes + test.process,
-          test.paras,
-          true
-        );
+        result = process_realloc(process, test.para_base, true);
         printf(
           "... %s\n",
           result == test.success ?
@@ -555,72 +425,29 @@ int main(int argc, char **argv) {
         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 ==
-              old_blocks
-            );
+            rassert(process_realloc(process, old_para_base, true));
           }
           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)
+            process_calc(process, &calc);
+ printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
+            if (test.para_base < test.old_para_base)
               core_hash_verify(
                 test.process,
-                (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
-                  new_para +
-                  new_paras -
-                  old_paras,
-                old_paras,
+                (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_base,
+                process->para_limit - old_para_base,
                 0
               );
             else
               core_hash_verify(
                 test.process,
-                (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
-                  new_para,
-                new_paras,
-                old_paras - new_paras
+                (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
+                process->para_limit - test.para_base,
+                test.para_base - old_para_base
               );
             core_hash_init(
               test.process,
-              (processes[test.process].core_item.base << BLOCK_PARAS_SHIFT) +
-                new_para,
-              new_paras,
+              (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
+              process->para_limit - test.para_base,
               0
             );
           }
@@ -629,66 +456,57 @@ int main(int argc, char **argv) {
       break;
     case PROCESS_TEST_TYPE_RUN:
       printf("run %d\n", test.process);
-      if (processes[test.process].paras == -1)
+      if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
         printf("... not allocated, ignore\n");
       else {
-        process_run(processes + test.process);
+        process_run(process);
         printf("... ok\n");
       }
       break;
     case PROCESS_TEST_TYPE_FREE:
       printf(
-        "free %d %d %d %d\n",
+        "free %d %d %d\n",
         test.process,
-        test.old_para,
-        test.old_paras,
-        test.old_blocks
+        test.old_para_base,
+        test.old_para_limit
       );
-      if (processes[test.process].paras == -1)
+      if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
         printf("... not allocated, ignore\n");
       else {
-        old_para = processes[test.process].para;
-        if (old_para != test.old_para) {
+        old_para_base = process->para_base;
+        if (old_para_base != test.old_para_base)
           printf(
-            "... old para %d, should be %d\n",
-            old_para,
-            test.old_para
+            "... old para base %d, should be %d\n",
+            old_para_base,
+            test.para_base
           );
-        }
-        old_paras = processes[test.process].paras;
-        if (old_paras != test.old_paras) {
+        old_para_limit = process->para_limit;
+        if (old_para_limit != test.old_para_limit)
           printf(
-            "... old paras %d, should be %d\n",
-            old_paras,
-            test.old_paras
+            "... old para limit %d, should be %d\n",
+            old_para_limit,
+            test.para_limit
           );
-        }
-        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
-          );
-        }
-        process_get_state(processes + test.process, &state);
- printf("old core [%d,%d) swap occupation [%d,%d)\n", state.core_block, state.core_block + state.core_blocks, state.swap_block, state.swap_block + state.swap_blocks);
+        process_calc(process, &calc);
+ printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
+        in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+        if (in_core_para < process->para_base)
+          in_core_para = process->para_base;
+        else if (in_core_para > process->para_limit)
+          in_core_para = process->para_limit;
         core_hash_verify(
           test.process,
-          state.core_para,
-          state.core_paras,
+          (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base,
+          in_core_para - process->para_base,
           0 
         );
         swap_hash_verify(
           test.process,
-          state.swap_para,
-          state.swap_paras,
-          state.core_paras
+          (calc.swap_origin << BLOCK_PARAS_SHIFT) + in_core_para,
+          process->para_limit - in_core_para,
+          in_core_para - process->para_base
         );
-        process_free(processes + test.process);
-        processes[test.process].paras = -1;
+        process_free(process);
         printf("... ok\n");
       }
       break;
@@ -700,44 +518,37 @@ done:
 #endif
   printf("final state:\n");
   for (i = 0; i < n_processes; ++i) {
-    if (processes[i].paras == -1)
+    process = processes + i;
+    if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
       printf("process %d: not allocated\n", i);
     else {
-      process_get_state(processes + i, &state);
+      process_calc(process, &calc);
       printf(
-        "process %d: core [%d,%d) swap occupation [%d,%d)\n",
+        "process %d: core [%d,%d) swap [%d,%d)\n",
         i,
-        state.core_block,
-        state.core_block + state.core_blocks,
-        state.swap_block,
-        state.swap_block + state.swap_blocks
+        calc.block_base + calc.core_origin,
+        calc.in_core_block + calc.core_origin,
+        calc.in_core_block + calc.swap_origin,
+        calc.block_limit + calc.swap_origin
       );
+      in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
+      if (in_core_para < process->para_base)
+        in_core_para = process->para_base;
+      else if (in_core_para > process->para_limit)
+        in_core_para = process->para_limit;
       core_hash_verify(
         i,
-        state.core_para,
-        state.core_paras,
-        0
-      );
-#ifdef INDIRECT_CORE
-      block_pool_free(
-        &core_block_pool,
-        core_table_mem + state.core_block,
-        state.core_blocks
+        (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base,
+        in_core_para - process->para_base,
+        0 
       );
-#endif /* INDIRECT_CORE */
       swap_hash_verify(
         i,
-        state.swap_para,
-        state.swap_paras,
-        state.core_paras
+        (calc.swap_origin << BLOCK_PARAS_SHIFT) + in_core_para,
+        process->para_limit - in_core_para,
+        in_core_para - process->para_base
       );
-#ifdef INDIRECT_SWAP
-      block_pool_free(
-        &swap_block_pool,
-        swap_table_mem + state.swap_block,
-        state.swap_blocks
-      );
-#endif /* INDIRECT_SWAP */
+      process_free(process);
     }
   }