More optimal handling of incomplete last block in swap_read()/swap_write()
authorNick Downing <nick@ndcode.org>
Sat, 6 Apr 2019 03:31:15 +0000 (14:31 +1100)
committerNick Downing <nick@ndcode.org>
Sat, 6 Apr 2019 03:31:26 +0000 (14:31 +1100)
swap.c

diff --git a/swap.c b/swap.c
index 49abae0..4c7a9db 100644 (file)
--- a/swap.c
+++ b/swap.c
@@ -203,11 +203,20 @@ void swap_block_free(int *table, int size) {
 
 // bases are in blocks, size is in bytes (allows incomplete last block)
 void swap_read(int swap_base, int core_base, long size) {
-  int blocks = (int)((size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
- printf("swap_read swap [%d,%d) to core [%d,%d)\n", swap_base, swap_base + blocks, core_base, core_base + blocks);
-#if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
+#if !defined(INDIRECT_CORE) && !defined(INDIRECT_SWAP)
+ int blocks = (int)(size >> BLOCK_SHIFT);
+ int partial = (int)size & (BLOCK_SIZE - 1);
+ printf("swap_read swap [%d,%d) to core [%d,%d)\n", swap_base, swap_base + blocks + (partial != 0), core_base, core_base + blocks + (partial != 0));
+  swap_to_core_copy(
+    (long)swap_block << BLOCK_SHIFT,
+    (long)core_block << BLOCK_SHIFT,
+    size
+  );
+#else
+  int blocks = (int)(size >> BLOCK_SHIFT);
+  int partial = (int)size & (BLOCK_SIZE - 1);
+ printf("swap_read swap [%d,%d) to core [%d,%d)\n", swap_base, swap_base + blocks + (partial != 0), core_base, core_base + blocks + (partial != 0));
  printf("blocks");
-#endif
   for (int i = 0; i < blocks; ++i) {
     int swap_block = swap_base + i;
 #ifdef INDIRECT_SWAP
@@ -223,29 +232,53 @@ void swap_read(int swap_base, int core_base, long size) {
  printf(" %d", core_block);
 #endif
 #endif
-    long count = size < BLOCK_SIZE ? size : BLOCK_SIZE;
-#if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
- if (count < BLOCK_SIZE)
-  putchar('*');
+    swap_to_core_copy(
+      (long)swap_block << BLOCK_SHIFT,
+      (long)core_block << BLOCK_SHIFT,
+      BLOCK_SIZE
+    );
+  }
+  if (partial) {
+    int swap_block = swap_base + blocks;
+#ifdef INDIRECT_SWAP
+    swap_block = swap_table_mem[swap_block];
+ printf(" %d", swap_block);
+#endif
+    int core_block = core_base + blocks;
+#ifdef INDIRECT_CORE
+    core_block = core_table_mem[core_block];
+#ifdef INDIRECT_SWAP
+ printf(",%d", core_block);
+#else
+ printf(" %d", core_block);
+#endif
 #endif
+ putchar('*');
     swap_to_core_copy(
       (long)swap_block << BLOCK_SHIFT,
       (long)core_block << BLOCK_SHIFT,
-      count
+      partial
     );
-    size -= count;
   }
-#if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
  printf("\n");
 #endif
 }
 
 void swap_write(int core_base, int swap_base, long size) {
-  int blocks = (int)((size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT);
- printf("swap_write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + blocks, swap_base, swap_base + blocks);
-#if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
+#if !defined(INDIRECT_CORE) && !defined(INDIRECT_SWAP)
+ int blocks = (int)(size >> BLOCK_SHIFT);
+ int partial = (int)size & (BLOCK_SIZE - 1);
+ printf("swap_write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + blocks + (partial != 0), swap_base, swap_base + blocks + (partial != 0));
+  core_to_swap_copy(
+    (long)core_block << BLOCK_SHIFT,
+    (long)swap_block << BLOCK_SHIFT,
+    size
+  );
+#else
+  int blocks = (int)(size >> BLOCK_SHIFT);
+  int partial = (int)size & (BLOCK_SIZE - 1);
+ printf("swap_write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + blocks + (partial != 0), swap_base, swap_base + blocks + (partial != 0));
  printf("blocks");
-#endif
   for (int i = 0; i < blocks; ++i) {
     int core_block = core_base + i;
 #ifdef INDIRECT_CORE
@@ -261,19 +294,34 @@ void swap_write(int core_base, int swap_base, long size) {
  printf(" %d", swap_block);
 #endif
 #endif
-    long count = size < BLOCK_SIZE ? size : BLOCK_SIZE;
-#if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
- if (count < BLOCK_SIZE)
-  putchar('*');
+    core_to_swap_copy(
+      (long)core_block << BLOCK_SHIFT,
+      (long)swap_block << BLOCK_SHIFT,
+      BLOCK_SIZE
+    );
+  }
+  if (partial) {
+    int core_block = core_base + blocks;
+#ifdef INDIRECT_CORE
+    core_block = core_table_mem[core_block];
+ printf(" %d", core_block);
+#endif
+    int swap_block = swap_base + blocks;
+#ifdef INDIRECT_SWAP
+    swap_block = swap_table_mem[swap_block];
+#ifdef INDIRECT_CORE
+ printf(",%d", swap_block);
+#else
+ printf(" %d", swap_block);
+#endif
 #endif
+ putchar('*');
     core_to_swap_copy(
       (long)core_block << BLOCK_SHIFT,
       (long)swap_block << BLOCK_SHIFT,
-      count
+      partial
     );
-    size -= count;
   }
-#if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
  printf("\n");
 #endif
 }