summaryrefslogtreecommitdiff
path: root/zlib/crc32.c
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2004-09-19 16:14:54 +0000
committerjbj <devnull@localhost>2004-09-19 16:14:54 +0000
commit40409429140f8db038e62291ba92630f3928ca74 (patch)
tree4a7ea4ef3a9df28f2bc857491f8d22786e4e28c2 /zlib/crc32.c
parent59293dd8928d6f0033a45fdef9e9f50a296a3a0b (diff)
downloadlibrpm-tizen-40409429140f8db038e62291ba92630f3928ca74.tar.gz
librpm-tizen-40409429140f8db038e62291ba92630f3928ca74.tar.bz2
librpm-tizen-40409429140f8db038e62291ba92630f3928ca74.zip
- upgrade to pristine zlib-1.2.1.2.
CVS patchset: 7420 CVS date: 2004/09/19 16:14:54
Diffstat (limited to 'zlib/crc32.c')
-rw-r--r--zlib/crc32.c107
1 files changed, 67 insertions, 40 deletions
diff --git a/zlib/crc32.c b/zlib/crc32.c
index 368061c9f..0e0488058 100644
--- a/zlib/crc32.c
+++ b/zlib/crc32.c
@@ -11,6 +11,14 @@
/* @(#) $Id$ */
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection
+ on the static variables used to control the first-use generation of the crc
+ tables. Therefore if you #define DYNAMIC_CRC_TABLE, you should first call
+ get_crc_table() to initialize the tables before allowing more than on thread
+ to use crc32().
+ */
+
#ifdef MAKECRCH
# include <stdio.h>
# ifndef DYNAMIC_CRC_TABLE
@@ -48,11 +56,9 @@
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned))
- /*@*/;
+ const unsigned char FAR *, unsigned));
local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned))
- /*@*/;
+ const unsigned char FAR *, unsigned));
# define TBLS 8
#else
# define TBLS 1
@@ -60,13 +66,11 @@
#ifdef DYNAMIC_CRC_TABLE
-local int crc_table_empty = 1;
+local volatile int crc_table_empty = 1;
local unsigned long FAR crc_table[TBLS][256];
-local void make_crc_table OF((void))
- /*@*/;
+local void make_crc_table OF((void));
#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *))
- /*@*/;
+ local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */
/*
@@ -99,38 +103,51 @@ local void make_crc_table()
{
unsigned long c;
int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
+ unsigned long poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0UL;
+ for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+ poly |= 1UL << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
#ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros, and
- then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = REV(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
- }
- }
+ /* generate crc for each value followed by one, two, and three zeros, and
+ then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = REV(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = REV(c);
+ }
+ }
#endif /* BYFOUR */
- crc_table_empty = 0;
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not exactly efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
#ifdef MAKECRCH
/* write out CRC tables to crc32.h */
@@ -181,12 +198,13 @@ local void write_table(out, table)
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
-const unsigned long FAR * ZEXPORT get_crc_table(void)
+const unsigned long FAR * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty) make_crc_table();
+ if (crc_table_empty)
+ make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
+ return (const unsigned long FAR *)crc_table;
}
/* ========================================================================= */
@@ -194,7 +212,10 @@ const unsigned long FAR * ZEXPORT get_crc_table(void)
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
/* ========================================================================= */
-unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, unsigned len)
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
{
if (buf == Z_NULL) return 0UL;
@@ -234,7 +255,10 @@ unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uns
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
/* ========================================================================= */
-local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len)
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
{
register u4 c;
register const u4 FAR *buf4;
@@ -271,7 +295,10 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
/* ========================================================================= */
-local unsigned long crc32_big(unsigned long crc, const unsigned char FAR *buf, unsigned len)
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
{
register u4 c;
register const u4 FAR *buf4;