Compare commits

...

3 Commits

Author SHA1 Message Date
Christopher Haster
d804c2d3b7 Added scripts/code_size.py, for more in-depth code-size reporting
Inspired by Linux's Bloat-O-Meter, code_size.py wraps nm to provide
function-level code size, and supports detailed comparison between
different builds.

One difference is that code_size.py invokes littlefs's build system
similarly to test.py, creating a duplicate build in the "sizes"
directory. This makes it easy to monitor a cross-compiled build size
while simultaneously testing on the host machine.
2020-12-19 18:49:57 -06:00
Christopher Haster
1a59954ec6 Merge pull request #495 from littlefs-project/devel
Minor release: v2.3
2020-12-07 20:50:31 -06:00
Christopher Haster
6a7012774d Renamed internal lfs_*raw -> lfs_raw* functions
- Prefixing with raw is slightly more readable, follows
  common-prefix rule
- Matches existing raw prefixes in testbd
2020-12-06 00:26:24 -06:00
3 changed files with 419 additions and 85 deletions

View File

@@ -6,6 +6,7 @@ endif
CC ?= gcc CC ?= gcc
AR ?= ar AR ?= ar
SIZE ?= size SIZE ?= size
NM ?= nm
SRC += $(wildcard *.c bd/*.c) SRC += $(wildcard *.c bd/*.c)
OBJ := $(SRC:.c=.o) OBJ := $(SRC:.c=.o)
@@ -29,6 +30,7 @@ override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
ifdef VERBOSE ifdef VERBOSE
override TFLAGS += -v override TFLAGS += -v
override SFLAGS += -v
endif endif
@@ -39,6 +41,9 @@ asm: $(ASM)
size: $(OBJ) size: $(OBJ)
$(SIZE) -t $^ $(SIZE) -t $^
code_size:
./scripts/code_size.py $(SFLAGS)
test: test:
./scripts/test.py $(TFLAGS) ./scripts/test.py $(TFLAGS)
.SECONDEXPANSION: .SECONDEXPANSION:
@@ -65,3 +70,4 @@ clean:
rm -f $(DEP) rm -f $(DEP)
rm -f $(ASM) rm -f $(ASM)
rm -f tests/*.toml.* rm -f tests/*.toml.*
rm -f sizes/*

170
lfs.c
View File

@@ -459,9 +459,9 @@ static int lfs_dir_compact(lfs_t *lfs,
lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount, lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
lfs_mdir_t *source, uint16_t begin, uint16_t end); lfs_mdir_t *source, uint16_t begin, uint16_t end);
static lfs_ssize_t lfs_file_writeraw(lfs_t *lfs, lfs_file_t *file, static lfs_ssize_t lfs_file_rawwrite(lfs_t *lfs, lfs_file_t *file,
const void *buffer, lfs_size_t size); const void *buffer, lfs_size_t size);
static int lfs_file_syncraw(lfs_t *lfs, lfs_file_t *file); static int lfs_file_rawsync(lfs_t *lfs, lfs_file_t *file);
static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file); static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file);
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file); static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file);
@@ -482,20 +482,20 @@ static int lfs1_traverse(lfs_t *lfs,
int (*cb)(void*, lfs_block_t), void *data); int (*cb)(void*, lfs_block_t), void *data);
#endif #endif
static int lfs_dir_rewindraw(lfs_t *lfs, lfs_dir_t *dir); static int lfs_dir_rawrewind(lfs_t *lfs, lfs_dir_t *dir);
static lfs_ssize_t lfs_file_readraw(lfs_t *lfs, lfs_file_t *file, static lfs_ssize_t lfs_file_rawread(lfs_t *lfs, lfs_file_t *file,
void *buffer, lfs_size_t size); void *buffer, lfs_size_t size);
static int lfs_file_closeraw(lfs_t *lfs, lfs_file_t *file); static int lfs_file_rawclose(lfs_t *lfs, lfs_file_t *file);
static lfs_soff_t lfs_file_sizeraw(lfs_t *lfs, lfs_file_t *file); static lfs_soff_t lfs_file_rawsize(lfs_t *lfs, lfs_file_t *file);
static lfs_ssize_t lfs_fs_sizeraw(lfs_t *lfs); static lfs_ssize_t lfs_fs_rawsize(lfs_t *lfs);
static int lfs_fs_traverseraw(lfs_t *lfs, static int lfs_fs_rawtraverse(lfs_t *lfs,
int (*cb)(void *data, lfs_block_t block), void *data, int (*cb)(void *data, lfs_block_t block), void *data,
bool includeorphans); bool includeorphans);
static int lfs_deinit(lfs_t *lfs); static int lfs_deinit(lfs_t *lfs);
static int lfs_unmountraw(lfs_t *lfs); static int lfs_rawunmount(lfs_t *lfs);
/// Block allocator /// /// Block allocator ///
@@ -567,7 +567,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
// find mask of free blocks from tree // find mask of free blocks from tree
memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size);
int err = lfs_fs_traverseraw(lfs, lfs_alloc_lookahead, lfs, true); int err = lfs_fs_rawtraverse(lfs, lfs_alloc_lookahead, lfs, true);
if (err) { if (err) {
lfs_alloc_drop(lfs); lfs_alloc_drop(lfs);
return err; return err;
@@ -1626,7 +1626,7 @@ static int lfs_dir_compact(lfs_t *lfs,
if (lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) == 0) { if (lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) == 0) {
// oh no! we're writing too much to the superblock, // oh no! we're writing too much to the superblock,
// should we expand? // should we expand?
lfs_ssize_t res = lfs_fs_sizeraw(lfs); lfs_ssize_t res = lfs_fs_rawsize(lfs);
if (res < 0) { if (res < 0) {
return res; return res;
} }
@@ -2011,7 +2011,7 @@ compact:
/// Top level directory operations /// /// Top level directory operations ///
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_mkdirraw(lfs_t *lfs, const char *path) { static int lfs_rawmkdir(lfs_t *lfs, const char *path) {
// deorphan if we haven't yet, needed at most once after poweron // deorphan if we haven't yet, needed at most once after poweron
int err = lfs_fs_forceconsistency(lfs); int err = lfs_fs_forceconsistency(lfs);
if (err) { if (err) {
@@ -2101,7 +2101,7 @@ static int lfs_mkdirraw(lfs_t *lfs, const char *path) {
} }
#endif #endif
static int lfs_dir_openraw(lfs_t *lfs, lfs_dir_t *dir, const char *path) { static int lfs_dir_rawopen(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
lfs_stag_t tag = lfs_dir_find(lfs, &dir->m, &path, NULL); lfs_stag_t tag = lfs_dir_find(lfs, &dir->m, &path, NULL);
if (tag < 0) { if (tag < 0) {
return tag; return tag;
@@ -2145,14 +2145,14 @@ static int lfs_dir_openraw(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
return 0; return 0;
} }
static int lfs_dir_closeraw(lfs_t *lfs, lfs_dir_t *dir) { static int lfs_dir_rawclose(lfs_t *lfs, lfs_dir_t *dir) {
// remove from list of mdirs // remove from list of mdirs
lfs_mlist_remove(lfs, (struct lfs_mlist *)dir); lfs_mlist_remove(lfs, (struct lfs_mlist *)dir);
return 0; return 0;
} }
static int lfs_dir_readraw(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { static int lfs_dir_rawread(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) {
memset(info, 0, sizeof(*info)); memset(info, 0, sizeof(*info));
// special offset for '.' and '..' // special offset for '.' and '..'
@@ -2197,9 +2197,9 @@ static int lfs_dir_readraw(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) {
return true; return true;
} }
static int lfs_dir_seekraw(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { static int lfs_dir_rawseek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) {
// simply walk from head dir // simply walk from head dir
int err = lfs_dir_rewindraw(lfs, dir); int err = lfs_dir_rawrewind(lfs, dir);
if (err) { if (err) {
return err; return err;
} }
@@ -2234,12 +2234,12 @@ static int lfs_dir_seekraw(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) {
return 0; return 0;
} }
static lfs_soff_t lfs_dir_tellraw(lfs_t *lfs, lfs_dir_t *dir) { static lfs_soff_t lfs_dir_rawtell(lfs_t *lfs, lfs_dir_t *dir) {
(void)lfs; (void)lfs;
return dir->pos; return dir->pos;
} }
static int lfs_dir_rewindraw(lfs_t *lfs, lfs_dir_t *dir) { static int lfs_dir_rawrewind(lfs_t *lfs, lfs_dir_t *dir) {
// reload the head dir // reload the head dir
int err = lfs_dir_fetch(lfs, &dir->m, dir->head); int err = lfs_dir_fetch(lfs, &dir->m, dir->head);
if (err) { if (err) {
@@ -2445,7 +2445,7 @@ static int lfs_ctz_traverse(lfs_t *lfs,
/// Top level file operations /// /// Top level file operations ///
static int lfs_file_opencfgraw(lfs_t *lfs, lfs_file_t *file, static int lfs_file_rawopencfg(lfs_t *lfs, lfs_file_t *file,
const char *path, int flags, const char *path, int flags,
const struct lfs_file_config *cfg) { const struct lfs_file_config *cfg) {
#ifndef LFS_READONLY #ifndef LFS_READONLY
@@ -2604,20 +2604,20 @@ cleanup:
#ifndef LFS_READONLY #ifndef LFS_READONLY
file->flags |= LFS_F_ERRED; file->flags |= LFS_F_ERRED;
#endif #endif
lfs_file_closeraw(lfs, file); lfs_file_rawclose(lfs, file);
return err; return err;
} }
static int lfs_file_openraw(lfs_t *lfs, lfs_file_t *file, static int lfs_file_rawopen(lfs_t *lfs, lfs_file_t *file,
const char *path, int flags) { const char *path, int flags) {
static const struct lfs_file_config defaults = {0}; static const struct lfs_file_config defaults = {0};
int err = lfs_file_opencfgraw(lfs, file, path, flags, &defaults); int err = lfs_file_rawopencfg(lfs, file, path, flags, &defaults);
return err; return err;
} }
static int lfs_file_closeraw(lfs_t *lfs, lfs_file_t *file) { static int lfs_file_rawclose(lfs_t *lfs, lfs_file_t *file) {
#ifndef LFS_READONLY #ifndef LFS_READONLY
int err = lfs_file_syncraw(lfs, file); int err = lfs_file_rawsync(lfs, file);
#else #else
int err = 0; int err = 0;
#endif #endif
@@ -2746,12 +2746,12 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
// copy over a byte at a time, leave it up to caching // copy over a byte at a time, leave it up to caching
// to make this efficient // to make this efficient
uint8_t data; uint8_t data;
lfs_ssize_t res = lfs_file_readraw(lfs, &orig, &data, 1); lfs_ssize_t res = lfs_file_rawread(lfs, &orig, &data, 1);
if (res < 0) { if (res < 0) {
return res; return res;
} }
res = lfs_file_writeraw(lfs, file, &data, 1); res = lfs_file_rawwrite(lfs, file, &data, 1);
if (res < 0) { if (res < 0) {
return res; return res;
} }
@@ -2800,7 +2800,7 @@ relocate:
#endif #endif
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_file_syncraw(lfs_t *lfs, lfs_file_t *file) { static int lfs_file_rawsync(lfs_t *lfs, lfs_file_t *file) {
if (file->flags & LFS_F_ERRED) { if (file->flags & LFS_F_ERRED) {
// it's not safe to do anything if our file errored // it's not safe to do anything if our file errored
return 0; return 0;
@@ -2852,7 +2852,7 @@ static int lfs_file_syncraw(lfs_t *lfs, lfs_file_t *file) {
} }
#endif #endif
static lfs_ssize_t lfs_file_readraw(lfs_t *lfs, lfs_file_t *file, static lfs_ssize_t lfs_file_rawread(lfs_t *lfs, lfs_file_t *file,
void *buffer, lfs_size_t size) { void *buffer, lfs_size_t size) {
LFS_ASSERT((file->flags & LFS_O_RDONLY) == LFS_O_RDONLY); LFS_ASSERT((file->flags & LFS_O_RDONLY) == LFS_O_RDONLY);
@@ -2926,7 +2926,7 @@ static lfs_ssize_t lfs_file_readraw(lfs_t *lfs, lfs_file_t *file,
} }
#ifndef LFS_READONLY #ifndef LFS_READONLY
static lfs_ssize_t lfs_file_writeraw(lfs_t *lfs, lfs_file_t *file, static lfs_ssize_t lfs_file_rawwrite(lfs_t *lfs, lfs_file_t *file,
const void *buffer, lfs_size_t size) { const void *buffer, lfs_size_t size) {
LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY); LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY);
@@ -2956,7 +2956,7 @@ static lfs_ssize_t lfs_file_writeraw(lfs_t *lfs, lfs_file_t *file,
file->pos = file->ctz.size; file->pos = file->ctz.size;
while (file->pos < pos) { while (file->pos < pos) {
lfs_ssize_t res = lfs_file_writeraw(lfs, file, &(uint8_t){0}, 1); lfs_ssize_t res = lfs_file_rawwrite(lfs, file, &(uint8_t){0}, 1);
if (res < 0) { if (res < 0) {
return res; return res;
} }
@@ -3046,7 +3046,7 @@ relocate:
} }
#endif #endif
static lfs_soff_t lfs_file_seekraw(lfs_t *lfs, lfs_file_t *file, static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
lfs_soff_t off, int whence) { lfs_soff_t off, int whence) {
#ifndef LFS_READONLY #ifndef LFS_READONLY
// write out everything beforehand, may be noop if rdonly // write out everything beforehand, may be noop if rdonly
@@ -3077,7 +3077,7 @@ static lfs_soff_t lfs_file_seekraw(lfs_t *lfs, lfs_file_t *file,
} }
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_file_truncateraw(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { static int lfs_file_rawtruncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY); LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY);
if (size > LFS_FILE_MAX) { if (size > LFS_FILE_MAX) {
@@ -3085,7 +3085,7 @@ static int lfs_file_truncateraw(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
} }
lfs_off_t pos = file->pos; lfs_off_t pos = file->pos;
lfs_off_t oldsize = lfs_file_sizeraw(lfs, file); lfs_off_t oldsize = lfs_file_rawsize(lfs, file);
if (size < oldsize) { if (size < oldsize) {
// need to flush since directly changing metadata // need to flush since directly changing metadata
int err = lfs_file_flush(lfs, file); int err = lfs_file_flush(lfs, file);
@@ -3107,7 +3107,7 @@ static int lfs_file_truncateraw(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
} else if (size > oldsize) { } else if (size > oldsize) {
// flush+seek if not already at end // flush+seek if not already at end
if (file->pos != oldsize) { if (file->pos != oldsize) {
lfs_soff_t res = lfs_file_seekraw(lfs, file, 0, LFS_SEEK_END); lfs_soff_t res = lfs_file_rawseek(lfs, file, 0, LFS_SEEK_END);
if (res < 0) { if (res < 0) {
return (int)res; return (int)res;
} }
@@ -3115,7 +3115,7 @@ static int lfs_file_truncateraw(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
// fill with zeros // fill with zeros
while (file->pos < size) { while (file->pos < size) {
lfs_ssize_t res = lfs_file_writeraw(lfs, file, &(uint8_t){0}, 1); lfs_ssize_t res = lfs_file_rawwrite(lfs, file, &(uint8_t){0}, 1);
if (res < 0) { if (res < 0) {
return (int)res; return (int)res;
} }
@@ -3123,7 +3123,7 @@ static int lfs_file_truncateraw(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
} }
// restore pos // restore pos
lfs_soff_t res = lfs_file_seekraw(lfs, file, pos, LFS_SEEK_SET); lfs_soff_t res = lfs_file_rawseek(lfs, file, pos, LFS_SEEK_SET);
if (res < 0) { if (res < 0) {
return (int)res; return (int)res;
} }
@@ -3132,13 +3132,13 @@ static int lfs_file_truncateraw(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
} }
#endif #endif
static lfs_soff_t lfs_file_tellraw(lfs_t *lfs, lfs_file_t *file) { static lfs_soff_t lfs_file_rawtell(lfs_t *lfs, lfs_file_t *file) {
(void)lfs; (void)lfs;
return file->pos; return file->pos;
} }
static int lfs_file_rewindraw(lfs_t *lfs, lfs_file_t *file) { static int lfs_file_rawrewind(lfs_t *lfs, lfs_file_t *file) {
lfs_soff_t res = lfs_file_seekraw(lfs, file, 0, LFS_SEEK_SET); lfs_soff_t res = lfs_file_rawseek(lfs, file, 0, LFS_SEEK_SET);
if (res < 0) { if (res < 0) {
return (int)res; return (int)res;
} }
@@ -3146,7 +3146,7 @@ static int lfs_file_rewindraw(lfs_t *lfs, lfs_file_t *file) {
return 0; return 0;
} }
static lfs_soff_t lfs_file_sizeraw(lfs_t *lfs, lfs_file_t *file) { static lfs_soff_t lfs_file_rawsize(lfs_t *lfs, lfs_file_t *file) {
(void)lfs; (void)lfs;
#ifndef LFS_READONLY #ifndef LFS_READONLY
@@ -3160,7 +3160,7 @@ static lfs_soff_t lfs_file_sizeraw(lfs_t *lfs, lfs_file_t *file) {
/// General fs operations /// /// General fs operations ///
static int lfs_statraw(lfs_t *lfs, const char *path, struct lfs_info *info) { static int lfs_rawstat(lfs_t *lfs, const char *path, struct lfs_info *info) {
lfs_mdir_t cwd; lfs_mdir_t cwd;
lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL);
if (tag < 0) { if (tag < 0) {
@@ -3171,7 +3171,7 @@ static int lfs_statraw(lfs_t *lfs, const char *path, struct lfs_info *info) {
} }
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_removeraw(lfs_t *lfs, const char *path) { static int lfs_rawremove(lfs_t *lfs, const char *path) {
// deorphan if we haven't yet, needed at most once after poweron // deorphan if we haven't yet, needed at most once after poweron
int err = lfs_fs_forceconsistency(lfs); int err = lfs_fs_forceconsistency(lfs);
if (err) { if (err) {
@@ -3244,7 +3244,7 @@ static int lfs_removeraw(lfs_t *lfs, const char *path) {
#endif #endif
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_renameraw(lfs_t *lfs, const char *oldpath, const char *newpath) { static int lfs_rawrename(lfs_t *lfs, const char *oldpath, const char *newpath) {
// deorphan if we haven't yet, needed at most once after poweron // deorphan if we haven't yet, needed at most once after poweron
int err = lfs_fs_forceconsistency(lfs); int err = lfs_fs_forceconsistency(lfs);
if (err) { if (err) {
@@ -3372,7 +3372,7 @@ static int lfs_renameraw(lfs_t *lfs, const char *oldpath, const char *newpath) {
} }
#endif #endif
static lfs_ssize_t lfs_getattrraw(lfs_t *lfs, const char *path, static lfs_ssize_t lfs_rawgetattr(lfs_t *lfs, const char *path,
uint8_t type, void *buffer, lfs_size_t size) { uint8_t type, void *buffer, lfs_size_t size) {
lfs_mdir_t cwd; lfs_mdir_t cwd;
lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL);
@@ -3430,7 +3430,7 @@ static int lfs_commitattr(lfs_t *lfs, const char *path,
#endif #endif
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_setattrraw(lfs_t *lfs, const char *path, static int lfs_rawsetattr(lfs_t *lfs, const char *path,
uint8_t type, const void *buffer, lfs_size_t size) { uint8_t type, const void *buffer, lfs_size_t size) {
if (size > lfs->attr_max) { if (size > lfs->attr_max) {
return LFS_ERR_NOSPC; return LFS_ERR_NOSPC;
@@ -3441,7 +3441,7 @@ static int lfs_setattrraw(lfs_t *lfs, const char *path,
#endif #endif
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_removeattrraw(lfs_t *lfs, const char *path, uint8_t type) { static int lfs_rawremoveattr(lfs_t *lfs, const char *path, uint8_t type) {
return lfs_commitattr(lfs, path, type, NULL, 0x3ff); return lfs_commitattr(lfs, path, type, NULL, 0x3ff);
} }
#endif #endif
@@ -3573,7 +3573,7 @@ static int lfs_deinit(lfs_t *lfs) {
} }
#ifndef LFS_READONLY #ifndef LFS_READONLY
static int lfs_formatraw(lfs_t *lfs, const struct lfs_config *cfg) { static int lfs_rawformat(lfs_t *lfs, const struct lfs_config *cfg) {
int err = 0; int err = 0;
{ {
err = lfs_init(lfs, cfg); err = lfs_init(lfs, cfg);
@@ -3638,7 +3638,7 @@ cleanup:
} }
#endif #endif
static int lfs_mountraw(lfs_t *lfs, const struct lfs_config *cfg) { static int lfs_rawmount(lfs_t *lfs, const struct lfs_config *cfg) {
int err = lfs_init(lfs, cfg); int err = lfs_init(lfs, cfg);
if (err) { if (err) {
return err; return err;
@@ -3761,17 +3761,17 @@ static int lfs_mountraw(lfs_t *lfs, const struct lfs_config *cfg) {
return 0; return 0;
cleanup: cleanup:
lfs_unmountraw(lfs); lfs_rawunmount(lfs);
return err; return err;
} }
static int lfs_unmountraw(lfs_t *lfs) { static int lfs_rawunmount(lfs_t *lfs) {
return lfs_deinit(lfs); return lfs_deinit(lfs);
} }
/// Filesystem filesystem operations /// /// Filesystem filesystem operations ///
int lfs_fs_traverseraw(lfs_t *lfs, int lfs_fs_rawtraverse(lfs_t *lfs,
int (*cb)(void *data, lfs_block_t block), void *data, int (*cb)(void *data, lfs_block_t block), void *data,
bool includeorphans) { bool includeorphans) {
// iterate over metadata pairs // iterate over metadata pairs
@@ -4201,9 +4201,9 @@ static int lfs_fs_size_count(void *p, lfs_block_t block) {
return 0; return 0;
} }
static lfs_ssize_t lfs_fs_sizeraw(lfs_t *lfs) { static lfs_ssize_t lfs_fs_rawsize(lfs_t *lfs) {
lfs_size_t size = 0; lfs_size_t size = 0;
int err = lfs_fs_traverseraw(lfs, lfs_fs_size_count, &size, false); int err = lfs_fs_rawtraverse(lfs, lfs_fs_size_count, &size, false);
if (err) { if (err) {
return err; return err;
} }
@@ -4632,7 +4632,7 @@ static int lfs1_unmount(lfs_t *lfs) {
} }
/// v1 migration /// /// v1 migration ///
static int lfs_migrateraw(lfs_t *lfs, const struct lfs_config *cfg) { static int lfs_rawmigrate(lfs_t *lfs, const struct lfs_config *cfg) {
struct lfs1 lfs1; struct lfs1 lfs1;
int err = lfs1_mount(lfs, &lfs1, cfg); int err = lfs1_mount(lfs, &lfs1, cfg);
if (err) { if (err) {
@@ -4895,7 +4895,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer,
cfg->name_max, cfg->file_max, cfg->attr_max); cfg->name_max, cfg->file_max, cfg->attr_max);
err = lfs_formatraw(lfs, cfg); err = lfs_rawformat(lfs, cfg);
LFS_TRACE("lfs_format -> %d", err); LFS_TRACE("lfs_format -> %d", err);
LFS_UNLOCK(cfg); LFS_UNLOCK(cfg);
@@ -4925,7 +4925,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer,
cfg->name_max, cfg->file_max, cfg->attr_max); cfg->name_max, cfg->file_max, cfg->attr_max);
err = lfs_mountraw(lfs, cfg); err = lfs_rawmount(lfs, cfg);
LFS_TRACE("lfs_mount -> %d", err); LFS_TRACE("lfs_mount -> %d", err);
LFS_UNLOCK(cfg); LFS_UNLOCK(cfg);
@@ -4939,7 +4939,7 @@ int lfs_unmount(lfs_t *lfs) {
} }
LFS_TRACE("lfs_unmount(%p)", (void*)lfs); LFS_TRACE("lfs_unmount(%p)", (void*)lfs);
err = lfs_unmountraw(lfs); err = lfs_rawunmount(lfs);
LFS_TRACE("lfs_unmount -> %d", err); LFS_TRACE("lfs_unmount -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -4954,7 +4954,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
} }
LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path); LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path);
err = lfs_removeraw(lfs, path); err = lfs_rawremove(lfs, path);
LFS_TRACE("lfs_remove -> %d", err); LFS_TRACE("lfs_remove -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -4970,7 +4970,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
} }
LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath); LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath);
err = lfs_renameraw(lfs, oldpath, newpath); err = lfs_rawrename(lfs, oldpath, newpath);
LFS_TRACE("lfs_rename -> %d", err); LFS_TRACE("lfs_rename -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -4985,7 +4985,7 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
} }
LFS_TRACE("lfs_stat(%p, \"%s\", %p)", (void*)lfs, path, (void*)info); LFS_TRACE("lfs_stat(%p, \"%s\", %p)", (void*)lfs, path, (void*)info);
err = lfs_statraw(lfs, path, info); err = lfs_rawstat(lfs, path, info);
LFS_TRACE("lfs_stat -> %d", err); LFS_TRACE("lfs_stat -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5001,7 +5001,7 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
LFS_TRACE("lfs_getattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", LFS_TRACE("lfs_getattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")",
(void*)lfs, path, type, buffer, size); (void*)lfs, path, type, buffer, size);
lfs_ssize_t res = lfs_getattrraw(lfs, path, type, buffer, size); lfs_ssize_t res = lfs_rawgetattr(lfs, path, type, buffer, size);
LFS_TRACE("lfs_getattr -> %"PRId32, res); LFS_TRACE("lfs_getattr -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5018,7 +5018,7 @@ int lfs_setattr(lfs_t *lfs, const char *path,
LFS_TRACE("lfs_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", LFS_TRACE("lfs_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")",
(void*)lfs, path, type, buffer, size); (void*)lfs, path, type, buffer, size);
err = lfs_setattrraw(lfs, path, type, buffer, size); err = lfs_rawsetattr(lfs, path, type, buffer, size);
LFS_TRACE("lfs_setattr -> %d", err); LFS_TRACE("lfs_setattr -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5034,7 +5034,7 @@ int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type) {
} }
LFS_TRACE("lfs_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs, path, type); LFS_TRACE("lfs_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs, path, type);
err = lfs_removeattrraw(lfs, path, type); err = lfs_rawremoveattr(lfs, path, type);
LFS_TRACE("lfs_removeattr -> %d", err); LFS_TRACE("lfs_removeattr -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5051,7 +5051,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, const char *path, int flags) {
(void*)lfs, (void*)file, path, flags); (void*)lfs, (void*)file, path, flags);
LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
err = lfs_file_openraw(lfs, file, path, flags); err = lfs_file_rawopen(lfs, file, path, flags);
LFS_TRACE("lfs_file_open -> %d", err); LFS_TRACE("lfs_file_open -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5071,7 +5071,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
(void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count); (void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count);
LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
err = lfs_file_opencfgraw(lfs, file, path, flags, cfg); err = lfs_file_rawopencfg(lfs, file, path, flags, cfg);
LFS_TRACE("lfs_file_opencfg -> %d", err); LFS_TRACE("lfs_file_opencfg -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5086,7 +5086,7 @@ int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
LFS_TRACE("lfs_file_close(%p, %p)", (void*)lfs, (void*)file); LFS_TRACE("lfs_file_close(%p, %p)", (void*)lfs, (void*)file);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
err = lfs_file_closeraw(lfs, file); err = lfs_file_rawclose(lfs, file);
LFS_TRACE("lfs_file_close -> %d", err); LFS_TRACE("lfs_file_close -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5102,7 +5102,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
LFS_TRACE("lfs_file_sync(%p, %p)", (void*)lfs, (void*)file); LFS_TRACE("lfs_file_sync(%p, %p)", (void*)lfs, (void*)file);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
err = lfs_file_syncraw(lfs, file); err = lfs_file_rawsync(lfs, file);
LFS_TRACE("lfs_file_sync -> %d", err); LFS_TRACE("lfs_file_sync -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5120,7 +5120,7 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
(void*)lfs, (void*)file, buffer, size); (void*)lfs, (void*)file, buffer, size);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
lfs_ssize_t res = lfs_file_readraw(lfs, file, buffer, size); lfs_ssize_t res = lfs_file_rawread(lfs, file, buffer, size);
LFS_TRACE("lfs_file_read -> %"PRId32, res); LFS_TRACE("lfs_file_read -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5138,7 +5138,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
(void*)lfs, (void*)file, buffer, size); (void*)lfs, (void*)file, buffer, size);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
lfs_ssize_t res = lfs_file_writeraw(lfs, file, buffer, size); lfs_ssize_t res = lfs_file_rawwrite(lfs, file, buffer, size);
LFS_TRACE("lfs_file_write -> %"PRId32, res); LFS_TRACE("lfs_file_write -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5156,7 +5156,7 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
(void*)lfs, (void*)file, off, whence); (void*)lfs, (void*)file, off, whence);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
lfs_soff_t res = lfs_file_seekraw(lfs, file, off, whence); lfs_soff_t res = lfs_file_rawseek(lfs, file, off, whence);
LFS_TRACE("lfs_file_seek -> %"PRId32, res); LFS_TRACE("lfs_file_seek -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5173,7 +5173,7 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
(void*)lfs, (void*)file, size); (void*)lfs, (void*)file, size);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
err = lfs_file_truncateraw(lfs, file, size); err = lfs_file_rawtruncate(lfs, file, size);
LFS_TRACE("lfs_file_truncate -> %d", err); LFS_TRACE("lfs_file_truncate -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5189,7 +5189,7 @@ lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file) {
LFS_TRACE("lfs_file_tell(%p, %p)", (void*)lfs, (void*)file); LFS_TRACE("lfs_file_tell(%p, %p)", (void*)lfs, (void*)file);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
lfs_soff_t res = lfs_file_tellraw(lfs, file); lfs_soff_t res = lfs_file_rawtell(lfs, file);
LFS_TRACE("lfs_file_tell -> %"PRId32, res); LFS_TRACE("lfs_file_tell -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5203,7 +5203,7 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file) {
} }
LFS_TRACE("lfs_file_rewind(%p, %p)", (void*)lfs, (void*)file); LFS_TRACE("lfs_file_rewind(%p, %p)", (void*)lfs, (void*)file);
err = lfs_file_rewindraw(lfs, file); err = lfs_file_rawrewind(lfs, file);
LFS_TRACE("lfs_file_rewind -> %d", err); LFS_TRACE("lfs_file_rewind -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5218,7 +5218,7 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
LFS_TRACE("lfs_file_size(%p, %p)", (void*)lfs, (void*)file); LFS_TRACE("lfs_file_size(%p, %p)", (void*)lfs, (void*)file);
LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
lfs_soff_t res = lfs_file_sizeraw(lfs, file); lfs_soff_t res = lfs_file_rawsize(lfs, file);
LFS_TRACE("lfs_file_size -> %"PRId32, res); LFS_TRACE("lfs_file_size -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5233,7 +5233,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
} }
LFS_TRACE("lfs_mkdir(%p, \"%s\")", (void*)lfs, path); LFS_TRACE("lfs_mkdir(%p, \"%s\")", (void*)lfs, path);
err = lfs_mkdirraw(lfs, path); err = lfs_rawmkdir(lfs, path);
LFS_TRACE("lfs_mkdir -> %d", err); LFS_TRACE("lfs_mkdir -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5249,7 +5249,7 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path); LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path);
LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)dir)); LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)dir));
err = lfs_dir_openraw(lfs, dir, path); err = lfs_dir_rawopen(lfs, dir, path);
LFS_TRACE("lfs_dir_open -> %d", err); LFS_TRACE("lfs_dir_open -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5263,7 +5263,7 @@ int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
} }
LFS_TRACE("lfs_dir_close(%p, %p)", (void*)lfs, (void*)dir); LFS_TRACE("lfs_dir_close(%p, %p)", (void*)lfs, (void*)dir);
err = lfs_dir_closeraw(lfs, dir); err = lfs_dir_rawclose(lfs, dir);
LFS_TRACE("lfs_dir_close -> %d", err); LFS_TRACE("lfs_dir_close -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5278,7 +5278,7 @@ int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) {
LFS_TRACE("lfs_dir_read(%p, %p, %p)", LFS_TRACE("lfs_dir_read(%p, %p, %p)",
(void*)lfs, (void*)dir, (void*)info); (void*)lfs, (void*)dir, (void*)info);
err = lfs_dir_readraw(lfs, dir, info); err = lfs_dir_rawread(lfs, dir, info);
LFS_TRACE("lfs_dir_read -> %d", err); LFS_TRACE("lfs_dir_read -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5293,7 +5293,7 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) {
LFS_TRACE("lfs_dir_seek(%p, %p, %"PRIu32")", LFS_TRACE("lfs_dir_seek(%p, %p, %"PRIu32")",
(void*)lfs, (void*)dir, off); (void*)lfs, (void*)dir, off);
err = lfs_dir_seekraw(lfs, dir, off); err = lfs_dir_rawseek(lfs, dir, off);
LFS_TRACE("lfs_dir_seek -> %d", err); LFS_TRACE("lfs_dir_seek -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5307,7 +5307,7 @@ lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir) {
} }
LFS_TRACE("lfs_dir_tell(%p, %p)", (void*)lfs, (void*)dir); LFS_TRACE("lfs_dir_tell(%p, %p)", (void*)lfs, (void*)dir);
lfs_soff_t res = lfs_dir_tellraw(lfs, dir); lfs_soff_t res = lfs_dir_rawtell(lfs, dir);
LFS_TRACE("lfs_dir_tell -> %"PRId32, res); LFS_TRACE("lfs_dir_tell -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5321,7 +5321,7 @@ int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir) {
} }
LFS_TRACE("lfs_dir_rewind(%p, %p)", (void*)lfs, (void*)dir); LFS_TRACE("lfs_dir_rewind(%p, %p)", (void*)lfs, (void*)dir);
err = lfs_dir_rewindraw(lfs, dir); err = lfs_dir_rawrewind(lfs, dir);
LFS_TRACE("lfs_dir_rewind -> %d", err); LFS_TRACE("lfs_dir_rewind -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5335,7 +5335,7 @@ lfs_ssize_t lfs_fs_size(lfs_t *lfs) {
} }
LFS_TRACE("lfs_fs_size(%p)", (void*)lfs); LFS_TRACE("lfs_fs_size(%p)", (void*)lfs);
lfs_ssize_t res = lfs_fs_sizeraw(lfs); lfs_ssize_t res = lfs_fs_rawsize(lfs);
LFS_TRACE("lfs_fs_size -> %"PRId32, res); LFS_TRACE("lfs_fs_size -> %"PRId32, res);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5350,7 +5350,7 @@ int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void *, lfs_block_t), void *data) {
LFS_TRACE("lfs_fs_traverse(%p, %p, %p)", LFS_TRACE("lfs_fs_traverse(%p, %p, %p)",
(void*)lfs, (void*)(uintptr_t)cb, data); (void*)lfs, (void*)(uintptr_t)cb, data);
err = lfs_fs_traverseraw(lfs, cb, data, true); err = lfs_fs_rawtraverse(lfs, cb, data, true);
LFS_TRACE("lfs_fs_traverse -> %d", err); LFS_TRACE("lfs_fs_traverse -> %d", err);
LFS_UNLOCK(lfs->cfg); LFS_UNLOCK(lfs->cfg);
@@ -5380,7 +5380,7 @@ int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer,
cfg->name_max, cfg->file_max, cfg->attr_max); cfg->name_max, cfg->file_max, cfg->attr_max);
err = lfs_migrateraw(lfs, cfg); err = lfs_rawmigrate(lfs, cfg);
LFS_TRACE("lfs_migrate -> %d", err); LFS_TRACE("lfs_migrate -> %d", err);
LFS_UNLOCK(cfg); LFS_UNLOCK(cfg);

328
scripts/code_size.py Executable file
View File

@@ -0,0 +1,328 @@
#!/usr/bin/env python3
#
# This script finds the code size at the function level, with/without
# static functions, and has some conveniences for comparing different
# versions. It's basically one big wrapper around nm, and may or may
# not have been written out of jealousy of Linux's Bloat-O-Meter.
#
# Here's a useful bash script to use while developing:
# ./scripts/code_size.py -qo old.csv
# while true ; do ./code_scripts/size.py -d old.csv ; inotifywait -rqe modify * ; done
#
# Or even better, to automatically update results on commit:
# ./scripts/code_size.py -qo commit.csv
# while true ; do ./scripts/code_size.py -d commit.csv -o current.csv ; git diff --exit-code --quiet && cp current.csv commit.csv ; inotifywait -rqe modify * ; done
#
# Or my personal favorite:
# ./scripts/code_size.py -qo master.csv && cp master.csv commit.csv
# while true ; do ( ./scripts/code_size.py -i commit.csv -d master.csv -s ; ./scripts/code_size.py -i current.csv -d master.csv -s ; ./scripts/code_size.py -d master.csv -o current.csv -s ) | awk 'BEGIN {printf "%-16s %7s %7s %7s\n","","old","new","diff"} (NR==2 && $1="commit") || (NR==4 && $1="prev") || (NR==6 && $1="current") {printf "%-16s %7s %7s %7s %s\n",$1,$2,$3,$5,$6}' ; git diff --exit-code --quiet && cp current.csv commit.csv ; inotifywait -rqe modify * ; done
#
import os
import itertools as it
import subprocess as sp
import shlex
import re
import csv
import collections as co
SIZEDIR = 'sizes'
RULES = """
define FLATTEN
%(sizedir)s/%(build)s.$(subst /,.,$(target)): $(target)
( echo "#line 1 \\"$$<\\"" ; %(cat)s $$< ) > $$@
%(sizedir)s/%(build)s.$(subst /,.,$(target:.c=.size)): \\
%(sizedir)s/%(build)s.$(subst /,.,$(target:.c=.o))
$(NM) --size-sort $$^ | sed 's/^/$(subst /,\\/,$(target:.c=.o)):/' > $$@
endef
$(foreach target,$(SRC),$(eval $(FLATTEN)))
-include %(sizedir)s/*.d
.SECONDARY:
%%.size: $(foreach t,$(subst /,.,$(SRC:.c=.size)),%%.$t)
cat $^ > $@
"""
CATS = {
'code': 'cat',
'code_inlined': 'sed \'s/^static\( inline\)\?//\'',
}
def build(**args):
# mkdir -p sizedir
os.makedirs(args['sizedir'], exist_ok=True)
if args.get('inlined', False):
builds = ['code', 'code_inlined']
else:
builds = ['code']
# write makefiles for the different types of builds
makefiles = []
targets = []
for build in builds:
path = args['sizedir'] + '/' + build
with open(path + '.mk', 'w') as mk:
mk.write(RULES.replace(4*' ', '\t') % dict(
sizedir=args['sizedir'],
build=build,
cat=CATS[build]))
mk.write('\n')
# pass on defines
for d in args['D']:
mk.write('%s: override CFLAGS += -D%s\n' % (
path+'.size', d))
makefiles.append(path + '.mk')
targets.append(path + '.size')
# build in parallel
cmd = (['make', '-f', 'Makefile'] +
list(it.chain.from_iterable(['-f', m] for m in makefiles)) +
[target for target in targets])
if args.get('verbose', False):
print(' '.join(shlex.quote(c) for c in cmd))
proc = sp.Popen(cmd,
stdout=sp.DEVNULL if not args.get('verbose', False) else None)
proc.wait()
if proc.returncode != 0:
sys.exit(-1)
# find results
build_results = co.defaultdict(lambda: 0)
# notes
# - filters type
# - discards internal/debug functions (leading __)
pattern = re.compile(
'^(?P<file>[^:]+)' +
':(?P<size>[0-9a-fA-F]+)' +
' (?P<type>[%s])' % re.escape(args['type']) +
' (?!__)(?P<name>.+?)$')
for build in builds:
path = args['sizedir'] + '/' + build
with open(path + '.size') as size:
for line in size:
match = pattern.match(line)
if match:
file = match.group('file')
# discard .8449 suffixes created by optimizer
name = re.sub('\.[0-9]+', '', match.group('name'))
size = int(match.group('size'), 16)
build_results[(build, file, name)] += size
results = []
for (build, file, name), size in build_results.items():
if build == 'code':
results.append((file, name, size, False))
elif (build == 'code_inlined' and
('inlined', file, name) not in results):
results.append((file, name, size, True))
return results
def main(**args):
# find results
if not args.get('input', None):
results = build(**args)
else:
with open(args['input']) as f:
r = csv.DictReader(f)
results = [
( result['file'],
result['name'],
int(result['size']),
bool(int(result.get('inlined', 0))))
for result in r
if (not bool(int(result.get('inlined', 0))) or
args.get('inlined', False))]
total = 0
for _, _, size, inlined in results:
if not inlined:
total += size
# find previous results?
if args.get('diff', None):
with open(args['diff']) as f:
r = csv.DictReader(f)
prev_results = [
( result['file'],
result['name'],
int(result['size']),
bool(int(result.get('inlined', 0))))
for result in r
if (not bool(int(result.get('inlined', 0))) or
args.get('inlined', False))]
prev_total = 0
for _, _, size, inlined in prev_results:
if not inlined:
prev_total += size
# write results to CSV
if args.get('output', None):
results.sort(key=lambda x: (-x[2], x))
with open(args['output'], 'w') as f:
w = csv.writer(f)
if args.get('inlined', False):
w.writerow(['file', 'name', 'size', 'inlined'])
for file, name, size, inlined in results:
w.writerow((file, name, size, int(inlined)))
else:
w.writerow(['file', 'name', 'size'])
for file, name, size, inlined in results:
w.writerow((file, name, size))
# print results
def dedup_functions(results):
functions = co.defaultdict(lambda: (0, True))
for _, name, size, inlined in results:
if not inlined:
functions[name] = (functions[name][0] + size, False)
for _, name, size, inlined in results:
if inlined and functions[name][1]:
functions[name] = (functions[name][0] + size, True)
return functions
def dedup_files(results):
files = co.defaultdict(lambda: 0)
for file, _, size, inlined in results:
if not inlined:
files[file] += size
return files
def diff_sizes(olds, news):
diff = co.defaultdict(lambda: (None, None, None))
for name, new in news.items():
diff[name] = (None, new, new)
for name, old in olds.items():
new = diff[name][1] or 0
diff[name] = (old, new, new-old)
return diff
def print_header(name=''):
if not args.get('diff', False):
print('%-40s %7s' % (name, 'size'))
else:
print('%-40s %7s %7s %7s' % (name, 'old', 'new', 'diff'))
def print_functions():
functions = dedup_functions(results)
functions = {
name+' (inlined)' if inlined else name: size
for name, (size, inlined) in functions.items()}
if not args.get('diff', None):
print_header('function')
for name, size in sorted(functions.items(),
key=lambda x: (-x[1], x)):
print("%-40s %7d" % (name, size))
else:
prev_functions = dedup_functions(prev_results)
prev_functions = {
name+' (inlined)' if inlined else name: size
for name, (size, inlined) in prev_functions.items()}
diff = diff_sizes(functions, prev_functions)
print_header('function (%d added, %d removed)' % (
sum(1 for old, _, _ in diff.values() if not old),
sum(1 for _, new, _ in diff.values() if not new)))
for name, (old, new, diff) in sorted(diff.items(),
key=lambda x: (-(x[1][2] or 0), x)):
if diff or args.get('all', False):
print("%-40s %7s %7s %+7d%s" % (
name, old or "-", new or "-", diff,
' (%+.2f%%)' % (100*((new-old)/old))
if old and new else
''))
def print_files():
files = dedup_files(results)
if not args.get('diff', None):
print_header('file')
for file, size in sorted(files.items(),
key=lambda x: (-x[1], x)):
print("%-40s %7d" % (file, size))
else:
prev_files = dedup_files(prev_results)
diff = diff_sizes(files, prev_files)
print_header('file (%d added, %d removed)' % (
sum(1 for old, _, _ in diff.values() if not old),
sum(1 for _, new, _ in diff.values() if not new)))
for name, (old, new, diff) in sorted(diff.items(),
key=lambda x: (-(x[1][2] or 0), x)):
if diff or args.get('all', False):
print("%-40s %7s %7s %+7d%s" % (
name, old or "-", new or "-", diff,
' (%+.2f%%)' % (100*((new-old)/old))
if old and new else
''))
def print_totals():
if not args.get('diff', None):
print("%-40s %7d" % ('TOTALS', total))
else:
print("%-40s %7s %7s %+7d%s" % (
'TOTALS', prev_total, total, total-prev_total,
' (%+.2f%%)' % (100*((total-prev_total)/total))
if prev_total and total else
''))
def print_status():
if not args.get('diff', None):
print(total)
else:
print("%d (%+.2f%%)" % (total, 100*((total-prev_total)/total)))
if args.get('quiet', False):
pass
elif args.get('status', False):
print_status()
elif args.get('summary', False):
print_header()
print_totals()
elif args.get('files', False):
print_files()
print_totals()
else:
print_functions()
print_totals()
if __name__ == "__main__":
import argparse
import sys
parser = argparse.ArgumentParser(
description="Find code size at the function level.")
parser.add_argument('sizedir', nargs='?', default=SIZEDIR,
help="Directory to store intermediary results. Defaults "
"to \"%s\"." % SIZEDIR)
parser.add_argument('-D', action='append', default=[],
help="Specify compile-time define.")
parser.add_argument('-v', '--verbose', action='store_true',
help="Output commands that run behind the scenes.")
parser.add_argument('-i', '--input',
help="Don't compile and find code sizes, instead use this CSV file.")
parser.add_argument('-o', '--output',
help="Specify CSV file to store results.")
parser.add_argument('-d', '--diff',
help="Specify CSV file to diff code size against.")
parser.add_argument('-a', '--all', action='store_true',
help="Show all functions, not just the ones that changed.")
parser.add_argument('--inlined', action='store_true',
help="Run a second compilation to find the sizes of functions normally "
"removed by optimizations. These will be shown as \"*.inlined\" "
"functions, and will not be included in the total.")
parser.add_argument('--files', action='store_true',
help="Show file-level code sizes. Note this does not include padding! "
"So sizes may differ from other tools.")
parser.add_argument('-s', '--summary', action='store_true',
help="Only show the total code size.")
parser.add_argument('-S', '--status', action='store_true',
help="Show minimum info useful for a single-line status.")
parser.add_argument('-q', '--quiet', action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument('--type', default='tTrRdDbB',
help="Type of symbols to report, this uses the same single-character "
"type-names emitted by nm. Defaults to %(default)r.")
sys.exit(main(**vars(parser.parse_args())))