From owner-freebsd-bugs Sat Oct 7 13:35:47 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by hub.freebsd.org (Postfix) with SMTP id 6055C37B66C; Sat, 7 Oct 2000 13:35:42 -0700 (PDT) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 7 Oct 2000 21:35:41 +0100 (BST) Date: Sat, 7 Oct 2000 21:35:40 +0100 From: David Malone To: dwmalone@FreeBSD.org Cc: freebsd-bugs@FreeBSD.org, bob@immure.com, bde@FreeBSD.org Subject: Re: misc/21204: bit_ffc and bit_ffs macros in bitstring.h test 1 byte too many. Message-ID: <20001007213540.A15000@walton.maths.tcd.ie> References: <200010022119.OAA17662@freefall.freebsd.org> <20001005105720.A1562@turing.maths.tcd.ie> <20001006134808.A87828@walton.maths.tcd.ie> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20001006134808.A87828@walton.maths.tcd.ie>; from dwmalone@maths.tcd.ie on Fri, Oct 06, 2000 at 01:48:08PM +0100 Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org I intend to commit the following patch to bitstring.h. It does the following: 1) fixes the problems with bit_ffs and bit_ffc searching off the end of the bitstring, 2) Makes our version of bitstring.h much more like NetBSD's, adding extra brackets and do { ... } while(0);, 3) Change bitstr_size and bit_alloc to match NetBSD's (same results, neater macros). NetBSD has a different fix for the bitstring problems which produce much slower code according to Bob Wilcox's tests. David. Index: bitstring.h =================================================================== RCS file: /cvs/FreeBSD-CVS/src/include/bitstring.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 bitstring.h --- bitstring.h 1994/05/24 09:57:25 1.1.1.1 +++ bitstring.h 2000/10/07 19:38:17 @@ -53,16 +53,15 @@ /* external macros */ /* bytes in a bitstring of nbits bits */ #define bitstr_size(nbits) \ - ((((nbits) - 1) >> 3) + 1) + (((nbits) + 7) >> 3) /* allocate a bitstring */ #define bit_alloc(nbits) \ - (bitstr_t *)calloc(1, \ - (unsigned int)bitstr_size(nbits) * sizeof(bitstr_t)) + (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t)) /* allocate a bitstring on the stack */ #define bit_decl(name, nbits) \ - (name)[bitstr_size(nbits)] + ((name)[bitstr_size(nbits)]) /* is bit N of bitstring name set? */ #define bit_test(name, bit) \ @@ -70,14 +69,14 @@ /* set bit N of bitstring name */ #define bit_set(name, bit) \ - (name)[_bit_byte(bit)] |= _bit_mask(bit) + ((name)[_bit_byte(bit)] |= _bit_mask(bit)) /* clear bit N of bitstring name */ #define bit_clear(name, bit) \ - (name)[_bit_byte(bit)] &= ~_bit_mask(bit) + ((name)[_bit_byte(bit)] &= ~_bit_mask(bit)) /* clear bits start ... stop in bitstring */ -#define bit_nclear(name, start, stop) { \ +#define bit_nclear(name, start, stop) do { \ register bitstr_t *_name = name; \ register int _start = start, _stop = stop; \ register int _startbyte = _bit_byte(_start); \ @@ -91,10 +90,10 @@ _name[_startbyte] = 0; \ _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ } \ -} +} while (0) /* set bits start ... stop in bitstring */ -#define bit_nset(name, start, stop) { \ +#define bit_nset(name, start, stop) do { \ register bitstr_t *_name = name; \ register int _start = start, _stop = stop; \ register int _startbyte = _bit_byte(_start); \ @@ -108,13 +107,13 @@ _name[_startbyte] = 0xff; \ _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ } \ -} +} while (0) /* find first bit clear in name */ -#define bit_ffc(name, nbits, value) { \ +#define bit_ffc(name, nbits, value) do { \ register bitstr_t *_name = name; \ register int _byte, _nbits = nbits; \ - register int _stopbyte = _bit_byte(_nbits), _value = -1; \ + register int _stopbyte = _bit_byte(_nbits-1), _value = -1; \ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ if (_name[_byte] != 0xff) { \ _value = _byte << 3; \ @@ -122,14 +121,16 @@ ++_value, _stopbyte >>= 1); \ break; \ } \ + if (_value >= nbits) \ + _value = -1; \ *(value) = _value; \ -} +} while (0) /* find first bit set in name */ -#define bit_ffs(name, nbits, value) { \ +#define bit_ffs(name, nbits, value) do { \ register bitstr_t *_name = name; \ register int _byte, _nbits = nbits; \ - register int _stopbyte = _bit_byte(_nbits), _value = -1; \ + register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \ for (_byte = 0; _byte <= _stopbyte; ++_byte) \ if (_name[_byte]) { \ _value = _byte << 3; \ @@ -137,7 +138,9 @@ ++_value, _stopbyte >>= 1); \ break; \ } \ + if (_value >= nbits) \ + _value = -1; \ *(value) = _value; \ -} +} while (0) #endif /* !_BITSTRING_H_ */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message