From 77bfcb69ad16a5984344293097f4ba4d56da0de7 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 5 May 2024 19:28:05 -0500 Subject: [PATCH] Ripped out attr-list data/buf allocators, hand allocated necessary state This attr-list allocator stuff is becoming over-engineered, these allocations really aren't that complex... This may have simplified after removing becksums, but if we need that complexity again we can cross that bridge when we get to it. Hand-allocating, dropping buf_size/data_count tracking, and refactoring lfsr_file_carve to pre-encode the right sibling gives us a nice bit of code/stack savings: code stack before: 33796 2808 after: 33728 (-0.2%) 2776 (-1.1%) --- lfs.c | 113 +++++++++++++++++++--------------------------------------- 1 file changed, 37 insertions(+), 76 deletions(-) diff --git a/lfs.c b/lfs.c index b43dc2f8..80f6dc90 100644 --- a/lfs.c +++ b/lfs.c @@ -4377,10 +4377,8 @@ static int lfsr_btree_parent(lfs_t *lfs, const lfsr_btree_t *btree, // extra state needed for non-terminating lfsr_btree_commit_ calls typedef struct lfsr_btree_scratch { lfsr_attr_t attrs[4]; - union { - lfsr_data_t data; - uint8_t buf[LFSR_BRANCH_DSIZE]; - } datas[3]; + lfsr_data_t split_data; + uint8_t buf[2*LFSR_BRANCH_DSIZE]; } lfsr_btree_scratch_t; // core btree algorithm @@ -4513,8 +4511,6 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // note that since we defer merges to compaction time, we can // end up removing an rbyd here attr_count = 0; - lfs_size_t data_count = 0; - bid -= pid - (rbyd.weight-1); if (rbyd_.weight == 0) { scratch->attrs[attr_count++] = LFSR_ATTR( @@ -4522,9 +4518,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, } else { scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_BRANCH, 0, - lfsr_cat_frombranch( - &rbyd_, - scratch->datas[data_count++].buf)); + lfsr_cat_frombranch(&rbyd_, scratch->buf)); if (rbyd_.weight != rbyd.weight) { scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight, @@ -4776,9 +4770,8 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // note we need to do this after playing out pending attrs in case // they introduce a new name! lfsr_tag_t split_tag; - lfsr_data_t split_data; err = lfsr_rbyd_lookupnext(lfs, &sibling, 0, LFSR_TAG_NAME, - NULL, &split_tag, NULL, &split_data); + NULL, &split_tag, NULL, &scratch->split_data); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); return err; @@ -4788,25 +4781,22 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, LFS_ASSERT(rbyd_.weight > 0); LFS_ASSERT(sibling.weight > 0); attr_count = 0; - data_count = 0; - // new root? if (!lfsr_rbyd_trunk(&parent)) { scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_BRANCH, +rbyd_.weight, lfsr_cat_frombranch( &rbyd_, - scratch->datas[data_count++].buf)); + &scratch->buf[0*LFSR_BRANCH_DSIZE])); scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_BRANCH, +sibling.weight, lfsr_cat_frombranch( &sibling, - scratch->datas[data_count++].buf)); + &scratch->buf[1*LFSR_BRANCH_DSIZE])); if (lfsr_tag_suptype(split_tag) == LFSR_TAG_NAME) { - scratch->datas[data_count].data = split_data; scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_NAME, 0, - LFSR_CAT_DATA(&scratch->datas[data_count++].data)); + LFSR_CAT_DATA(&scratch->split_data)); } // split root? } else { @@ -4815,7 +4805,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, LFSR_TAG_BRANCH, 0, lfsr_cat_frombranch( &rbyd_, - scratch->datas[data_count++].buf)); + &scratch->buf[0*LFSR_BRANCH_DSIZE])); if (rbyd_.weight != rbyd.weight) { scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight, @@ -4825,12 +4815,11 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, LFSR_TAG_BRANCH, +sibling.weight, lfsr_cat_frombranch( &sibling, - scratch->datas[data_count++].buf)); + &scratch->buf[1*LFSR_BRANCH_DSIZE])); if (lfsr_tag_suptype(split_tag) == LFSR_TAG_NAME) { - scratch->datas[data_count].data = split_data; scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_NAME, 0, - LFSR_CAT_DATA(&scratch->datas[data_count++].data)); + LFSR_CAT_DATA(&scratch->split_data)); } } attrs = scratch->attrs; @@ -4893,16 +4882,12 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // prepare commit to parent, tail recursing upwards LFS_ASSERT(rbyd_.weight > 0); attr_count = 0; - data_count = 0; - bid -= pid - (rbyd.weight-1); scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_RM, -sibling.weight, LFSR_CAT_NULL()); scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_BRANCH, 0, - lfsr_cat_frombranch( - &rbyd_, - scratch->datas[data_count++].buf)); + lfsr_cat_frombranch(&rbyd_, scratch->buf)); if (rbyd_.weight != rbyd.weight) { scratch->attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight, @@ -10315,8 +10300,11 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, union { lfsr_data_t data; uint8_t buf[LFSR_BPTR_DSIZE]; - } datas[2]; - lfs_size_t data_count = 0; + } left; + union { + lfsr_data_t data; + uint8_t buf[LFSR_BPTR_DSIZE]; + } right; // always convert to bshrub/btree when this function is called if (!lfsr_bshrub_isbshruborbtree(&file->bshrub)) { @@ -10330,9 +10318,7 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, } else if (lfsr_bshrub_isbptr(&file->m.mdir, &file->bshrub)) { attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_BLOCK, +lfsr_bshrub_size(&file->bshrub), - lfsr_cat_frombptr( - &file->bshrub.u.bptr, - datas[data_count++].buf)); + lfsr_cat_frombptr(&file->bshrub.u.bptr, left.buf)); } file->bshrub.u.bshrub.blocks[0] = file->m.mdir.rbyd.blocks[0]; @@ -10343,7 +10329,6 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, if (attr_count > 0) { LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t)); - LFS_ASSERT(data_count <= sizeof(datas)/sizeof(datas[0])); int err = lfsr_bshrub_commit(lfs, file, 0, attrs, attr_count); if (err) { @@ -10352,7 +10337,6 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, } attr_count = 0; - data_count = 0; } // need a hole? @@ -10376,7 +10360,7 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, // try to carve any existing data lfsr_tag_t right_tag_ = 0; lfsr_bid_t right_weight_; - lfsr_bptr_t right_bptr_; + lfsr_cat_t right_cat_; while (pos < lfsr_bshrub_size(&file->bshrub)) { lfsr_tag_t tag_; lfsr_bid_t weight_; @@ -10465,11 +10449,11 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, // carve fragment? } else if (tag_ == LFSR_TAG_DATA) { - datas[data_count].data = left_slice_; + left.data = left_slice_; attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_GROW | LFSR_TAG_SUB | LFSR_TAG_DATA, -(bid+1 - pos), - LFSR_CAT_DATA(&datas[data_count++].data)); + LFSR_CAT_DATA(&left.data)); // carve bptr? } else if (tag_ == LFSR_TAG_BLOCK) { @@ -10481,7 +10465,7 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, .data = left_slice_, .cksize = bptr_.cksize, .cksum = bptr_.cksum}, - datas[data_count++].buf)); + left.buf)); } else { LFS_UNREACHABLE(); @@ -10498,7 +10482,6 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, if (pos+weight > bid+1) { LFS_ASSERT(lfsr_data_size(right_slice_) == 0); LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t)); - LFS_ASSERT(data_count <= sizeof(datas)/sizeof(datas[0])); err = lfsr_bshrub_commit(lfs, file, bid, attrs, attr_count); @@ -10509,7 +10492,6 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, delta += lfs_min32(weight, bid+1 - pos); weight -= lfs_min32(weight, bid+1 - pos); attr_count = 0; - data_count = 0; continue; } @@ -10521,19 +10503,21 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, // carve fragment? } else if (tag_ == LFSR_TAG_DATA) { + right.data = right_slice_; right_tag_ = tag_; right_weight_ = bid+1 - (pos+weight); - right_bptr_.data = right_slice_; + right_cat_ = LFSR_CAT_DATA(&right.data); // carve bptr? } else if (tag_ == LFSR_TAG_BLOCK) { right_tag_ = tag_; right_weight_ = bid+1 - (pos+weight); - right_bptr_ = (lfsr_bptr_t){ - .data = right_slice_, - .cksize = bptr_.cksize, - .cksum = bptr_.cksum, - }; + right_cat_ = lfsr_cat_frombptr( + &(lfsr_bptr_t){ + .data = right_slice_, + .cksize = bptr_.cksize, + .cksum = bptr_.cksum}, + right.buf); } else { LFS_UNREACHABLE(); @@ -10567,32 +10551,15 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file, } } - // and don't forget the right sibling's attrs + // and don't forget the right sibling if (right_tag_) { - // right fragment? - if (right_tag_ == LFSR_TAG_DATA) { - datas[data_count].data = right_bptr_.data; - attrs[attr_count++] = LFSR_ATTR( - LFSR_TAG_DATA, +right_weight_, - LFSR_CAT_DATA(&datas[data_count++].data)); - - // right bptr? - } else if (right_tag_ == LFSR_TAG_BLOCK) { - attrs[attr_count++] = LFSR_ATTR( - LFSR_TAG_BLOCK, +right_weight_, - lfsr_cat_frombptr( - &right_bptr_, - datas[data_count++].buf)); - - } else { - LFS_UNREACHABLE(); - } + attrs[attr_count++] = LFSR_ATTR( + right_tag_, +right_weight_, right_cat_); } // commit pending attrs if (attr_count > 0) { LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t)); - LFS_ASSERT(data_count <= sizeof(datas)/sizeof(datas[0])); int err = lfsr_bshrub_commit(lfs, file, bid, attrs, attr_count); @@ -11410,16 +11377,13 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) { // commit our file's metadata lfsr_attr_t attrs[2]; lfs_size_t attr_count = 0; - union { - lfsr_data_t data; - uint8_t buf[LFSR_BTREE_DSIZE]; - } datas[2]; - lfs_size_t data_count = 0; + lfsr_data_t name_data; + uint8_t buf[LFSR_BTREE_DSIZE]; // not created yet? need to convert orphan to normal file if (lfsr_f_isorphan(file->m.flags)) { err = lfsr_mdir_lookup(lfs, &file->m.mdir, LFSR_TAG_ORPHAN, - &datas[data_count].data); + &name_data); if (err) { // we must have an orphan at this point LFS_ASSERT(err != LFS_ERR_NOENT); @@ -11428,7 +11392,7 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) { attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_SUB | LFSR_TAG_REG, 0, - LFSR_CAT_DATA(&datas[data_count++].data)); + LFSR_CAT_DATA(&name_data)); } // commit the file state @@ -11452,15 +11416,12 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) { } else if (lfsr_bshrub_isbtree(&file->m.mdir, &file->bshrub)) { attrs[attr_count++] = LFSR_ATTR( LFSR_TAG_SUB | LFSR_TAG_BTREE, 0, - lfsr_cat_frombtree( - &file->bshrub.u.btree, - datas[data_count++].buf)); + lfsr_cat_frombtree(&file->bshrub.u.btree, buf)); } else { LFS_UNREACHABLE(); } LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t)); - LFS_ASSERT(data_count <= sizeof(datas)/sizeof(datas[0])); err = lfsr_mdir_commit(lfs, &file->m.mdir, attrs, attr_count);