summaryrefslogtreecommitdiff
path: root/crc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'crc32.c')
-rw-r--r--crc32.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/crc32.c b/crc32.c
index 689b288..0e04880 100644
--- a/crc32.c
+++ b/crc32.c
@@ -11,6 +11,14 @@
11 11
12/* @(#) $Id$ */ 12/* @(#) $Id$ */
13 13
14/*
15 Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection
16 on the static variables used to control the first-use generation of the crc
17 tables. Therefore if you #define DYNAMIC_CRC_TABLE, you should first call
18 get_crc_table() to initialize the tables before allowing more than on thread
19 to use crc32().
20 */
21
14#ifdef MAKECRCH 22#ifdef MAKECRCH
15# include <stdio.h> 23# include <stdio.h>
16# ifndef DYNAMIC_CRC_TABLE 24# ifndef DYNAMIC_CRC_TABLE
@@ -58,7 +66,7 @@
58 66
59#ifdef DYNAMIC_CRC_TABLE 67#ifdef DYNAMIC_CRC_TABLE
60 68
61local int crc_table_empty = 1; 69local volatile int crc_table_empty = 1;
62local unsigned long FAR crc_table[TBLS][256]; 70local unsigned long FAR crc_table[TBLS][256];
63local void make_crc_table OF((void)); 71local void make_crc_table OF((void));
64#ifdef MAKECRCH 72#ifdef MAKECRCH
@@ -95,38 +103,51 @@ local void make_crc_table()
95{ 103{
96 unsigned long c; 104 unsigned long c;
97 int n, k; 105 int n, k;
98 unsigned long poly; /* polynomial exclusive-or pattern */ 106 unsigned long poly; /* polynomial exclusive-or pattern */
99 /* terms of polynomial defining this crc (except x^32): */ 107 /* terms of polynomial defining this crc (except x^32): */
108 static volatile int first = 1; /* flag to limit concurrent making */
100 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; 109 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
101 110
102 /* make exclusive-or pattern from polynomial (0xedb88320UL) */ 111 /* See if another task is already doing this (not thread-safe, but better
103 poly = 0UL; 112 than nothing -- significantly reduces duration of vulnerability in
104 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) 113 case the advice about DYNAMIC_CRC_TABLE is ignored) */
105 poly |= 1UL << (31 - p[n]); 114 if (first) {
106 115 first = 0;
107 /* generate a crc for every 8-bit value */ 116
108 for (n = 0; n < 256; n++) { 117 /* make exclusive-or pattern from polynomial (0xedb88320UL) */
109 c = (unsigned long)n; 118 poly = 0UL;
110 for (k = 0; k < 8; k++) 119 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
111 c = c & 1 ? poly ^ (c >> 1) : c >> 1; 120 poly |= 1UL << (31 - p[n]);
112 crc_table[0][n] = c; 121
113 } 122 /* generate a crc for every 8-bit value */
123 for (n = 0; n < 256; n++) {
124 c = (unsigned long)n;
125 for (k = 0; k < 8; k++)
126 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
127 crc_table[0][n] = c;
128 }
114 129
115#ifdef BYFOUR 130#ifdef BYFOUR
116 /* generate crc for each value followed by one, two, and three zeros, and 131 /* generate crc for each value followed by one, two, and three zeros, and
117 then the byte reversal of those as well as the first table */ 132 then the byte reversal of those as well as the first table */
118 for (n = 0; n < 256; n++) { 133 for (n = 0; n < 256; n++) {
119 c = crc_table[0][n]; 134 c = crc_table[0][n];
120 crc_table[4][n] = REV(c); 135 crc_table[4][n] = REV(c);
121 for (k = 1; k < 4; k++) { 136 for (k = 1; k < 4; k++) {
122 c = crc_table[0][c & 0xff] ^ (c >> 8); 137 c = crc_table[0][c & 0xff] ^ (c >> 8);
123 crc_table[k][n] = c; 138 crc_table[k][n] = c;
124 crc_table[k + 4][n] = REV(c); 139 crc_table[k + 4][n] = REV(c);
125 } 140 }
126 } 141 }
127#endif /* BYFOUR */ 142#endif /* BYFOUR */
128 143
129 crc_table_empty = 0; 144 crc_table_empty = 0;
145 }
146 else { /* not first */
147 /* wait for the other guy to finish (not exactly efficient, but rare) */
148 while (crc_table_empty)
149 ;
150 }
130 151
131#ifdef MAKECRCH 152#ifdef MAKECRCH
132 /* write out CRC tables to crc32.h */ 153 /* write out CRC tables to crc32.h */
@@ -180,9 +201,10 @@ local void write_table(out, table)
180const unsigned long FAR * ZEXPORT get_crc_table() 201const unsigned long FAR * ZEXPORT get_crc_table()
181{ 202{
182#ifdef DYNAMIC_CRC_TABLE 203#ifdef DYNAMIC_CRC_TABLE
183 if (crc_table_empty) make_crc_table(); 204 if (crc_table_empty)
205 make_crc_table();
184#endif /* DYNAMIC_CRC_TABLE */ 206#endif /* DYNAMIC_CRC_TABLE */
185 return (const unsigned long FAR *)crc_table; 207 return (const unsigned long FAR *)crc_table;
186} 208}
187 209
188/* ========================================================================= */ 210/* ========================================================================= */