Do proper computations about disk free space including possible direct and indirect...
authorNick Downing <nick@ndcode.org>
Sun, 21 Apr 2019 11:38:36 +0000 (21:38 +1000)
committerNick Downing <nick@ndcode.org>
Sun, 21 Apr 2019 11:52:12 +0000 (21:52 +1000)
Makefile
fuzix_fs.h
indirect_core_inode_swap/o.sh
moveable_core_inode_swap/o.sh
o.sh
process.c
process_test_gen.c
process_test_run.c
q.sh
rassert.h

index b36b816..1f74582 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
 CFLAGS=-g -Wall
+#CPPFLAGS=-DNDEBUG
 
 all: pool_test_gen pool_test_run process_test_gen process_test_run ucp mkfs \
 inode_test_gen inode_test_run
index 53cb69e..e7daa47 100644 (file)
@@ -16,7 +16,7 @@
 #define NDEVS 1
 #define NBUFS 10
 #define OFTSIZE 15
-#define ITABSIZE 96 //20
+#define ITABSIZE 20
 #define _NSIG NSIGS
 #define NULLINODE ((inoptr)NULL)
 #define NULLBLK ((blkno_t)-1)
index 1e04eea..5a42b5f 100755 (executable)
@@ -5,5 +5,8 @@ echo "generate test script"
 
 echo "run test script"
 rm -f fs.bin
-../mkfs fs.bin 256 16384
+# we need 1536 x 0.5 kbyte data blocks for 192 x 4 = 768 kbytes of swap data,
+# add 6 FULL indirect blocks, 32 partial indirect/double indirect, 1 root dir,
+# thus data part of volume will need 1575 blocks, so use 25 blocks of inodes
+../mkfs fs.bin 25 1600
 ./process_test_run 16 64 fs.bin 8 384 <process_test.txt
index 8788480..c8d5d83 100755 (executable)
@@ -5,5 +5,8 @@ echo "generate test script"
 
 echo "run test script"
 rm -f fs.bin
-../mkfs fs.bin 256 16384
+# we need 1536 x 0.5 kbyte data blocks for 192 x 4 = 768 kbytes of swap data,
+# add 6 FULL indirect blocks, 32 partial indirect/double indirect, 1 root dir,
+# thus data part of volume will need 1575 blocks, so use 25 blocks of inodes
+../mkfs fs.bin 25 1600
 ./process_test_run 16 64 fs.bin 8 <process_test.txt
diff --git a/o.sh b/o.sh
index edeccf3..0bde1b7 100755 (executable)
--- a/o.sh
+++ b/o.sh
@@ -6,5 +6,8 @@ echo "generate test script"
 echo "run test script"
 #./process_test_run 16 64 192 8 384 384 <process_test.txt
 rm -f fs.bin
-./mkfs fs.bin 256 16384
+# we need 1536 x 0.5 kbyte data blocks for 192 x 4 = 768 kbytes of swap data,
+# add 6 FULL indirect blocks, 32 partial indirect/double indirect, 1 root dir,
+# thus data part of volume will need 1575 blocks, so use 25 blocks of inodes
+./mkfs fs.bin 25 1600
 ./process_test_run 16 64 fs.bin 8 384 384 <process_test.txt
index a98c809..08e64d4 100644 (file)
--- a/process.c
+++ b/process.c
@@ -18,7 +18,7 @@ struct process *processes;
 int n_processes;
 
 #ifdef INODE_SWAP
-long process_avail;
+long process_avail, process_spare;
 #else
 int process_avail;
 #endif
@@ -28,7 +28,10 @@ struct lru_item lru_head;
 struct process *victim;
 
 #ifdef INODE_SWAP
