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
#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)
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
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
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
int n_processes;
#ifdef INODE_SWAP
-long process_avail;
+long process_avail, process_spare;
#else
int process_avail;
#endif
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;
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) {
#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
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;
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
// 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
// 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
#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));
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;
}
}
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
}
}
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
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)
rassert(writei(inode) == (int)count && udata.u_error == 0);
}
+#ifndef NDEBUG
memset(core_block_mem + core_base, 0xaa, size);
+#endif
}
#else
#ifndef INDIRECT_SWAP
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
#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;
#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);
#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);
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
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;
#!/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)
#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