Make swap reading/writing take bytes not blocks, allowing incomplete last block
authorNick Downing <nick@ndcode.org>
Thu, 4 Apr 2019 10:20:03 +0000 (21:20 +1100)
committerNick Downing <nick@ndcode.org>
Thu, 4 Apr 2019 10:54:36 +0000 (21:54 +1100)
process.c
swap.c
swap.h

index 318b791..513ca3b 100644 (file)
--- a/process.c
+++ b/process.c
@@ -259,7 +259,7 @@ static void do_swap_out(int swap_out) {
 #ifdef INDIRECT_SWAP
       rassert(swap_block_alloc(swap_table_mem + swap_base, blocks));
 #endif
-      swap_write(swap_base, core_base, blocks);
+      swap_write(swap_base, core_base, (long)blocks << BLOCK_SHIFT);
 #ifdef INDIRECT_CORE
       core_block_free(core_table_mem + core_base, blocks);
 #endif
@@ -549,7 +549,7 @@ void process_run(struct process *process) {
 #ifdef INDIRECT_CORE
       core_block_alloc(core_table_mem + core_base, blocks);
 #endif
-      swap_read(swap_base, core_base, blocks);
+      swap_read(swap_base, core_base, (long)blocks << BLOCK_SHIFT);
 #ifdef INDIRECT_SWAP
       swap_block_free(swap_table_mem + swap_base, blocks);
 #endif
diff --git a/swap.c b/swap.c
index 175b103..d814595 100644 (file)
--- a/swap.c
+++ b/swap.c
@@ -194,80 +194,71 @@ void swap_block_free(int *table, int size) {
 }
 #endif
 
-void swap_read(int swap_base, int core_base, int size) {
- printf("swap_read swap [%d,%d) to core [%d,%d)\n", swap_base, swap_base + size, core_base, core_base + 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)
  printf("blocks");
 #endif
   for (int i = 0; i < size; ++i) {
+    int swap_block = swap_base + i;
 #ifdef INDIRECT_SWAP
-    int swap_block = swap_table_mem[swap_base + i];
+    swap_block = swap_table_mem[swap_block];
  printf(" %d", swap_block);
-#else
-    int swap_block = swap_base + i;
 #endif
+    long swap_addr = (long)swap_block << BLOCK_SHIFT;
+    int core_block = core_base + i;
 #ifdef INDIRECT_CORE
-    int core_block = core_table_mem[core_base + i];
+    core_block = core_table_mem[core_block];
 #ifdef INDIRECT_SWAP
  printf(",%d", core_block);
 #else
  printf(" %d", core_block);
 #endif
-#else
-    int core_block = core_base + i;
 #endif
-    for (int j = 0; j < BLOCK_SIZE; ++j)
-      assert(core_block_mem[core_block * BLOCK_SIZE + j] == 0xaa);
-    memcpy(
-      core_block_mem + core_block * BLOCK_SIZE,
-      swap_block_mem + swap_block * BLOCK_SIZE,
-      BLOCK_SIZE
-    );
-    memset(
-      swap_block_mem + swap_block * BLOCK_SIZE,
-      0xaa,
-      BLOCK_SIZE
-    );
+    long core_addr = (long)core_block << BLOCK_SHIFT;
+    int count = size < BLOCK_SIZE ? (int)size : BLOCK_SIZE;
+    size -= count;
+    for (int j = 0; j < count; ++j)
+      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 defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
  printf("\n");
 #endif
 }
 
-void swap_write(int swap_base, int core_base, int size) {
- printf("swap_write core [%d,%d) to swap [%d,%d)\n", core_base, core_base + size, swap_base, swap_base + size);
+void swap_write(int swap_base, int core_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)
  printf("blocks");
 #endif
   for (int i = 0; i < size; ++i) {
+    int core_block = core_base + i;
 #ifdef INDIRECT_CORE
-    int core_block = core_table_mem[core_base + i];
+    core_block = core_table_mem[core_block];
  printf(" %d", core_block);
-#else
-    int core_block = core_base + i;
 #endif
+    long core_addr = (long)core_block << BLOCK_SHIFT;
+    int swap_block = swap_base + i;
 #ifdef INDIRECT_SWAP
-    int swap_block = swap_table_mem[swap_base + i];
+    swap_block = swap_table_mem[swap_block];
 #ifdef INDIRECT_CORE
  printf(",%d", swap_block);
 #else
  printf(" %d", swap_block);
 #endif
-#else
-    int swap_block = swap_base + i;
 #endif
-    for (int j = 0; j < BLOCK_SIZE; ++j)
-      assert(swap_block_mem[swap_block * BLOCK_SIZE + j] == 0xaa);
-    memcpy(
-      swap_block_mem + swap_block * BLOCK_SIZE,
-      core_block_mem + core_block * BLOCK_SIZE,
-      BLOCK_SIZE
-    );
-    memset(
-      core_block_mem + core_block * BLOCK_SIZE,
-      0xaa,
-      BLOCK_SIZE
-    );
+    long swap_addr = (long)swap_block << BLOCK_SHIFT;
+    int count = size < BLOCK_SIZE ? (int)size : BLOCK_SIZE;
+    size -= count;
+    for (int j = 0; j < count; ++j)
+      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 defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
  printf("\n");
diff --git a/swap.h b/swap.h
index c720a0b..894ced1 100644 (file)
--- a/swap.h
+++ b/swap.h
@@ -50,7 +50,7 @@ void swap_block_free(int *blocks, int size);
 #else
 void swap_init(int n_table);
 #endif
-void swap_read(int swap_base, int core_base, int size);
-void swap_write(int swap_base, int core_base, int size);
+void swap_read(int swap_base, int core_base, long size);
+void swap_write(int swap_base, int core_base, long size);
 
 #endif