Implement partial transfer to/from swap for incomplete last block pool_swap
authorNick Downing <nick@ndcode.org>
Thu, 4 Apr 2019 11:20:43 +0000 (22:20 +1100)
committerNick Downing <nick@ndcode.org>
Thu, 4 Apr 2019 11:20:43 +0000 (22:20 +1100)
o.sh
process.c
swap.c

diff --git a/o.sh b/o.sh
index ef53fbb..a2d40dc 100755 (executable)
--- a/o.sh
+++ b/o.sh
@@ -1,12 +1,7 @@
 #!/bin/sh
 
 echo "generate test script"
-# preallocated core, possible preallocated swap (not indirect):
-#./process_test_gen 16 48 1024 32 >process_test.txt
-# non preallocated core, preallocated swap (not indirect):
-#./process_test_gen 16 176 1024 32 >process_test.txt
-# non preallocated core, non preallocated swap (or indirect swap):
-./process_test_gen 16 240 1024 32 >process_test.txt
+./process_test_gen 16 248 1024 32 >process_test.txt
 
 echo "run test script"
-./process_test_run 16 64 192 16 384 384 <process_test.txt
+./process_test_run 16 64 192 8 384 384 <process_test.txt
index 513ca3b..52b35b2 100644 (file)
--- a/process.c
+++ b/process.c
@@ -196,6 +196,7 @@ static void do_swap_out(int swap_out) {
   int victim_swap_blocks;
 #endif
   int blocks, swap_base, core_base;
+  long size;
 
   // loop entry code for the case of an existing victim
   if (swap_out > 0) {
@@ -253,13 +254,21 @@ static void do_swap_out(int swap_out) {
 #endif
 
     loop_entry:
-      // transfer data to swap
+      // calculate transfer parameters
       swap_base = DEDICATED_SWAP_LIMIT(victim, victim_swap_blocks) - blocks;
       core_base = DEDICATED_CORE_BASE(victim, victim_swap_blocks - blocks);
+      size = (long)blocks << BLOCK_SHIFT;
+
+      // see if last transfer for victim
+      if (victim_core_blocks == blocks)
+        // yes, correct size for partial last block
+        size += ((victim->size - 1L) | -BLOCK_SIZE) + 1L;
+
+      // transfer data to swap
 #ifdef INDIRECT_SWAP
       rassert(swap_block_alloc(swap_table_mem + swap_base, blocks));
 #endif
-      swap_write(swap_base, core_base, (long)blocks << BLOCK_SHIFT);
+      swap_write(swap_base, core_base, size);
 #ifdef INDIRECT_CORE
       core_block_free(core_table_mem + core_base, blocks);
 #endif
@@ -272,11 +281,12 @@ static void do_swap_out(int swap_out) {
         rassert(core_table_realloc_base(&victim_core_item, victim_core_blocks));
 #endif
 
-        // as an optimization, skip the calculation of swap_out -= blocks
+        // in this case there can't be any further victim to swap
+        assert(swap_out == blocks);
         return;
       }
-
  printf("victimized %d\n", (int)(victim - processes));
+
 #ifndef PREALLOCATE_CORE
       // remove from core pool, using dedicated core item
       core_table_free(&victim_core_item);
@@ -435,6 +445,7 @@ void process_run(struct process *process) {
   struct pool_item process_swap_item;
 #endif
   int swap_base, core_base;
+  long size;
 
   // must be already allocated
   assert(process->size != -1L);
@@ -543,13 +554,21 @@ void process_run(struct process *process) {
 #endif
 
     loop_entry_full:
-      // transfer data to core
+      // calculate transfer parameters
       swap_base = DEDICATED_SWAP_LIMIT(process, process_swap_blocks) - blocks;
       core_base = DEDICATED_CORE_BASE(process, process_swap_blocks - blocks);
+      size = (long)blocks << BLOCK_SHIFT;
+
+      // see if first transfer for process
+      if (process_core_blocks == blocks)
+        // yes, correct size for partial last block
+        size += ((process->size - 1L) | -BLOCK_SIZE) + 1L;
+
+      // transfer data to core
 #ifdef INDIRECT_CORE
       core_block_alloc(core_table_mem + core_base, blocks);
 #endif
-      swap_read(swap_base, core_base, (long)blocks << BLOCK_SHIFT);
+      swap_read(swap_base, core_base, size);
 #ifdef INDIRECT_SWAP
       swap_block_free(swap_table_mem + swap_base, blocks);
 #endif
diff --git a/swap.c b/swap.c
index d814595..2cfe598 100644 (file)
--- a/swap.c
+++ b/swap.c
@@ -224,6 +224,10 @@ void swap_read(int swap_base, int core_base, long size) {
       assert(core_block_mem[core_addr + j] == 0xaa);
     memcpy(core_block_mem + core_addr, swap_block_mem + swap_addr, count);
     memset(swap_block_mem + swap_addr, 0xaa, count);
+ if (count < BLOCK_SIZE) {
+  putchar('*');
+  assert(swap_block_mem[swap_addr + count] == 0xaa);
+ }
   }
 #if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
  printf("\n");
@@ -259,6 +263,10 @@ void swap_write(int swap_base, int core_base, long size) {
       assert(swap_block_mem[swap_addr + j] == 0xaa);
     memcpy(swap_block_mem + swap_addr, core_block_mem + core_addr, count);
     memset(core_block_mem + core_addr, 0xaa, count);
+ if (count < BLOCK_SIZE) {
+  putchar('*');
+  assert(core_block_mem[core_addr + count] == 0xaa);
+ }
   }
 #if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
  printf("\n");