Adopted crc32c xor trick to avoid masking valid bits
Turns out these are equivalent:
cksum' = crc32c([d & ~0x80], cksum)
cksum' = crc32c([d], cksum ^ (d & 0x80))
Which is quite nice. The second form is a bit cheaper and works better
in situations where you may have an immutable buffer.
I took the long way to find this and may or may not have brute forced
an xor mask for the valid bit:
crc32c(62 95 e3 fd 00) => c7844d4d
crc32c(00 00 00 00 80) => c7844d4d
But this is equivalent to 00000080 after xoring in the init junk.
If you look at the naive lfs_crc32c impl, the first step is to xor the
first byte, so really xoring any byte will cancel it out of our crc32c.
Code changes, thought this would save more because we can reuse bd
checksumming a bit better... Oh well, at least the theory works:
code stack
before: 33916 2824
after: 33908 (-0.0%) 2824 (+0.0%)
This commit is contained in:
@@ -1087,9 +1087,10 @@ static lfs_ssize_t lfsr_bd_readtag_(lfs_t *lfs,
|
||||
LFS_ASSERT(size <= 0x0fffffff);
|
||||
d += d_;
|
||||
|
||||
// ignore the valid bit when calculating optional checksum
|
||||
tag_buf[0] &= ~0x80;
|
||||
// optional checksum
|
||||
if (cksum_) {
|
||||
// ignore the valid bit when calculating checksums
|
||||
*cksum_ ^= tag_buf[0] & 0x80;
|
||||
*cksum_ = lfs_crc32c(*cksum_, tag_buf, d);
|
||||
}
|
||||
|
||||
@@ -1146,19 +1147,17 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
|
||||
}
|
||||
d += d_;
|
||||
|
||||
// ignore the valid bit when calculating checksums
|
||||
if (cksum_) {
|
||||
*cksum_ ^= tag_buf[0] & 0x80;
|
||||
}
|
||||
int err = lfsr_bd_prog(lfs, block, off, &tag_buf, d,
|
||||
NULL);
|
||||
cksum_);
|
||||
if (err) {
|
||||
LFS_ASSERT(err < 0);
|
||||
return err;
|
||||
}
|
||||
|
||||
// ignore the valid bit when calculating optional checksum
|
||||
tag_buf[0] &= ~0x80;
|
||||
if (cksum_) {
|
||||
*cksum_ = lfs_crc32c(*cksum_, tag_buf, d);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user