Replaced attr-list arenas with three independent arrays

lfsr_attr_t attrs[a*d*b];  =>  lfsr_attr_t attrs[a];
  lfs_size_t attr_count;         lfs_size_t attr_count;
  lfs_size_t attr_scratch;       lfsr_data_t datas[d];
                                 lfs_size_t data_count;
                                 uint8_t buf[b];
                                 lfs_size_t buf_size;

This mostly reverts the allocator scaffolding needed for the attr-list
arenas (LFS_ALIGNOF, etc). This is the main draw of this change, as it
would be nice to avoid a low-level arena implementation headaches unless
they prove to be worthwhile. Which they haven't really so far...

Unfortunately this comes with another code cost, I think due to the
number of counters needed to keep track of separate attr/data/buf
allocations. At least stack showed a slight improvement:

           code          stack
  before: 33844           2824
  after:  33872 (+0.1%)   2816 (-0.3%)
This commit is contained in:
Christopher Haster
2024-05-05 14:43:07 -05:00
parent 8f3036f1e5
commit 0509fba9b9
2 changed files with 107 additions and 128 deletions
+107 -118
View File
@@ -1631,29 +1631,6 @@ static inline lfsr_shrub_t *lfsr_attr_shrubtrunk(const lfsr_attr_t *attr) {
return (lfsr_shrub_t*)attr->cat.u.buf.buffer; return (lfsr_shrub_t*)attr->cat.u.buf.buffer;
} }
// sometimes we want some extra scratch space associated with an
// attribute list
#define LFSR_ATTR_SCRATCH(_size) \
(((_size)+sizeof(lfsr_attr_t)-1) / sizeof(lfsr_attr_t))
static inline void *lfsr_attr_scratch(
lfsr_attr_t *attr, lfs_size_t *attr_scratch,
lfs_size_t size) {
lfs_size_t attr_scratch_ = *attr_scratch - size;
*attr_scratch = attr_scratch_;
return &((uint8_t*)attr)[attr_scratch_];
}
static inline lfsr_data_t *lfsr_attr_scratchdata(
lfsr_attr_t *attr, lfs_size_t *attr_scratch) {
lfs_size_t attr_scratch_ = *attr_scratch - sizeof(lfsr_data_t);
// align down
attr_scratch_ -= (uintptr_t)&((uint8_t*)attr)[attr_scratch_]
% LFS_ALIGNOF(lfsr_data_t);
*attr_scratch = attr_scratch_;
return (lfsr_data_t*)&((uint8_t*)attr)[attr_scratch_];
}
// generalized info returned by traveral functions // generalized info returned by traveral functions
@@ -4397,10 +4374,12 @@ static int lfsr_btree_parent(lfs_t *lfs, const lfsr_btree_t *btree,
} }
// attrs needed for lfsr_btree_commit_ // extra state needed for non-terminating lfsr_btree_commit_ calls
#define LFSR_BTREE_COMMIT_ATTRS \ typedef struct lfsr_btree_scratch {
(4 + LFSR_ATTR_SCRATCH( \ lfsr_attr_t attrs[4];
LFS_ALIGNEDSIZEOF(lfsr_data_t) + 2*LFSR_BRANCH_DSIZE)) lfsr_data_t datas[1];
uint8_t buf[2*LFSR_BRANCH_DSIZE];
} lfsr_btree_scratch_t;
// core btree algorithm // core btree algorithm
// //
@@ -4409,8 +4388,9 @@ static int lfsr_btree_parent(lfs_t *lfs, const lfsr_btree_t *btree,
// 2. we have a shrub root // 2. we have a shrub root
// //
static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
lfsr_bid_t *bid_, const lfsr_attr_t **attrs_, lfs_size_t *attr_count_, lfsr_btree_scratch_t *scratch,
lfsr_attr_t attrs__[static LFSR_BTREE_COMMIT_ATTRS]) { lfsr_bid_t *bid_,
const lfsr_attr_t **attrs_, lfs_size_t *attr_count_) {
lfsr_bid_t bid = *bid_; lfsr_bid_t bid = *bid_;
LFS_ASSERT(bid <= (lfsr_bid_t)btree->weight); LFS_ASSERT(bid <= (lfsr_bid_t)btree->weight);
const lfsr_attr_t *attrs = *attrs_; const lfsr_attr_t *attrs = *attrs_;
@@ -4531,24 +4511,25 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
// note that since we defer merges to compaction time, we can // note that since we defer merges to compaction time, we can
// end up removing an rbyd here // end up removing an rbyd here
attr_count = 0; attr_count = 0;
lfs_size_t attr_scratch = LFSR_BTREE_COMMIT_ATTRS*sizeof(lfsr_attr_t); lfs_size_t data_count = 0;
lfs_size_t buf_size = 0;
bid -= pid - (rbyd.weight-1); bid -= pid - (rbyd.weight-1);
if (rbyd_.weight == 0) { if (rbyd_.weight == 0) {
attrs__[attr_count++] = LFSR_ATTR( scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_RM, -rbyd.weight, LFSR_CAT_NULL()); LFSR_TAG_RM, -rbyd.weight, LFSR_CAT_NULL());
} else { } else {
uint8_t *buf = lfsr_attr_scratch(attrs__, &attr_scratch, scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_BRANCH_DSIZE);
attrs__[attr_count++] = LFSR_ATTR(
LFSR_TAG_BRANCH, 0, LFSR_TAG_BRANCH, 0,
lfsr_cat_frombranch(&rbyd_, buf)); lfsr_cat_frombranch(&rbyd_, &scratch->buf[buf_size]));
buf_size += LFSR_BRANCH_DSIZE;
if (rbyd_.weight != rbyd.weight) { if (rbyd_.weight != rbyd.weight) {
attrs__[attr_count++] = LFSR_ATTR( scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight, LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight,
LFSR_CAT_NULL()); LFSR_CAT_NULL());
} }
} }
attrs = attrs__; attrs = scratch->attrs;
rbyd = parent; rbyd = parent;
rid = pid; rid = pid;
@@ -4788,68 +4769,68 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
goto finalize; goto finalize;
} }
// prepare commit to parent, tail recursing upwards
LFS_ASSERT(rbyd_.weight > 0);
LFS_ASSERT(sibling.weight > 0);
attr_count = 0;
attr_scratch = LFSR_BTREE_COMMIT_ATTRS*sizeof(lfsr_attr_t);
// lookup first name in sibling to use as the split name // lookup first name in sibling to use as the split name
// //
// note we need to do this after playing out pending attrs in case // note we need to do this after playing out pending attrs in case
// they introduce a new name! // they introduce a new name!
lfsr_tag_t split_tag; lfsr_tag_t split_tag;
lfsr_data_t *split_data = lfsr_attr_scratchdata( lfsr_data_t split_data;
attrs__, &attr_scratch);
err = lfsr_rbyd_lookupnext(lfs, &sibling, 0, LFSR_TAG_NAME, err = lfsr_rbyd_lookupnext(lfs, &sibling, 0, LFSR_TAG_NAME,
NULL, &split_tag, NULL, split_data); NULL, &split_tag, NULL, &split_data);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
return err; return err;
} }
// prepare commit to parent, tail recursing upwards
LFS_ASSERT(rbyd_.weight > 0);
LFS_ASSERT(sibling.weight > 0);
attr_count = 0;
data_count = 0;
buf_size = 0;
// new root? // new root?
if (!lfsr_rbyd_trunk(&parent)) { if (!lfsr_rbyd_trunk(&parent)) {
uint8_t *buf = lfsr_attr_scratch(attrs__, &attr_scratch, scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_BRANCH_DSIZE);
attrs__[attr_count++] = LFSR_ATTR(
LFSR_TAG_BRANCH, +rbyd_.weight, LFSR_TAG_BRANCH, +rbyd_.weight,
lfsr_cat_frombranch(&rbyd_, buf)); lfsr_cat_frombranch(&rbyd_, &scratch->buf[buf_size]));
buf = lfsr_attr_scratch(attrs__, &attr_scratch, buf_size += LFSR_BRANCH_DSIZE;
LFSR_BRANCH_DSIZE); scratch->attrs[attr_count++] = LFSR_ATTR(
attrs__[attr_count++] = LFSR_ATTR(
LFSR_TAG_BRANCH, +sibling.weight, LFSR_TAG_BRANCH, +sibling.weight,
lfsr_cat_frombranch(&sibling, buf)); lfsr_cat_frombranch(&sibling, &scratch->buf[buf_size]));
buf_size += LFSR_BRANCH_DSIZE;
if (lfsr_tag_suptype(split_tag) == LFSR_TAG_NAME) { if (lfsr_tag_suptype(split_tag) == LFSR_TAG_NAME) {
attrs__[attr_count++] = LFSR_ATTR( scratch->datas[data_count] = split_data;
scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_NAME, 0, LFSR_TAG_NAME, 0,
LFSR_CAT_DATA(split_data)); LFSR_CAT_DATA(&scratch->datas[data_count]));
data_count += 1;
} }
// split root? // split root?
} else { } else {
bid -= pid - (rbyd.weight-1); bid -= pid - (rbyd.weight-1);
uint8_t *buf = lfsr_attr_scratch(attrs__, &attr_scratch, scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_BRANCH_DSIZE);
attrs__[attr_count++] = LFSR_ATTR(
LFSR_TAG_BRANCH, 0, LFSR_TAG_BRANCH, 0,
lfsr_cat_frombranch(&rbyd_, buf)); lfsr_cat_frombranch(&rbyd_, &scratch->buf[buf_size]));
buf_size += LFSR_BRANCH_DSIZE;
if (rbyd_.weight != rbyd.weight) { if (rbyd_.weight != rbyd.weight) {
attrs__[attr_count++] = LFSR_ATTR( scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight, LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight,
LFSR_CAT_NULL()); LFSR_CAT_NULL());
} }
buf = lfsr_attr_scratch(attrs__, &attr_scratch, scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_BRANCH_DSIZE);
attrs__[attr_count++] = LFSR_ATTR(
LFSR_TAG_BRANCH, +sibling.weight, LFSR_TAG_BRANCH, +sibling.weight,
lfsr_cat_frombranch(&sibling, buf)); lfsr_cat_frombranch(&sibling, &scratch->buf[buf_size]));
buf_size += LFSR_BRANCH_DSIZE;
if (lfsr_tag_suptype(split_tag) == LFSR_TAG_NAME) { if (lfsr_tag_suptype(split_tag) == LFSR_TAG_NAME) {
attrs__[attr_count++] = LFSR_ATTR( scratch->datas[data_count] = split_data;
scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_NAME, 0, LFSR_TAG_NAME, 0,
LFSR_CAT_DATA(split_data)); LFSR_CAT_DATA(&scratch->datas[data_count]));
data_count += 1;
} }
} }
attrs = attrs__; attrs = scratch->attrs;
rbyd = parent; rbyd = parent;
rid = pid; rid = pid;
@@ -4909,21 +4890,22 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
// prepare commit to parent, tail recursing upwards // prepare commit to parent, tail recursing upwards
LFS_ASSERT(rbyd_.weight > 0); LFS_ASSERT(rbyd_.weight > 0);
attr_count = 0; attr_count = 0;
attr_scratch = LFSR_BTREE_COMMIT_ATTRS*sizeof(lfsr_attr_t); data_count = 0;
buf_size = 0;
bid -= pid - (rbyd.weight-1); bid -= pid - (rbyd.weight-1);
attrs__[attr_count++] = LFSR_ATTR( scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_RM, -sibling.weight, LFSR_CAT_NULL()); LFSR_TAG_RM, -sibling.weight, LFSR_CAT_NULL());
uint8_t *buf = lfsr_attr_scratch(attrs__, &attr_scratch, scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_BRANCH_DSIZE);
attrs__[attr_count++] = LFSR_ATTR(
LFSR_TAG_BRANCH, 0, LFSR_TAG_BRANCH, 0,
lfsr_cat_frombranch(&rbyd_, buf)); lfsr_cat_frombranch(&rbyd_, &scratch->buf[buf_size]));
buf_size += LFSR_BRANCH_DSIZE;
if (rbyd_.weight != rbyd.weight) { if (rbyd_.weight != rbyd.weight) {
attrs__[attr_count++] = LFSR_ATTR( scratch->attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight, LFSR_TAG_GROW, -rbyd.weight + rbyd_.weight,
LFSR_CAT_NULL()); LFSR_CAT_NULL());
} }
attrs = attrs__; attrs = scratch->attrs;
rbyd = parent; rbyd = parent;
rid = pid + sibling.weight; rid = pid + sibling.weight;
@@ -4935,10 +4917,9 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree, static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
lfsr_bid_t bid, const lfsr_attr_t *attrs, lfs_size_t attr_count) { lfsr_bid_t bid, const lfsr_attr_t *attrs, lfs_size_t attr_count) {
// try to commit to the btree // try to commit to the btree
lfsr_attr_t attrs__[LFSR_BTREE_COMMIT_ATTRS]; lfsr_btree_scratch_t scratch;
int err = lfsr_btree_commit_(lfs, btree, int err = lfsr_btree_commit_(lfs, btree, &scratch,
&bid, &attrs, &attr_count, &bid, &attrs, &attr_count);
attrs__);
if (err && err != LFS_ERR_RANGE) { if (err && err != LFS_ERR_RANGE) {
return err; return err;
} }
@@ -10181,10 +10162,9 @@ static int lfsr_bshrub_commit(lfs_t *lfs, lfsr_file_t *file,
} }
// try to commit to the btree // try to commit to the btree
lfsr_attr_t attrs__[LFSR_BTREE_COMMIT_ATTRS]; lfsr_btree_scratch_t scratch;
int err = lfsr_btree_commit_(lfs, &file->bshrub.u.btree, int err = lfsr_btree_commit_(lfs, &file->bshrub.u.btree, &scratch,
&bid, &attrs, &attr_count, &bid, &attrs, &attr_count);
attrs__);
if (err && err != LFS_ERR_RANGE) { if (err && err != LFS_ERR_RANGE) {
return err; return err;
} }
@@ -10327,10 +10307,12 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
// try to merge commits where possible // try to merge commits where possible
lfsr_bid_t bid = lfsr_bshrub_size(&file->bshrub); lfsr_bid_t bid = lfsr_bshrub_size(&file->bshrub);
lfsr_attr_t attrs[5 + LFSR_ATTR_SCRATCH( lfsr_attr_t attrs[5];
2*LFS_MAX(LFS_ALIGNEDSIZEOF(lfsr_data_t), LFSR_BPTR_DSIZE))];
lfs_size_t attr_count = 0; lfs_size_t attr_count = 0;
lfs_size_t attr_scratch = sizeof(attrs); lfsr_data_t datas[2];
lfs_size_t data_count = 0;
uint8_t buf[2*LFSR_BPTR_DSIZE];
lfs_size_t buf_size = 0;
// always convert to bshrub/btree when this function is called // always convert to bshrub/btree when this function is called
if (!lfsr_bshrub_isbshruborbtree(&file->bshrub)) { if (!lfsr_bshrub_isbshruborbtree(&file->bshrub)) {
@@ -10342,11 +10324,10 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
LFSR_TAG_DATA, +lfsr_bshrub_size(&file->bshrub), LFSR_TAG_DATA, +lfsr_bshrub_size(&file->bshrub),
LFSR_CAT_DATA(&file->bshrub.u.bsprout)); LFSR_CAT_DATA(&file->bshrub.u.bsprout));
} else if (lfsr_bshrub_isbptr(&file->m.mdir, &file->bshrub)) { } else if (lfsr_bshrub_isbptr(&file->m.mdir, &file->bshrub)) {
uint8_t *buf = lfsr_attr_scratch(attrs, &attr_scratch,
LFSR_BPTR_DSIZE);
attrs[attr_count++] = LFSR_ATTR( attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_BLOCK, +lfsr_bshrub_size(&file->bshrub), LFSR_TAG_BLOCK, +lfsr_bshrub_size(&file->bshrub),
lfsr_cat_frombptr(&file->bshrub.u.bptr, buf)); lfsr_cat_frombptr(&file->bshrub.u.bptr, &buf[buf_size]));
buf_size += LFSR_BPTR_DSIZE;
} }
file->bshrub.u.bshrub.blocks[0] = file->m.mdir.rbyd.blocks[0]; file->bshrub.u.bshrub.blocks[0] = file->m.mdir.rbyd.blocks[0];
@@ -10356,7 +10337,9 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
file->bshrub.u.bshrub.estimate = -1; file->bshrub.u.bshrub.estimate = -1;
if (attr_count > 0) { if (attr_count > 0) {
LFS_ASSERT(attr_count*sizeof(lfsr_attr_t) <= attr_scratch); LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t));
LFS_ASSERT(data_count <= sizeof(datas)/sizeof(lfsr_data_t));
LFS_ASSERT(buf_size <= sizeof(buf));
int err = lfsr_bshrub_commit(lfs, file, 0, attrs, attr_count); int err = lfsr_bshrub_commit(lfs, file, 0, attrs, attr_count);
if (err) { if (err) {
@@ -10365,7 +10348,8 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
} }
attr_count = 0; attr_count = 0;
attr_scratch = sizeof(attrs); data_count = 0;
buf_size = 0;
} }
// need a hole? // need a hole?
@@ -10478,18 +10462,15 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
// carve fragment? // carve fragment?
} else if (tag_ == LFSR_TAG_DATA) { } else if (tag_ == LFSR_TAG_DATA) {
lfsr_data_t *data = lfsr_attr_scratchdata( datas[data_count] = left_slice_;
attrs, &attr_scratch);
*data = left_slice_;
attrs[attr_count++] = LFSR_ATTR( attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_GROW | LFSR_TAG_SUB | LFSR_TAG_DATA, LFSR_TAG_GROW | LFSR_TAG_SUB | LFSR_TAG_DATA,
-(bid+1 - pos), -(bid+1 - pos),
LFSR_CAT_DATA(data)); LFSR_CAT_DATA(&datas[data_count]));
data_count += 1;
// carve bptr? // carve bptr?
} else if (tag_ == LFSR_TAG_BLOCK) { } else if (tag_ == LFSR_TAG_BLOCK) {
uint8_t *buf = lfsr_attr_scratch(attrs, &attr_scratch,
LFSR_BPTR_DSIZE);
attrs[attr_count++] = LFSR_ATTR( attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_GROW | LFSR_TAG_SUB | LFSR_TAG_BLOCK, LFSR_TAG_GROW | LFSR_TAG_SUB | LFSR_TAG_BLOCK,
-(bid+1 - pos), -(bid+1 - pos),
@@ -10498,7 +10479,8 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
.data = left_slice_, .data = left_slice_,
.cksize = bptr_.cksize, .cksize = bptr_.cksize,
.cksum = bptr_.cksum}, .cksum = bptr_.cksum},
buf)); &buf[buf_size]));
buf_size += LFSR_BPTR_DSIZE;
} else { } else {
LFS_UNREACHABLE(); LFS_UNREACHABLE();
@@ -10514,7 +10496,9 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
// so commit what we have and move on to next entry // so commit what we have and move on to next entry
if (pos+weight > bid+1) { if (pos+weight > bid+1) {
LFS_ASSERT(lfsr_data_size(right_slice_) == 0); LFS_ASSERT(lfsr_data_size(right_slice_) == 0);
LFS_ASSERT(attr_count*sizeof(lfsr_attr_t) <= attr_scratch); LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t));
LFS_ASSERT(data_count <= sizeof(datas)/sizeof(lfsr_data_t));
LFS_ASSERT(buf_size <= sizeof(buf));
err = lfsr_bshrub_commit(lfs, file, bid, err = lfsr_bshrub_commit(lfs, file, bid,
attrs, attr_count); attrs, attr_count);
@@ -10525,7 +10509,8 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
delta += lfs_min32(weight, bid+1 - pos); delta += lfs_min32(weight, bid+1 - pos);
weight -= lfs_min32(weight, bid+1 - pos); weight -= lfs_min32(weight, bid+1 - pos);
attr_count = 0; attr_count = 0;
attr_scratch = sizeof(attrs); data_count = 0;
buf_size = 0;
continue; continue;
} }
@@ -10587,19 +10572,18 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
if (right_tag_) { if (right_tag_) {
// right fragment? // right fragment?
if (right_tag_ == LFSR_TAG_DATA) { if (right_tag_ == LFSR_TAG_DATA) {
lfsr_data_t *data = lfsr_attr_scratchdata(attrs, &attr_scratch); datas[data_count] = right_bptr_.data;
*data = right_bptr_.data;
attrs[attr_count++] = LFSR_ATTR( attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_DATA, +right_weight_, LFSR_TAG_DATA, +right_weight_,
LFSR_CAT_DATA(data)); LFSR_CAT_DATA(&datas[data_count]));
data_count += 1;
// right bptr? // right bptr?
} else if (right_tag_ == LFSR_TAG_BLOCK) { } else if (right_tag_ == LFSR_TAG_BLOCK) {
uint8_t *buf = lfsr_attr_scratch(attrs, &attr_scratch,
LFSR_BPTR_DSIZE);
attrs[attr_count++] = LFSR_ATTR( attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_BLOCK, +right_weight_, LFSR_TAG_BLOCK, +right_weight_,
lfsr_cat_frombptr(&right_bptr_, buf)); lfsr_cat_frombptr(&right_bptr_, &buf[buf_size]));
buf_size += LFSR_BPTR_DSIZE;
} else { } else {
LFS_UNREACHABLE(); LFS_UNREACHABLE();
@@ -10608,7 +10592,9 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
// commit pending attrs // commit pending attrs
if (attr_count > 0) { if (attr_count > 0) {
LFS_ASSERT(attr_count*sizeof(lfsr_attr_t) <= attr_scratch); LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t));
LFS_ASSERT(data_count <= sizeof(datas)/sizeof(lfsr_data_t));
LFS_ASSERT(buf_size <= sizeof(buf));
int err = lfsr_bshrub_commit(lfs, file, bid, int err = lfsr_bshrub_commit(lfs, file, bid,
attrs, attr_count); attrs, attr_count);
@@ -11424,16 +11410,17 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
lfs_alloc_ckpoint(lfs); lfs_alloc_ckpoint(lfs);
// commit our file's metadata // commit our file's metadata
lfsr_attr_t attrs[2 + LFSR_ATTR_SCRATCH( lfsr_attr_t attrs[2];
LFS_ALIGNEDSIZEOF(lfsr_data_t) + LFSR_BTREE_DSIZE)];
lfs_size_t attr_count = 0; lfs_size_t attr_count = 0;
lfs_size_t attr_scratch = sizeof(attrs); lfsr_data_t datas[1];
lfs_size_t data_count = 0;
uint8_t buf[LFSR_BTREE_DSIZE];
lfs_size_t buf_size = 0;
// not created yet? need to convert orphan to normal file // not created yet? need to convert orphan to normal file
if (lfsr_f_isorphan(file->m.flags)) { if (lfsr_f_isorphan(file->m.flags)) {
lfsr_data_t *data = lfsr_attr_scratchdata(attrs, &attr_scratch);
err = lfsr_mdir_lookup(lfs, &file->m.mdir, LFSR_TAG_ORPHAN, err = lfsr_mdir_lookup(lfs, &file->m.mdir, LFSR_TAG_ORPHAN,
data); &datas[data_count]);
if (err) { if (err) {
// we must have an orphan at this point // we must have an orphan at this point
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
@@ -11442,7 +11429,8 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
attrs[attr_count++] = LFSR_ATTR( attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_SUB | LFSR_TAG_REG, 0, LFSR_TAG_SUB | LFSR_TAG_REG, 0,
LFSR_CAT_DATA(data)); LFSR_CAT_DATA(&datas[data_count]));
data_count += 1;
} }
// commit the file state // commit the file state
@@ -11464,16 +11452,17 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
&file->bshrub_.u.bshrub); &file->bshrub_.u.bshrub);
// btree? // btree?
} else if (lfsr_bshrub_isbtree(&file->m.mdir, &file->bshrub)) { } else if (lfsr_bshrub_isbtree(&file->m.mdir, &file->bshrub)) {
uint8_t *buf = lfsr_attr_scratch(attrs, &attr_scratch,
LFSR_BTREE_DSIZE);
attrs[attr_count++] = LFSR_ATTR( attrs[attr_count++] = LFSR_ATTR(
LFSR_TAG_SUB | LFSR_TAG_BTREE, 0, LFSR_TAG_SUB | LFSR_TAG_BTREE, 0,
lfsr_cat_frombtree(&file->bshrub.u.btree, buf)); lfsr_cat_frombtree(&file->bshrub.u.btree, &buf[buf_size]));
buf_size += LFSR_BTREE_DSIZE;
} else { } else {
LFS_UNREACHABLE(); LFS_UNREACHABLE();
} }
LFS_ASSERT(attr_count*sizeof(lfsr_attr_t) <= attr_scratch); LFS_ASSERT(attr_count <= sizeof(attrs)/sizeof(lfsr_attr_t));
LFS_ASSERT(data_count <= sizeof(datas)/sizeof(lfsr_data_t));
LFS_ASSERT(buf_size <= sizeof(buf));
err = lfsr_mdir_commit(lfs, &file->m.mdir, err = lfsr_mdir_commit(lfs, &file->m.mdir,
attrs, attr_count); attrs, attr_count);
-10
View File
@@ -221,16 +221,6 @@ static inline void lfs_sswap32(int32_t *a, int32_t *b) {
*b = t; *b = t;
} }
// Find alignment of a type at compile time
#if !defined(LFS_NO_INTRINSICS)
#define LFS_ALIGNOF(t) __alignof__(t)
#else
#define LFS_ALIGNOF(t) ((size_t)&((struct {char a; t b;}*)0)->b)
#endif
// Find size necessary to align type at compile time
#define LFS_ALIGNEDSIZEOF(t) (sizeof(t) + LFS_ALIGNOF(t)-1)
// Align to nearest multiple of a size // Align to nearest multiple of a size
static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) { static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) {
return a - (a % alignment); return a - (a % alignment);