summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2005-04-27 22:26:45 +0000
committermarcel <marcel@FreeBSD.org>2005-04-27 22:26:45 +0000
commit6ac44cbe2b773476ffb6659ca468dde0f4604199 (patch)
tree561ffb753666f41dfb80e6d9182262888ede6ec8
parent4caac8b9730f92775c41e5d0d46b932473c22b48 (diff)
downloadFreeBSD-src-6ac44cbe2b773476ffb6659ca468dde0f4604199.zip
FreeBSD-src-6ac44cbe2b773476ffb6659ca468dde0f4604199.tar.gz
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 :-)
-rw-r--r--sys/libkern/crc32.c33
-rw-r--r--sys/sys/systm.h22
2 files changed, 39 insertions, 16 deletions
diff --git a/sys/libkern/crc32.c b/sys/libkern/crc32.c
index a6a162b..4c937d2 100644
--- a/sys/libkern/crc32.c
+++ b/sys/libkern/crc32.c
@@ -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;
+ * }
+ */
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 0c114b3..64545f7 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -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);
OpenPOWER on IntegriCloud