From f4338d0b1e56cd85b3a323c9f0c0d9cc93ac003f Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Sun, 21 Apr 2019 21:38:36 +1000 Subject: [PATCH] Do proper computations about disk free space including possible direct and indirect blocks (should revisit to be less conservative in transfer sizes by estimating each victim separately so we don't need to allow for so many partial direct/indirect blocks upfront), get NDEBUG working again (doesn't fill core with 0xaa) --- Makefile | 1 + fuzix_fs.h | 2 +- indirect_core_inode_swap/o.sh | 5 +++- moveable_core_inode_swap/o.sh | 5 +++- o.sh | 5 +++- process.c | 44 +++++++++++++++++++++++++---------- process_test_gen.c | 4 ++-- process_test_run.c | 34 +++++++++++++++++++++++---- q.sh | 12 +++++----- rassert.h | 7 +++++- 10 files changed, 90 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index b36b816..1f74582 100644 --- 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 diff --git a/fuzix_fs.h b/fuzix_fs.h index 53cb69e..e7daa47 100644 --- a/fuzix_fs.h +++ b/fuzix_fs.h @@ -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) diff --git a/indirect_core_inode_swap/o.sh b/indirect_core_inode_swap/o.sh index 1e04eea..5a42b5f 100755 --- a/indirect_core_inode_swap/o.sh +++ b/indirect_core_inode_swap/o.sh @@ -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 = 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 diff --git a/process_test_gen.c b/process_test_gen.c index dd40e94..6dbf00f 100644 --- a/process_test_gen.c +++ b/process_test_gen.c @@ -4,8 +4,8 @@ #include #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)); diff --git a/process_test_run.c b/process_test_run.c index 0445783..2e78354 100644 --- a/process_test_run.c +++ b/process_test_run.c @@ -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 --- 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) diff --git a/rassert.h b/rassert.h index 39a41f4..552f04b 100644 --- a/rassert.h +++ b/rassert.h @@ -3,12 +3,17 @@ #include +/* 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 -- 2.34.1