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:
parent
ca83142fc3
commit
ee6bcf1223
@ -94,18 +94,21 @@ uint32_t crc32_tab[] = {
|
|||||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t
|
/*
|
||||||
crc32(const void *buf, size_t size)
|
* A function that calculates the CRC-32 based on the table above is
|
||||||
{
|
* given below for documentation purposes. An equivalent implementation
|
||||||
const uint8_t *p;
|
* of this function that's actually used in the kernel can be found
|
||||||
uint32_t crc;
|
* in sys/systm.h, where it can be inlined.
|
||||||
|
*
|
||||||
p = buf;
|
* uint32_t
|
||||||
crc = ~0U;
|
* crc32(const void *buf, size_t size)
|
||||||
|
* {
|
||||||
while (size--)
|
* const uint8_t *p = buf;
|
||||||
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
|
* uint32_t crc;
|
||||||
|
*
|
||||||
return crc ^ ~0U;
|
* crc = ~0U;
|
||||||
}
|
* while (size--)
|
||||||
|
* crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
|
||||||
|
* return crc ^ ~0U;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
@ -143,8 +143,28 @@ void panic(const char *, ...) __dead2 __printflike(1, 2);
|
|||||||
|
|
||||||
void cpu_boot(int);
|
void cpu_boot(int);
|
||||||
void cpu_rootconf(void);
|
void cpu_rootconf(void);
|
||||||
|
|
||||||
extern uint32_t crc32_tab[];
|
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_enter(void);
|
||||||
void critical_exit(void);
|
void critical_exit(void);
|
||||||
void init_param1(void);
|
void init_param1(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user