-long estimate_size(long size) {
+// adds indirect and double indirect block(s) to estimate disk size of file
+// also does another estimation based on the internal fragmentation of core
+// returns the larger of the two estimates
+static long estimate_size(long size) {
   long core_size;
   int blocks, disk_blocks;
   long disk_size;
@@ -51,6 +54,18 @@ long estimate_size(long size) {
   disk_size = (long)disk_blocks << DISK_BLOCK_SHIFT;
   return core_size >= disk_size ? core_size : disk_size;
 }
+
+// basically the inverse of the above, estimates size of files that could be
+// created if space is divided into at most n files, but a bit conservatively
+static long estimate_free() {
+  int blocks;
+
+  // at most one partial indirect and double indirect block per file
+  blocks = fs_tab[0].s_tfree - (n_processes << 1);
+  // max number of FULL indirect blocks (ignore the 18 direct blocks)
+  blocks -= blocks / (DISK_INDIRECT_SIZE + 1);
+  return (long)blocks << DISK_BLOCK_SHIFT;
+}
 #endif
 
 void process_init(int n, int spare) {
@@ -71,13 +86,13 @@ void process_init(int n, int spare) {
 
 #ifdef INODE_SWAP
   process_avail =
-    ((long)(core_avail() - spare) << BLOCK_SHIFT) + 
-    ((long)fs_tab[0].s_tfree << DISK_BLOCK_SHIFT);
+    ((long)(core_avail() - spare) << BLOCK_SHIFT) + estimate_free();
 #ifdef PREALLOCATE_CORE
   core_table_avail = (long)core_table.avail << BLOCK_SHIFT;
   if (process_avail > core_table_avail)
     process_avail = core_table_avail;
 #endif
+ printf("process_avail %ld\n", process_avail);
 #else
   process_avail = core_avail() + swap_avail() - spare;
 #ifdef PREALLOCATE_CORE
@@ -88,6 +103,7 @@ void process_init(int n, int spare) {
   if (process_avail > swap_table.avail)
     process_avail = swap_table.avail;
 #endif
+ printf("process_avail %d\n", process_avail);
 #endif
 
   lru_head.prev = &lru_head;
@@ -499,10 +515,8 @@ bool process_realloc(struct process *process, long size) {
 
 void process_run(struct process *process) {
   int blocks, swap_out;
-#ifndef INODE_SWAP // temporarily remove until we can fix the logic
 #if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
   int excess;
-#endif
 #endif
   int process_core_blocks, process_swap_blocks;
 #ifdef INODE_SWAP
@@ -544,14 +558,17 @@ void process_run(struct process *process) {
       // calculate amounts to swap out then in
       blocks = process_swap_blocks;
       swap_out = blocks - core_avail();
-#ifndef INODE_SWAP // temporarily remove until we can fix the logic
 #if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
+#ifdef INODE_SWAP
+ printf("estimate_free %ld blocks %d\n", estimate_free(), (int)(estimate_free() >> BLOCK_SHIFT));
+      excess = swap_out - (int)(estimate_free() >> BLOCK_SHIFT);
+#else
       excess = swap_out - swap_avail();
+#endif
       if (excess > 0) {
         blocks -= excess;
-        swap_out = swap_avail();
+        swap_out -= excess;
       }
-#endif
 #endif
 
       // free up as much core as we can
@@ -603,14 +620,17 @@ void process_run(struct process *process) {
       // calculate amounts to swap out then in
       blocks = process_swap_blocks;
       swap_out = blocks - core_avail();
-#ifndef INODE_SWAP // temporarily remove until we can fix the logic
 #if !defined(PREALLOCATE_SWAP) || defined(INDIRECT_SWAP)
+#ifdef INODE_SWAP
+ printf("estimate_free %ld blocks %d\n", estimate_free(), (int)(estimate_free() >> BLOCK_SHIFT));
+      excess = swap_out - (int)(estimate_free() >> BLOCK_SHIFT);
+#else
       excess = swap_out - swap_avail();
+#endif
       if (excess > 0) {
         blocks -= excess;
-        swap_out = swap_avail();
+        swap_out -= excess;
       }
-#endif
 #endif
 
       // free up as much core as we can
index dd40e94..6dbf00f 100644 (file)
@@ -4,8 +4,8 @@
 #include <string.h>
 #include "rassert.h"
 
-#define BLOCK_SIZE 0x10 //0x1000
-#define BLOCK_SHIFT 4 //12
+#define BLOCK_SIZE 0x1000
+#define BLOCK_SHIFT 12
 
 int rand_int(int n) {
   return (int)((long long)rand() * n / (RAND_MAX + 1LL));
index 0445783..2e78354 100644 (file)
@@ -38,7 +38,7 @@ void core_hash_init(int process, long base, long size, long offset) {
     hash = (hash & 0xffffLL) + (hash >> 16);
     hash = (hash & 0xffLL) + (hash >> 8);
     hash = (hash & 0xffLL) + (hash >> 8);
-    rassert(core_block_mem[addr] == 0xaa);
+    assert(core_block_mem[addr] == 0xaa);
     core_block_mem[addr] = (uint8_t)hash;
   }
 }
@@ -61,7 +61,9 @@ void core_hash_verify(int process, long base, long size, long offset) {
     hash = (hash & 0xffLL) + (hash >> 8);
     hash = (hash & 0xffLL) + (hash >> 8);
     rassert(core_block_mem[addr] == (uint8_t)hash);
+#ifndef NDEBUG
     core_block_mem[addr] = 0xaa;
+#endif
   }
 }
 
@@ -115,7 +117,9 @@ void swap_hash_verify(int process, long base, long size) {
     hash = (hash & 0xffLL) + (hash >> 8);
     hash = (hash & 0xffLL) + (hash >> 8);
     rassert(swap_block_mem[addr] == (uint8_t)hash);
+#ifndef NDEBUG
     swap_block_mem[addr] = 0xaa;
+#endif
   }
 }
 #endif
@@ -157,8 +161,10 @@ void swap_read(
   long i, count;
 
  //printf("swap_read %d %ld %ld %ld\n", inode->c_num, offset, core_base, size);
+#ifndef NDEBUG
   for (i = 0; i < size; ++i)
-    rassert(core_block_mem[core_base + i] == 0xaa);
+    assert(core_block_mem[core_base + i] == 0xaa);
+#endif
 
   for (i = 0; (count = size - i) > 0; i += count) {
     if (count > TRANSFER_SIZE)
@@ -192,7 +198,9 @@ void swap_write(
     rassert(writei(inode) == (int)count && udata.u_error == 0);
   }
 
+#ifndef NDEBUG
   memset(core_block_mem + core_base, 0xaa, size);
+#endif
 }
 #else
 #ifndef INDIRECT_SWAP
@@ -226,20 +234,28 @@ void core_to_swap_copy(long src_base, long dest_base, long size) {
   long i;
 
  //printf("core_to_swap_copy %ld(%d) %ld(%d) %ld(%d)\n", src_base, (int)(src_base >> BLOCK_SHIFT), dest_base, (int)(dest_base >> BLOCK_SHIFT), size, (int)((size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT));
+#ifndef NDEBUG
   for (i = 0; i < size; ++i)
     assert(swap_block_mem[dest_base + i] == 0xaa);
+#endif
   memcpy(swap_block_mem + dest_base, core_block_mem + src_base, size);
+#ifndef NDEBUG
   memset(core_block_mem + src_base, 0xaa, size);
+#endif
 }
 
 void swap_to_core_copy(long src_base, long dest_base, long size) {
   long i;
 
  //printf("swap_to_core_copy %ld(%d) %ld(%d) %ld(%d)\n", src_base, (int)(src_base >> BLOCK_SHIFT), dest_base, (int)(dest_base >> BLOCK_SHIFT), size, (int)((size + (BLOCK_SIZE - 1)) >> BLOCK_SHIFT));
+#ifndef NDEBUG
   for (i = 0; i < size; ++i)
     assert(core_block_mem[dest_base + i] == 0xaa);
+#endif
   memcpy(core_block_mem + dest_base, swap_block_mem + src_base, size);
+#ifndef NDEBUG
   memset(swap_block_mem + src_base, 0xaa, size);
+#endif
 }
 #endif
 
@@ -260,8 +276,10 @@ int main(int argc, char **argv) {
 #endif
 #if defined(INDIRECT_CORE) || defined(INDIRECT_SWAP)
   int i, j, k;
-#else
+#elif !defined(NDEBUG)
   int i, j;
+#else
+  int i;
 #endif
   char buf[256];
   int process;
@@ -318,7 +336,9 @@ int main(int argc, char **argv) {
 #endif
   core_block_mem = malloc((long)n_core_blocks << BLOCK_SHIFT);
   rassert(core_block_mem);
+#ifndef NDEBUG
   memset(core_block_mem, 0xaa, (long)n_core_blocks << BLOCK_SHIFT);
+#endif
 
 #ifdef INODE_SWAP
   fd_open(fs_path);
@@ -332,7 +352,9 @@ int main(int argc, char **argv) {
 #endif
   swap_block_mem = malloc((long)n_swap_blocks << BLOCK_SHIFT);
   rassert(swap_block_mem);
+#ifndef NDEBUG
   memset(swap_block_mem, 0xaa, (long)n_swap_blocks << BLOCK_SHIFT);
+#endif
 #endif
 
   process_init(n_processes, spare);
@@ -687,9 +709,11 @@ done:
       rassert(core_block_bitmap[j] == (uint8_t)~(-1 << k));
   }
 #endif
+#ifndef NDEBUG
   j = n_core_blocks << BLOCK_SHIFT;
   for (i = 0; i < j; ++i)
-    rassert(core_block_mem[i] == 0xaa);
+    assert(core_block_mem[i] == 0xaa);
+#endif
 #ifdef INODE_SWAP
   printf("free inodes %d blocks %d\n", fs_tab[0].s_tinode, fs_tab[0].s_tfree);
 #else
@@ -705,9 +729,11 @@ done:
       rassert(swap_block_bitmap[j] == (uint8_t)~(-1 << k));
   }
 #endif
+#ifndef NDEBUG
   j = n_swap_blocks << BLOCK_SHIFT;
   for (i = 0; i < j; ++i)
     rassert(swap_block_mem[i] == 0xaa);
+#endif
 #endif
 
   return 0;
diff --git a/q.sh b/q.sh
index 0e71219..3558241 100755 (executable)
--- a/q.sh
+++ b/q.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
-(cd indirect_core_indirect_swap && make && ./o.sh)
-(cd indirect_core_inode_swap && make && ./o.sh)
-(cd indirect_core_preallocate_swap && make && ./o.sh)
-(cd moveable_core_indirect_swap && make && ./o.sh)
-(cd moveable_core_inode_swap && make && ./o.sh)
-(cd moveable_core_preallocate_swap && make && ./o.sh)
+(cd indirect_core_indirect_swap && make clean && make && ./o.sh)
+(cd indirect_core_inode_swap && make clean && make && ./o.sh)
+(cd indirect_core_preallocate_swap && make clean && make && ./o.sh)
+(cd moveable_core_indirect_swap && make clean && make && ./o.sh)
+(cd moveable_core_inode_swap && make clean && make && ./o.sh)
+(cd moveable_core_preallocate_swap && make clean && make && ./o.sh)
index 39a41f4..552f04b 100644 (file)
--- a/rassert.h
+++ b/rassert.h
@@ -3,12 +3,17 @@
 
 #include <assert.h>
 
+/* This prints an "Assertion failed" message and aborts.  */
+extern void __assert_fail (const char *__assertion, const char *__file,
+                          unsigned int __line, const char *__function)
+     __THROW __attribute__ ((__noreturn__));
+
 #  define rassert(expr)                                                        \
   ((void) sizeof ((expr) ? 1 : 0), __extension__ ({                    \
       if (expr)                                                                \
         ; /* empty */                                                  \
       else                                                             \
-        __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION);  \
+        __assert_fail (#expr, __FILE__, __LINE__, __func__);           \
     }))
 
 #endif