gc: Moved incremental gc behind ifdef LFS_GC
Incremental gc, being stateful and not gc-able (ironic), was always
going to need to be conditionally compilable.
This moves incremental gc behind the LFS_GC define, so that we can focus
on the "default" costs. This cuts lfs_t in nearly half!
lfs_t with LFS_GC: 308
lfs_t without LFS_C: 168 (-45.5%)
This does save less code than one might expect though. We still need
most of the internal traversal/gc logic for things like block allocation
and orphan cleanup, so most of the savings is limited to the RAM storing
the incremental state:
code stack ctx
before: 37916 2608 768
after with LFS_CFG: 37944 (+0.1%) 2608 (+0.0%) 768 (+0.0%)
after without LFS_CFG: 37796 (-0.3%) 2608 (+0.0%) 620 (-19.3%)
On the flip side, this does mean most of the incremental gc
functionality is still availables in the lfsr_traversal_t APIs.
Applications with more advanced gc use-cases may actually benefit from
_not_ enabling the incremental gc APIs, and instead use the
lfsr_traversal_t APIs directly.
This commit is contained in:
@@ -352,12 +352,15 @@ struct lfs_config {
|
||||
// can track 8 blocks.
|
||||
lfs_size_t lookahead_size;
|
||||
|
||||
#ifdef LFS_GC
|
||||
// Flags indicating what gc work to do during lfsr_gc calls.
|
||||
//
|
||||
// Defaults to LFS_GC_MKCONSISTENT + LFS_GC_LOOKAHEAD +
|
||||
// LFS_GC_COMPACT when zero.
|
||||
uint32_t gc_flags;
|
||||
#endif
|
||||
|
||||
#ifdef LFS_GC
|
||||
// Number of gc steps to perform in each call to lfsr_gc, with each
|
||||
// step being ~1 block of work.
|
||||
//
|
||||
@@ -369,6 +372,7 @@ struct lfs_config {
|
||||
//
|
||||
// Defaults to steps=1 when zero.
|
||||
lfs_soff_t gc_steps;
|
||||
#endif
|
||||
|
||||
// Threshold for metadata compaction during gc in bytes. Metadata logs
|
||||
// that exceed this threshold will be compacted during gc operations.
|
||||
@@ -879,12 +883,13 @@ typedef struct lfs {
|
||||
uint8_t grm_p[LFSR_GRM_DSIZE];
|
||||
uint8_t grm_d[LFSR_GRM_DSIZE];
|
||||
|
||||
// TODO allow compile time opt-out to reclaim RAM
|
||||
#ifdef LFS_GC
|
||||
struct {
|
||||
uint32_t flags;
|
||||
lfs_soff_t steps;
|
||||
lfsr_traversal_t t;
|
||||
} gc;
|
||||
#endif
|
||||
} lfs_t;
|
||||
|
||||
|
||||
@@ -1253,7 +1258,7 @@ int lfsr_traversal_rewind(lfs_t *lfs, lfsr_traversal_t *t);
|
||||
|
||||
/// Incremental gc operations ///
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
#ifdef LFS_GC
|
||||
// Perform any janitorial work that may be pending.
|
||||
//
|
||||
// The exact janitorial work depends on the configured flags and steps.
|
||||
@@ -1265,14 +1270,14 @@ int lfsr_traversal_rewind(lfs_t *lfs, lfsr_traversal_t *t);
|
||||
int lfsr_gc(lfs_t *lfs);
|
||||
#endif
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
#ifdef LFS_GC
|
||||
// Sets the gc flags.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfsr_gc_setflags(lfs_t *lfs, uint32_t flags);
|
||||
#endif
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
#ifdef LFS_GC
|
||||
// Sets the number of gc steps per lfsr_gc call, with each step being
|
||||
// ~1 block of work.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user