6 messages in com.perforce.jamming[jamming] [Matthias Troyer <troyer@it...| From | Sent On | Attachments |
|---|---|---|
| davi...@rcn.com | 22 Jan 2003 12:51 | |
| Christopher Seiwald | 24 Jan 2003 16:43 | |
| davi...@rcn.com | 24 Jan 2003 17:22 | |
| Lex Spoon | 25 Jan 2003 10:43 | |
| davi...@rcn.com | 25 Jan 2003 11:24 | |
| davi...@rcn.com | 25 Jan 2003 13:32 |
| Subject: | [jamming] [Matthias Troyer <troyer@itp.phys.ethz.ch>] [jamboost] Patch for jam bug on Cray![]() |
|---|---|
| From: | davi...@rcn.com (davi...@rcn.com) |
| Date: | 01/24/2003 05:22:43 PM |
| List: | com.perforce.jamming |
Christopher Seiwald <seiw...@perforce.com> writes:
| Our local Cray adminstrators (Bruno Loepfe from ETH and Olivier Byrde | from Cray) found a bug in the boost jam sources. it is in the file | hash.c: | | char *b = (*data)->key; | int keyval; | | ..... | | keyval = *b; | | while( *b ) | keyval = keyval * 2147059363 + *b++; | | keyval &= 0x7FFFFFFF; | | This assumes that overflows are benign, and works only if int is 32 | bit. It will not work on the Cray, where int is 64 bit, and with | optimization turned on actually 46 bit (on the Cray SV1 and some other | Crays integer operations will be performed in 46 bit arithmetic by | employing the floating point units). There are two proposed bug fixes:
I may have slept through this class in college, but I'm not getting a clear picture of what the problem is. Is it that the cray will generate a trap on integer overflow?
He didn't spell it out for me, but I'm guessing that's the case; it's certainly conforming behavior. Actually, looking at it closely, it seems to be conforming behavior for any platform regardless of word size. I don't think I like the suggested fix because it's highly platform-specific. Instead I would just use unsigned integer types. According to the 6.2.5/9 in the 'C' standard,
"A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type."
Other than that, we're only relying on keyval producing the same value (the hash) for a given input string. We don't really care how it gets there.
Then I'd go with:
int /* if you insist, but should be unsigned */ hashitem( register struct hash *hp, HASHDATA **data, int enter ) { ITEM **base; register ITEM *i; char *b = (*data)->key; unsigned keyval;
if( enter && !hp->items.more ) hashrehash( hp );
if( !enter && !hp->items.nel ) return 0;
keyval = (unsigned char)*b;
while( *b ) keyval = keyval * 2147059363u + (unsigned char)*b++;
/* keyval &= 0x7FFFFFFF; */
base = hp->tab.base + ( keyval % (unsigned)hp->tab.nel );
for( i = *base; i; i = i->hdr.next ) if( keyval == i->hdr.keyval && !strcmp( i->data.key, (*data)->key ) ) { *data = &i->data; return !0; }
if( enter ) { i = (ITEM *)hp->items.next; hp->items.next += hp->items.size; hp->items.more--; memcpy( (char *)&i->data, (char *)*data, hp->items.datalen ); i->hdr.keyval = keyval; i->hdr.next = *base; *base = i; *data = &i->data; }
return 0; }
-- David Abrahams da...@boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution




