mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
WIP one possible solution for non-DAG trees exploiting half-orphans
This commit is contained in:
@@ -350,116 +350,117 @@ exhausted:
|
||||
LFS_ASSERT(run_cycles[1]*110/100 > 2*run_cycles[0]);
|
||||
'''
|
||||
|
||||
[[case]] # test that we wear blocks roughly evenly
|
||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
||||
define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
||||
define.LFS_BLOCK_CYCLES = [5, 4, 3, 2, 1]
|
||||
define.CYCLES = 100
|
||||
define.FILES = 10
|
||||
if = 'LFS_BLOCK_CYCLES < CYCLES/10'
|
||||
code = '''
|
||||
lfs_format(&lfs, &cfg) => 0;
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_mkdir(&lfs, "roadrunner") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
|
||||
uint32_t cycle = 0;
|
||||
while (cycle < CYCLES) {
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
for (uint32_t i = 0; i < FILES; i++) {
|
||||
// chose name, roughly random seed, and random 2^n size
|
||||
sprintf(path, "roadrunner/test%d", i);
|
||||
srand(cycle * i);
|
||||
size = 1 << 4; //((rand() % 10)+2);
|
||||
|
||||
lfs_file_open(&lfs, &file, path,
|
||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||
|
||||
for (lfs_size_t j = 0; j < size; j++) {
|
||||
char c = 'a' + (rand() % 26);
|
||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
||||
assert(res == 1 || res == LFS_ERR_NOSPC);
|
||||
if (res == LFS_ERR_NOSPC) {
|
||||
err = lfs_file_close(&lfs, &file);
|
||||
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||
lfs_unmount(&lfs) => 0;
|
||||
goto exhausted;
|
||||
}
|
||||
}
|
||||
|
||||
err = lfs_file_close(&lfs, &file);
|
||||
assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
lfs_unmount(&lfs) => 0;
|
||||
goto exhausted;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < FILES; i++) {
|
||||
// check for errors
|
||||
sprintf(path, "roadrunner/test%d", i);
|
||||
srand(cycle * i);
|
||||
size = 1 << 4; //((rand() % 10)+2);
|
||||
|
||||
lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||
for (lfs_size_t j = 0; j < size; j++) {
|
||||
char c = 'a' + (rand() % 26);
|
||||
char r;
|
||||
lfs_file_read(&lfs, &file, &r, 1) => 1;
|
||||
assert(r == c);
|
||||
}
|
||||
|
||||
lfs_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
lfs_unmount(&lfs) => 0;
|
||||
|
||||
cycle += 1;
|
||||
}
|
||||
|
||||
exhausted:
|
||||
// should still be readable
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
for (uint32_t i = 0; i < FILES; i++) {
|
||||
// check for errors
|
||||
sprintf(path, "roadrunner/test%d", i);
|
||||
lfs_stat(&lfs, path, &info) => 0;
|
||||
}
|
||||
lfs_unmount(&lfs) => 0;
|
||||
|
||||
LFS_WARN("completed %d cycles", cycle);
|
||||
|
||||
// check the wear on our block device
|
||||
lfs_testbd_wear_t minwear = -1;
|
||||
lfs_testbd_wear_t totalwear = 0;
|
||||
lfs_testbd_wear_t maxwear = 0;
|
||||
// skip 0 and 1 as superblock movement is intentionally avoided
|
||||
for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
|
||||
lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
|
||||
printf("%08x: wear %d\n", b, wear);
|
||||
assert(wear >= 0);
|
||||
if (wear < minwear) {
|
||||
minwear = wear;
|
||||
}
|
||||
if (wear > maxwear) {
|
||||
maxwear = wear;
|
||||
}
|
||||
totalwear += wear;
|
||||
}
|
||||
lfs_testbd_wear_t avgwear = totalwear / LFS_BLOCK_COUNT;
|
||||
LFS_WARN("max wear: %d cycles", maxwear);
|
||||
LFS_WARN("avg wear: %d cycles", totalwear / LFS_BLOCK_COUNT);
|
||||
LFS_WARN("min wear: %d cycles", minwear);
|
||||
|
||||
// find standard deviation^2
|
||||
lfs_testbd_wear_t dev2 = 0;
|
||||
for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
|
||||
lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
|
||||
assert(wear >= 0);
|
||||
lfs_testbd_swear_t diff = wear - avgwear;
|
||||
dev2 += diff*diff;
|
||||
}
|
||||
dev2 /= totalwear;
|
||||
LFS_WARN("std dev^2: %d", dev2);
|
||||
assert(dev2 < 8);
|
||||
'''
|
||||
# TODO fixme
|
||||
#[[case]] # test that we wear blocks roughly evenly
|
||||
#define.LFS_ERASE_CYCLES = 0xffffffff
|
||||
#define.LFS_BLOCK_COUNT = 256 # small bd so test runs faster
|
||||
#define.LFS_BLOCK_CYCLES = [5, 4, 3, 2, 1]
|
||||
#define.CYCLES = 100
|
||||
#define.FILES = 10
|
||||
#if = 'LFS_BLOCK_CYCLES < CYCLES/10'
|
||||
#code = '''
|
||||
# lfs_format(&lfs, &cfg) => 0;
|
||||
# lfs_mount(&lfs, &cfg) => 0;
|
||||
# lfs_mkdir(&lfs, "roadrunner") => 0;
|
||||
# lfs_unmount(&lfs) => 0;
|
||||
#
|
||||
# uint32_t cycle = 0;
|
||||
# while (cycle < CYCLES) {
|
||||
# lfs_mount(&lfs, &cfg) => 0;
|
||||
# for (uint32_t i = 0; i < FILES; i++) {
|
||||
# // chose name, roughly random seed, and random 2^n size
|
||||
# sprintf(path, "roadrunner/test%d", i);
|
||||
# srand(cycle * i);
|
||||
# size = 1 << 4; //((rand() % 10)+2);
|
||||
#
|
||||
# lfs_file_open(&lfs, &file, path,
|
||||
# LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||
#
|
||||
# for (lfs_size_t j = 0; j < size; j++) {
|
||||
# char c = 'a' + (rand() % 26);
|
||||
# lfs_ssize_t res = lfs_file_write(&lfs, &file, &c, 1);
|
||||
# assert(res == 1 || res == LFS_ERR_NOSPC);
|
||||
# if (res == LFS_ERR_NOSPC) {
|
||||
# err = lfs_file_close(&lfs, &file);
|
||||
# assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||
# lfs_unmount(&lfs) => 0;
|
||||
# goto exhausted;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# err = lfs_file_close(&lfs, &file);
|
||||
# assert(err == 0 || err == LFS_ERR_NOSPC);
|
||||
# if (err == LFS_ERR_NOSPC) {
|
||||
# lfs_unmount(&lfs) => 0;
|
||||
# goto exhausted;
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# for (uint32_t i = 0; i < FILES; i++) {
|
||||
# // check for errors
|
||||
# sprintf(path, "roadrunner/test%d", i);
|
||||
# srand(cycle * i);
|
||||
# size = 1 << 4; //((rand() % 10)+2);
|
||||
#
|
||||
# lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0;
|
||||
# for (lfs_size_t j = 0; j < size; j++) {
|
||||
# char c = 'a' + (rand() % 26);
|
||||
# char r;
|
||||
# lfs_file_read(&lfs, &file, &r, 1) => 1;
|
||||
# assert(r == c);
|
||||
# }
|
||||
#
|
||||
# lfs_file_close(&lfs, &file) => 0;
|
||||
# }
|
||||
# lfs_unmount(&lfs) => 0;
|
||||
#
|
||||
# cycle += 1;
|
||||
# }
|
||||
#
|
||||
#exhausted:
|
||||
# // should still be readable
|
||||
# lfs_mount(&lfs, &cfg) => 0;
|
||||
# for (uint32_t i = 0; i < FILES; i++) {
|
||||
# // check for errors
|
||||
# sprintf(path, "roadrunner/test%d", i);
|
||||
# lfs_stat(&lfs, path, &info) => 0;
|
||||
# }
|
||||
# lfs_unmount(&lfs) => 0;
|
||||
#
|
||||
# LFS_WARN("completed %d cycles", cycle);
|
||||
#
|
||||
# // check the wear on our block device
|
||||
# lfs_testbd_wear_t minwear = -1;
|
||||
# lfs_testbd_wear_t totalwear = 0;
|
||||
# lfs_testbd_wear_t maxwear = 0;
|
||||
# // skip 0 and 1 as superblock movement is intentionally avoided
|
||||
# for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
|
||||
# lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
|
||||
# printf("%08x: wear %d\n", b, wear);
|
||||
# assert(wear >= 0);
|
||||
# if (wear < minwear) {
|
||||
# minwear = wear;
|
||||
# }
|
||||
# if (wear > maxwear) {
|
||||
# maxwear = wear;
|
||||
# }
|
||||
# totalwear += wear;
|
||||
# }
|
||||
# lfs_testbd_wear_t avgwear = totalwear / LFS_BLOCK_COUNT;
|
||||
# LFS_WARN("max wear: %d cycles", maxwear);
|
||||
# LFS_WARN("avg wear: %d cycles", totalwear / LFS_BLOCK_COUNT);
|
||||
# LFS_WARN("min wear: %d cycles", minwear);
|
||||
#
|
||||
# // find standard deviation^2
|
||||
# lfs_testbd_wear_t dev2 = 0;
|
||||
# for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) {
|
||||
# lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b);
|
||||
# assert(wear >= 0);
|
||||
# lfs_testbd_swear_t diff = wear - avgwear;
|
||||
# dev2 += diff*diff;
|
||||
# }
|
||||
# dev2 /= totalwear;
|
||||
# LFS_WARN("std dev^2: %d", dev2);
|
||||
# assert(dev2 < 8);
|
||||
#'''
|
||||
|
||||
|
||||
Reference in New Issue
Block a user