Refactor the CRC-32 code to enhance its usability. Move the actual

CRC logic to a new function: crc32_raw() that obtains the initial
CRC value as well as leaves any post-processing to the caller. As
such, it can be used when the initial CRC value is not ~0U or when
the final CRC value does need to be inverted (bitwise). It also
means that crc32_raw() can be called repeatedly when the data is
not available as a single block, such as for scatter/gather lists
and the likes.

Avoid the additional call overhead incured by the refactoring by
moving the implementation off crc32() to sys/systm.h and making it
inlinable. Since crc32_raw() is itself trivial and since it may
be used in loops that iterate over fragments, having it available
for inlining can be beneficial. Hence, move its implementation
to sys/systm.h as well.

Keep the original implementation of crc32() in libkern/crc32.c for
documentation purposes (as a comment of course).

Triggered by: Jose M Rodriguez (josemi at freebsd dot jazztel dot es)
Discussed on: current@
Tested on: amd64, ia64 (BVO having GPT partitions)
Jargon file candidate: BVO = By Virtue Of :-)
This commit is contained in:
Marcel Moolenaar 2005-04-27 22:26:45 +00:00
parent ca83142fc3
commit ee6bcf1223
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145604
2 changed files with 39 additions and 16 deletions

View File

@ -94,18 +94,21 @@ uint32_t crc32_tab[] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t
crc32(const void *buf, size_t size)
{
const uint8_t *p;
uint32_t crc;
p = buf;
crc = ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}
/*
* A function that calculates the CRC-32 based on the table above is
* given below for documentation purposes. An equivalent implementation
* of this function that's actually used in the kernel can be found
* in sys/systm.h, where it can be inlined.
*
* uint32_t
* crc32(const void *buf, size_t size)
* {
* const uint8_t *p = buf;
* uint32_t crc;
*
* crc = ~0U;
* while (size--)
* crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
* return crc ^ ~0U;
* }
*/

View File

@ -143,8 +143,28 @@ void panic(const char *, ...) __dead2 __printflike(1, 2);
void cpu_boot(int);
void cpu_rootconf(void);
extern uint32_t crc32_tab[];
uint32_t crc32(const void *buf, size_t size);
static __inline uint32_t
crc32_raw(const void *buf, size_t size, uint32_t crc)
{
const uint8_t *p = buf;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return (crc);
}
static __inline uint32_t
crc32(const void *buf, size_t size)
{
uint32_t crc;
crc = crc32_raw(buf, size, ~0U);
return (crc ^ ~0U);
}
void critical_enter(void);
void critical_exit(void);
void init_param1(void);