Added internal LFS_F_CANLOOKAHEAD flag
This is equivalent to the user-facing LFS_I_CANLOOKAHEAD flag, but
explicitly set in lfs_alloc/lfs_alloc_markfree, rather than being
implied.
Usually, I prefer implicit state, as this means less things that can
fall out-of-sync if there is a filesystem bug, but for
LFS_F_CANLOOKAHEAD explicit state might be warranted.
The main benefit is we can take advantage of the matching F/GC bit
patterns to simplify lfsr_fs_gc's progress checks.
This ends up saving a bit of code:
code stack
before: 36048 2696
after: 35988 (-0.2%) 2696 (+0.0%)
This commit is contained in:
@@ -6025,6 +6025,10 @@ static inline bool lfsr_f_hasorphans(uint32_t flags) {
|
||||
return flags & LFS_F_ORPHANS;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_canlookahead(uint32_t flags) {
|
||||
return flags & LFS_F_CANLOOKAHEAD;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isuncompacted(uint32_t flags) {
|
||||
return flags & LFS_F_UNCOMPACTED;
|
||||
}
|
||||
@@ -6038,12 +6042,6 @@ static bool lfsr_fs_isinconsistent(const lfs_t *lfs) {
|
||||
return lfsr_grm_count(lfs) > 0 || lfsr_f_hasorphans(lfs->flags);
|
||||
}
|
||||
|
||||
static bool lfsr_fs_canlookahead(const lfs_t *lfs) {
|
||||
return lfs->lookahead.size < lfs_min(
|
||||
8*lfs->cfg->lookahead_size,
|
||||
lfs->cfg->block_size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// opened mdir things ///
|
||||
@@ -8933,8 +8931,11 @@ static void lfs_alloc_markfree(lfs_t *lfs) {
|
||||
8*lfs->cfg->lookahead_size,
|
||||
lfs->lookahead.ckpoint);
|
||||
|
||||
// clear the canlookahead flag
|
||||
lfs->flags &= ~LFS_F_CANLOOKAHEAD;
|
||||
|
||||
// eagerly find the next free block so lookahead scans can make
|
||||
// the most progress
|
||||
// the most progress, this might reset the canlookahead flag
|
||||
lfs_alloc_findfree(lfs);
|
||||
}
|
||||
|
||||
@@ -8958,6 +8959,10 @@ static void lfs_alloc_inc(lfs_t *lfs) {
|
||||
// decrement size/ckpoint
|
||||
lfs->lookahead.size -= 1;
|
||||
lfs->lookahead.ckpoint -= 1;
|
||||
|
||||
// set the canlookahead flag, we can always make progress after
|
||||
// incrementing the lookahead buffer
|
||||
lfs->flags |= LFS_F_CANLOOKAHEAD;
|
||||
}
|
||||
|
||||
// find next free block in lookahead buffer, if there is one
|
||||
@@ -11812,7 +11817,12 @@ static int lfs_init(lfs_t *lfs, uint32_t flags,
|
||||
LFS_ASSERT(lfs->cfg->fragment_size <= lfs->cfg->block_size/4);
|
||||
|
||||
// setup flags
|
||||
lfs->flags = flags;
|
||||
lfs->flags = flags
|
||||
// lookahead buffer starts empty
|
||||
| LFS_F_CANLOOKAHEAD
|
||||
// default to assuming we need compaction somewhere, worst case
|
||||
// this just makes lfsr_fs_gc read more than is strictly needed
|
||||
| LFS_F_UNCOMPACTED;
|
||||
|
||||
// copy block_count so we can mutate it
|
||||
lfs->block_count = lfs->cfg->block_count;
|
||||
@@ -12536,10 +12546,6 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
lfsr_mid_rid(lfs, lfs->grm.mids[0]));
|
||||
}
|
||||
|
||||
// default to assuming we need a compaction somewhere, worst case this
|
||||
// just makes lfsr_fs_gc read more than is strictly needed
|
||||
lfs->flags |= LFS_F_UNCOMPACTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12732,10 +12738,10 @@ int lfsr_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo) {
|
||||
fsinfo->flags = lfs->flags & (
|
||||
LFS_I_RDONLY
|
||||
| LFS_I_CKPROGS
|
||||
| LFS_I_CANLOOKAHEAD
|
||||
| LFS_I_UNCOMPACTED);
|
||||
// some flags we calculate on demand
|
||||
fsinfo->flags |= (lfsr_fs_isinconsistent(lfs)) ? LFS_I_INCONSISTENT : 0;
|
||||
fsinfo->flags |= (lfsr_fs_canlookahead(lfs)) ? LFS_I_CANLOOKAHEAD : 0;
|
||||
|
||||
// return filesystem config, this may come from disk
|
||||
fsinfo->block_size = lfs->cfg->block_size;
|
||||
@@ -12994,9 +13000,10 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
||||
|
||||
// do we have any pending work?
|
||||
uint32_t pending = flags & (
|
||||
((lfsr_f_hasorphans(lfs->flags)) ? LFS_GC_MKCONSISTENT : 0)
|
||||
| ((lfsr_fs_canlookahead(lfs)) ? LFS_GC_LOOKAHEAD : 0)
|
||||
| ((lfsr_f_isuncompacted(lfs->flags)) ? LFS_GC_COMPACT : 0)
|
||||
((lfs->flags & (
|
||||
LFS_F_ORPHANS
|
||||
| LFS_F_CANLOOKAHEAD
|
||||
| LFS_F_UNCOMPACTED)) >> 16)
|
||||
| LFS_GC_CKMETA
|
||||
| LFS_GC_CKDATA);
|
||||
|
||||
@@ -13057,20 +13064,15 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
||||
lfsr_omdir_close(lfs, &lfs->gc.o.o);
|
||||
|
||||
// clear any pending flags we make progress on
|
||||
pending &= ~(
|
||||
((!lfsr_f_hasorphans(lfs->flags))
|
||||
? LFS_GC_MKCONSISTENT
|
||||
: 0)
|
||||
| ((!lfsr_fs_canlookahead(lfs))
|
||||
? LFS_GC_LOOKAHEAD
|
||||
: 0)
|
||||
| ((!lfsr_f_isuncompacted(lfs->flags))
|
||||
? LFS_GC_COMPACT
|
||||
: 0)
|
||||
pending &= (
|
||||
((lfs->flags & (
|
||||
LFS_F_ORPHANS
|
||||
| LFS_F_CANLOOKAHEAD
|
||||
| LFS_F_UNCOMPACTED)) >> 16)
|
||||
// only consider our filesystem checked if we
|
||||
// weren't mutated
|
||||
| ((!lfsr_f_isdirty(lfs->gc.o.o.flags)
|
||||
&& !lfsr_f_ismutated(lfs->gc.o.o.flags))
|
||||
| ((lfsr_f_isdirty(lfs->gc.o.o.flags)
|
||||
|| lfsr_f_ismutated(lfs->gc.o.o.flags))
|
||||
? LFS_GC_CKMETA | LFS_GC_CKDATA
|
||||
: 0));
|
||||
}
|
||||
|
||||
@@ -166,6 +166,8 @@ enum lfs_type {
|
||||
|
||||
// internally used flags
|
||||
#define LFS_F_ORPHANS 0x01000000 // Filesystem may have untracked orphans
|
||||
#define LFS_F_CANLOOKAHEAD \
|
||||
0x02000000 // Lookahead buffer is not full
|
||||
#define LFS_F_UNCOMPACTED \
|
||||
0x08000000 // Filesystem may have uncompacted metadata
|
||||
|
||||
|
||||
Reference in New Issue
Block a user