trv: Adopted LFS3_t_STALE for marking block queue as stale
This solves the previous gc-needs-block-queue-so-we-can-clobber-block-
queue issue by adding an additional LFS3_t_STALE flag to indicate when
any block queues would be invalid.
So instead of clearing block queues in lfs3_alloc_ckpoint, we just set
LFS3_t_STALE, and any lfs3_trv_ts can clear their block queues in
lfs3_trv_read. This allows lfs3_mgc_ts to be allocated without a block
queue when doing any LFS3_M_*/LFS3_F_*/LFS3_GC_* work.
LFS3_t_STALE is set at the same time as LFS3_t_CKPOINT and LFS3_t_DIRTY,
but we need a separate bit so lfs3_trv_read can clear the flag after
flushing without losing ckpoint/dirty information.
---
Unfortunately, none of the stack-allocated lfs3_mgc_ts are on the stack
hot-path, so we don't immediate savings. But note the 2-words saved in
ctx when compiling in LFS3_GC mode:
code stack ctx
before: 35940 2280 660
after: 35944 (+0.0%) 2280 (+0.0%) 660 (+0.0%)
code stack ctx
gbmap before: 38916 2296 772
gbmap after: 38916 (+0.0%) 2296 (+0.0%) 772 (+0.0%)
code stack ctx
gc before: 36012 2280 776
gc after: 36016 (+0.0%) 2280 (+0.0%) 768 (-1.0%)
This commit is contained in:
+18
-18
@@ -57,7 +57,7 @@ code = '''
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_RELOOKAHEAD);
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
@@ -127,11 +127,11 @@ code = '''
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_RELOOKAHEAD);
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
|
||||
// run GC one step
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
assert(lfs3.handles == &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles == &lfs3.gc.t.h);
|
||||
|
||||
// mutate the filesystem
|
||||
lfs3_file_open(&lfs3, &file, "spider",
|
||||
@@ -143,7 +143,7 @@ code = '''
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
// run GC until our traversal is done
|
||||
while (lfs3.handles == &lfs3.gc.gc.t.h) {
|
||||
while (lfs3.handles == &lfs3.gc.t.h) {
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ code = '''
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_REGBMAP);
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
@@ -391,11 +391,11 @@ code = '''
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_REGBMAP);
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
|
||||
// run GC one step
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
assert(lfs3.handles == &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles == &lfs3.gc.t.h);
|
||||
|
||||
// mutate the filesystem
|
||||
lfs3_file_open(&lfs3, &file, "spider",
|
||||
@@ -407,7 +407,7 @@ code = '''
|
||||
lfs3_file_close(&lfs3, &file) => 0;
|
||||
|
||||
// run GC until our traversal is done
|
||||
while (lfs3.handles == &lfs3.gc.gc.t.h) {
|
||||
while (lfs3.handles == &lfs3.gc.t.h) {
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ code = '''
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_COMPACTMETA);
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
@@ -684,19 +684,19 @@ code = '''
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_COMPACTMETA);
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
|
||||
// run GC one traversal + one step
|
||||
while (true) {
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
|
||||
// internal traversal done?
|
||||
if (lfs3.handles != &lfs3.gc.gc.t.h) {
|
||||
if (lfs3.handles != &lfs3.gc.t.h) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
assert(lfs3.handles == &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles == &lfs3.gc.t.h);
|
||||
|
||||
// mutate the filesystem
|
||||
lfs3_file_rewind(&lfs3, &file) => 0;
|
||||
@@ -707,7 +707,7 @@ code = '''
|
||||
lfs3_file_sync(&lfs3, &file) => 0;
|
||||
|
||||
// run GC until our traversal is done (twice for compactmeta)
|
||||
while (lfs3.handles == &lfs3.gc.gc.t.h) {
|
||||
while (lfs3.handles == &lfs3.gc.t.h) {
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
}
|
||||
|
||||
@@ -811,7 +811,7 @@ code = '''
|
||||
struct lfs3_fsinfo fsinfo;
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_MKCONSISTENT);
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
|
||||
// run GC until we make progress
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
@@ -917,7 +917,7 @@ code = '''
|
||||
lfs3_fs_stat(&lfs3, &fsinfo) => 0;
|
||||
assert(fsinfo.flags & LFS3_I_MKCONSISTENT);
|
||||
#ifdef LFS3_GC
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
#endif
|
||||
|
||||
// call lfs3_fs_mkconsistent
|
||||
@@ -1021,9 +1021,9 @@ code = '''
|
||||
}
|
||||
|
||||
// run GC one step
|
||||
assert(lfs3.handles != &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles != &lfs3.gc.t.h);
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
assert(lfs3.handles == &lfs3.gc.gc.t.h);
|
||||
assert(lfs3.handles == &lfs3.gc.t.h);
|
||||
|
||||
// create the rest of the orphans after GC has started
|
||||
for (lfs3_size_t i = 0; i < ORPHANS; i++) {
|
||||
@@ -1045,7 +1045,7 @@ code = '''
|
||||
assert(fsinfo.flags & LFS3_I_MKCONSISTENT);
|
||||
|
||||
// run GC until our traversal is done
|
||||
while (lfs3.handles == &lfs3.gc.gc.t.h) {
|
||||
while (lfs3.handles == &lfs3.gc.t.h) {
|
||||
lfs3_fs_gc(&lfs3) => 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user