diff --git a/.travis.yml b/.travis.yml index 0a47a56b..e3f786b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ script: # run tests with a few different configurations - make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=1 -DLFS_CACHE_SIZE=4" - make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=512 -DLFS_CACHE_SIZE=512 -DLFS_BLOCK_CYCLES=16" - - make test QUIET=1 CFLAGS+="-DLFS_BLOCK_COUNT=1023 -DLFS_LOOKAHEAD=2048" + - make test QUIET=1 CFLAGS+="-DLFS_BLOCK_COUNT=1023 -DLFS_LOOKAHEAD_SIZE=256" - make clean test QUIET=1 CFLAGS+="-DLFS_INLINE_MAX=0" - make clean test QUIET=1 CFLAGS+="-DLFS_NO_INTRINSICS" diff --git a/README.md b/README.md index 623ba0ae..45be6f4b 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,8 @@ const struct lfs_config cfg = { .prog_size = 16, .block_size = 4096, .block_count = 128, - .lookahead = 128, + .cache_size = 16, + .lookahead_size = 16, }; // entry point diff --git a/lfs.c b/lfs.c index 6f7813f8..8759f834 100644 --- a/lfs.c +++ b/lfs.c @@ -462,11 +462,11 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { lfs->free.off = (lfs->free.off + lfs->free.size) % lfs->cfg->block_count; - lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->free.ack); + lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, lfs->free.ack); lfs->free.i = 0; // find mask of free blocks from tree - memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); + memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); int err = lfs_fs_traverse(lfs, lfs_alloc_lookahead, lfs); if (err) { return err; @@ -3041,12 +3041,12 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { lfs_cache_zero(lfs, &lfs->pcache); // setup lookahead, must be multiple of 32-bits - LFS_ASSERT(lfs->cfg->lookahead % 32 == 0); - LFS_ASSERT(lfs->cfg->lookahead > 0); + LFS_ASSERT(lfs->cfg->lookahead_size % 4 == 0); + LFS_ASSERT(lfs->cfg->lookahead_size > 0); if (lfs->cfg->lookahead_buffer) { lfs->free.buffer = lfs->cfg->lookahead_buffer; } else { - lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8); + lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead_size); if (!lfs->free.buffer) { err = LFS_ERR_NOMEM; goto cleanup; @@ -3112,9 +3112,10 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { } // create free lookahead - memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); + memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); lfs->free.off = 0; - lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count); + lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, + lfs->cfg->block_count); lfs->free.i = 0; lfs_alloc_ack(lfs); diff --git a/lfs.h b/lfs.h index f4020fa5..dae59edb 100644 --- a/lfs.h +++ b/lfs.h @@ -177,39 +177,41 @@ struct lfs_config { lfs_size_t prog_size; // Size of an erasable block. This does not impact ram consumption and - // may be larger than the physical erase size. However, this should be - // kept small as each file currently takes up an entire block. - // Must be a multiple of the read, program, and cache sizes. + // may be larger than the physical erase size. However, non-inlined files + // take up at minimum one block. Must be a multiple of the read + // and program sizes. lfs_size_t block_size; // Number of erasable blocks on the device. lfs_size_t block_count; // Number of erase cycles before we should move data to another block. - // May be zero to never move data, in which case no block-level - // wear-leveling is performed. + // May be zero, in which case no block-level wear-leveling is performed. uint32_t block_cycles; // Size of block caches. Each cache buffers a portion of a block in RAM. - // This determines the size of the read cache, the program cache, and a + // The littlefs needs a read cache, a program cache, and one additional // cache per file. Larger caches can improve performance by storing more - // data. Must be a multiple of the read and program sizes. + // data and reducing the number of disk accesses. Must be a multiple of + // the read and program sizes, and a factor of the block size. lfs_size_t cache_size; - // Number of blocks to lookahead during block allocation. A larger - // lookahead reduces the number of passes required to allocate a block. - // The lookahead buffer requires only 1 bit per block so it can be quite - // large with little ram impact. Should be a multiple of 32. - lfs_size_t lookahead; + // Size of the lookahead buffer in bytes. A larger lookahead buffer + // increases the number of blocks found during an allocation pass. The + // lookahead buffer is stored as a compact bitmap, so each byte of RAM + // can track 8 blocks. Must be a multiple of 4. + lfs_size_t lookahead_size; - // Optional, statically allocated read buffer. Must be read sized. + // Optional statically allocated read buffer. Must be cache_size. + // By default lfs_malloc is used to allocate this buffer. void *read_buffer; - // Optional, statically allocated program buffer. Must be program sized. + // Optional statically allocated program buffer. Must be cache_size. + // By default lfs_malloc is used to allocate this buffer. void *prog_buffer; - // Optional, statically allocated lookahead buffer. Must be 1 bit per - // lookahead block. + // Optional statically allocated program buffer. Must be lookahead_size. + // By default lfs_malloc is used to allocate this buffer. void *lookahead_buffer; // Optional upper limit on length of file names in bytes. No downside for @@ -266,11 +268,11 @@ struct lfs_attr { // Optional configuration provided during lfs_file_opencfg struct lfs_file_config { - // Optional, statically allocated buffer for files. Must be program sized. - // If NULL, malloc will be used by default. + // Optional statically allocated file buffer. Must be cache_size. + // By default lfs_malloc is used to allocate this buffer. void *buffer; - // Optional, linked list of custom attributes related to the file. If the + // Optional linked list of custom attributes related to the file. If the // file is opened with read access, the attributes will be read from // during the open call. If the file is opened with write access, the // attributes will be written to disk every file sync or close. This diff --git a/tests/template.fmt b/tests/template.fmt index 85759db6..7fdec7c9 100644 --- a/tests/template.fmt +++ b/tests/template.fmt @@ -85,8 +85,8 @@ uintmax_t test; #define LFS_CACHE_SIZE 64 #endif -#ifndef LFS_LOOKAHEAD -#define LFS_LOOKAHEAD 128 +#ifndef LFS_LOOKAHEAD_SIZE +#define LFS_LOOKAHEAD_SIZE 16 #endif const struct lfs_config cfg = {{ @@ -96,13 +96,13 @@ const struct lfs_config cfg = {{ .erase = &lfs_emubd_erase, .sync = &lfs_emubd_sync, - .read_size = LFS_READ_SIZE, - .prog_size = LFS_PROG_SIZE, - .block_size = LFS_BLOCK_SIZE, - .block_count = LFS_BLOCK_COUNT, - .block_cycles = LFS_BLOCK_CYCLES, - .cache_size = LFS_CACHE_SIZE, - .lookahead = LFS_LOOKAHEAD, + .read_size = LFS_READ_SIZE, + .prog_size = LFS_PROG_SIZE, + .block_size = LFS_BLOCK_SIZE, + .block_count = LFS_BLOCK_COUNT, + .block_cycles = LFS_BLOCK_CYCLES, + .cache_size = LFS_CACHE_SIZE, + .lookahead_size = LFS_LOOKAHEAD_SIZE, }};