Added lfsr_bd_cpy for disk->disk progs
This logic previous lived in lfsr_bd_progdata, but really should be its
own bd function.
Hardware support can be a future thing-to-do. Maybe.
This currently uses the small-hardcoded-buffer approach used to
implement lfsr_bd_cmp/cksum, which isn't great, but gets the job done
for now.
code stack
before: 33544 2800
after: 33572 (+0.1%) 2800 (+0.0%)
This commit is contained in:
@@ -452,6 +452,49 @@ static lfs_scmp_t lfsr_bd_cmp(lfs_t *lfs,
|
||||
return LFS_CMP_EQ;
|
||||
}
|
||||
|
||||
static int lfsr_bd_cpy(lfs_t *lfs,
|
||||
lfs_block_t dst_block, lfs_size_t dst_off,
|
||||
lfs_block_t src_block, lfs_size_t src_off, lfs_size_t hint,
|
||||
lfs_size_t size,
|
||||
uint32_t *cksum_, uint32_t *flcksum_) {
|
||||
// check for in-bounds
|
||||
LFS_ASSERT(dst_block < lfs->cfg->block_count);
|
||||
if (dst_off+size > lfs->cfg->block_size) {
|
||||
return LFS_ERR_RANGE;
|
||||
}
|
||||
LFS_ASSERT(src_block < lfs->cfg->block_count);
|
||||
if (src_off+size > lfs->cfg->block_size) {
|
||||
return LFS_ERR_RANGE;
|
||||
}
|
||||
|
||||
lfs_size_t dst_off_ = dst_off;
|
||||
lfs_size_t src_off_ = src_off;
|
||||
lfs_size_t hint_ = lfs_max(hint, size); // make sure hint >= size
|
||||
lfs_size_t size_ = size;
|
||||
while (size_ > 0) {
|
||||
// TODO can we do better than this?
|
||||
uint8_t dat[8];
|
||||
lfs_size_t d = lfs_min(size_, sizeof(dat));
|
||||
int err = lfsr_bd_read(lfs, src_block, src_off_, hint_, &dat, d);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = lfsr_bd_prog(lfs, dst_block, dst_off_, &dat, d,
|
||||
cksum_, flcksum_);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
dst_off_ += d;
|
||||
src_off_ += d;
|
||||
hint_ -= d;
|
||||
size_ -= d;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Small type-level utilities ///
|
||||
@@ -1311,24 +1354,12 @@ static int lfsr_bd_progdata_(lfs_t *lfs,
|
||||
uint32_t *cksum_, uint32_t *flcksum_) {
|
||||
// on-disk?
|
||||
if (lfsr_data_ondisk(&data)) {
|
||||
// TODO byte-level copies have been a pain point, works for prototyping
|
||||
// but can this be better? configurable? leverage
|
||||
// rcache/pcache directly?
|
||||
uint8_t dat;
|
||||
for (lfs_size_t i = 0; i < lfsr_data_size(&data); i++) {
|
||||
int err = lfsr_bd_read(lfs,
|
||||
data.u.disk.block, data.u.disk.off+i,
|
||||
lfsr_data_size(&data)-i,
|
||||
&dat, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = lfsr_bd_prog(lfs, block, off+i, &dat, 1,
|
||||
cksum_, flcksum_);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
int err = lfsr_bd_cpy(lfs, block, off,
|
||||
data.u.disk.block, data.u.disk.off, lfsr_data_size(&data),
|
||||
lfsr_data_size(&data),
|
||||
cksum_, flcksum_);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// buffer?
|
||||
|
||||
Reference in New Issue
Block a user