Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157281705
D1408.id2943.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
42 KB
Referenced Files
None
Subscribers
None
D1408.id2943.diff
View Options
Index: sbin/hastd/activemap.c
===================================================================
--- sbin/hastd/activemap.c
+++ sbin/hastd/activemap.c
@@ -33,12 +33,13 @@
#include <sys/param.h> /* powerof2() */
#include <sys/queue.h>
-#include <bitstring.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
+#include <bitstring.h>
#include <pjdlog.h>
@@ -162,7 +163,7 @@
amp->am_extentsize = extentsize;
amp->am_extentshift = bitcount32(extentsize - 1);
amp->am_nextents = ((mediasize - 1) / extentsize) + 1;
- amp->am_mapsize = sizeof(bitstr_t) * bitstr_size(amp->am_nextents);
+ amp->am_mapsize = bitstr_size(amp->am_nextents);
amp->am_diskmapsize = roundup2(amp->am_mapsize, sectorsize);
amp->am_ndirty = 0;
amp->am_syncoff = -2;
Index: sbin/hastd/nv.c
===================================================================
--- sbin/hastd/nv.c
+++ sbin/hastd/nv.c
@@ -33,13 +33,14 @@
#include <sys/param.h>
#include <sys/endian.h>
-#include <bitstring.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
+#include <bitstring.h>
#include <unistd.h>
#include <ebuf.h>
Index: share/man/man3/bitstring.3
===================================================================
--- share/man/man3/bitstring.3
+++ share/man/man3/bitstring.3
@@ -30,14 +30,17 @@
.\" @(#)bitstring.3 8.1 (Berkeley) 7/19/93
.\" $FreeBSD$
.\"
-.Dd July 19, 1993
+.Dd December 31, 2014
.Dt BITSTRING 3
.Os
.Sh NAME
.Nm bit_alloc ,
.Nm bit_clear ,
.Nm bit_decl ,
+.Nm bit_ffc ,
+.Nm bit_ffc_at ,
.Nm bit_ffs ,
+.Nm bit_ffs_at ,
.Nm bit_nclear ,
.Nm bit_nset ,
.Nm bit_set ,
@@ -45,6 +48,8 @@
.Nm bit_test
.Nd bit-string manipulation macros
.Sh SYNOPSIS
+.In stdlib.h
+.In strings.h
.In bitstring.h
.Ft bitstr_t *
.Fn bit_alloc "int nbits"
@@ -55,8 +60,12 @@
.Ft void
.Fn bit_ffc "bitstr_t *name" "int nbits" "int *value"
.Ft void
+.Fn bit_ffc_at "bitstr_t *name" "int startbit" "int nbits" "int *value"
+.Ft void
.Fn bit_ffs "bitstr_t *name" "int nbits" "int *value"
.Ft void
+.Fn bit_ffs_at "bitstr_t *name" "int startbit" "int nbits" "int *value"
+.Ft void
.Fn bit_nclear "bitstr_t *name" "int start" "int stop"
.Ft void
.Fn bit_nset "bitstr_t *name" "int start" "int stop"
@@ -69,7 +78,7 @@
.Sh DESCRIPTION
These macros operate on strings of bits.
.Pp
-The macro
+The function
.Fn bit_alloc
returns a pointer of type
.Dq Fa "bitstr_t *"
@@ -81,9 +90,9 @@
.Pp
The macro
.Fn bit_decl
-allocates sufficient space to store
+declares a bitstring_t array with sufficient space to store
.Fa nbits
-bits on the stack.
+bits.
.Pp
The macro
.Fn bitstr_size
@@ -94,7 +103,7 @@
bits.
This is useful for copying bit strings.
.Pp
-The macros
+The functions
.Fn bit_clear
and
.Fn bit_set
@@ -107,7 +116,7 @@
.Fn bit_nset
and
.Fn bit_nclear
-macros
+functions
set or clear the zero-based numbered bits from
.Fa start
through
@@ -117,7 +126,7 @@
.Pp
The
.Fn bit_test
-macro
+function
evaluates to non-zero if the zero-based numbered bit
.Fa bit
of bit string
@@ -126,7 +135,7 @@
.Pp
The
.Fn bit_ffs
-macro
+function
stores in the location referenced by
.Fa value
the zero-based number of the first bit set in the array of
@@ -137,7 +146,22 @@
.Fa value
is set to \-1.
.Pp
-The macro
+The
+.Fn bit_ffs_at
+function
+stores in the location referenced by
+.Fa value
+the zero-based number of the first bit set in the array of
+.Fa nbits
+bits referenced by
+.Fa name
+that occurs at or after the bit at the zero-based position
+.Fa startbit .
+If no bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The function
.Fn bit_ffc
stores in the location referenced by
.Fa value
@@ -149,11 +173,27 @@
.Fa value
is set to \-1.
.Pp
-The arguments to these macros are evaluated only once and may safely
+The function
+.Fn bit_ffc_at
+stores in the location referenced by
+.Fa value
+the zero-based number of the first bit not set in the array of
+.Fa nbits
+bits referenced by
+.Fa name
+taht occurs at or after the bit at the zero-based position
+.Fa startbit .
+If all bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The arguments to bit string macros are evaluated only once and may safely
have side effects.
.Sh EXAMPLES
.Bd -literal -offset indent
#include <limits.h>
+#include <stdlib.h>
+#include <strings.h>
#include <bitstring.h>
\&...
Index: share/man/man9/bitstring.9
===================================================================
--- /dev/null
+++ share/man/man9/bitstring.9
@@ -0,0 +1,230 @@
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Vixie.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)bitstring.3 8.1 (Berkeley) 7/19/93
+.\" $FreeBSD$
+.\"
+.Dd December 31, 2014
+.Dt BITSTRING 9
+.Os
+.Sh NAME
+.Nm bit_alloc ,
+.Nm bit_clear ,
+.Nm bit_decl ,
+.Nm bit_ffc ,
+.Nm bit_ffc_at ,
+.Nm bit_ffs ,
+.Nm bit_ffs_at ,
+.Nm bit_nclear ,
+.Nm bit_nset ,
+.Nm bit_set ,
+.Nm bitstr_size ,
+.Nm bit_test
+.Nd bit-string manipulation macros
+.Sh SYNOPSIS
+.In sys/malloc.h
+.In sys/systm.h
+.In sys/bitstring.h
+.Ft bitstr_t *
+.Fn bit_alloc "int nbits" "struct malloc_type *type" "int flags"
+.Ft void
+.Fn bit_decl "bitstr_t *name" "int nbits"
+.Ft void
+.Fn bit_clear "bitstr_t *name" "int bit"
+.Ft void
+.Fn bit_ffc "bitstr_t *name" "int nbits" "int *value"
+.Ft void
+.Fn bit_ffc_at "bitstr_t *name" "int startbit" "int nbits" "int *value"
+.Ft void
+.Fn bit_ffs "bitstr_t *name" "int nbits" "int *value"
+.Ft void
+.Fn bit_ffs_at "bitstr_t *name" "int startbit" "int nbits" "int *value"
+.Ft void
+.Fn bit_nclear "bitstr_t *name" "int start" "int stop"
+.Ft void
+.Fn bit_nset "bitstr_t *name" "int start" "int stop"
+.Ft void
+.Fn bit_set "bitstr_t *name" "int bit"
+.Ft int
+.Fn bitstr_size "int nbits"
+.Ft int
+.Fn bit_test "bitstr_t *name" "int bit"
+.Sh DESCRIPTION
+These macros operate on strings of bits.
+.Pp
+The function
+.Fn bit_alloc
+returns a pointer of type
+.Dq Fa "bitstr_t *"
+to sufficient space to store
+.Fa nbits
+bits, or
+.Dv NULL
+if no space is available.
+The
+.Fa type
+and
+.Fa flags
+arguments are passed through to the kernel memory allocator.
+.Pp
+The macro
+.Fn bit_decl
+declares a bitstring_t array with sufficient space to store
+.Fa nbits
+bits.
+.Pp
+The macro
+.Fn bitstr_size
+returns the number of elements of type
+.Fa bitstr_t
+necessary to store
+.Fa nbits
+bits.
+This is useful for copying bit strings.
+.Pp
+The functions
+.Fn bit_clear
+and
+.Fn bit_set
+clear or set the zero-based numbered bit
+.Fa bit ,
+in the bit string
+.Ar name .
+.Pp
+The
+.Fn bit_nset
+and
+.Fn bit_nclear
+functions
+set or clear the zero-based numbered bits from
+.Fa start
+through
+.Fa stop
+in the bit string
+.Ar name .
+.Pp
+The
+.Fn bit_test
+function
+evaluates to non-zero if the zero-based numbered bit
+.Fa bit
+of bit string
+.Fa name
+is set, and zero otherwise.
+.Pp
+The
+.Fn bit_ffs
+function
+stores in the location referenced by
+.Fa value
+the zero-based number of the first bit set in the array of
+.Fa nbits
+bits referenced by
+.Fa name .
+If no bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The
+.Fn bit_ffs_at
+function
+stores in the location referenced by
+.Fa value
+the zero-based number of the first bit set in the array of
+.Fa nbits
+bits referenced by
+.Fa name
+that occurs at or after the bit at the zero-based position
+.Fa startbit .
+If no bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The function
+.Fn bit_ffc
+stores in the location referenced by
+.Fa value
+the zero-based number of the first bit not set in the array of
+.Fa nbits
+bits referenced by
+.Fa name .
+If all bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The function
+.Fn bit_ffc_at
+stores in the location referenced by
+.Fa value
+the zero-based number of the first bit not set in the array of
+.Fa nbits
+bits referenced by
+.Fa name
+taht occurs at or after the bit at the zero-based position
+.Fa startbit .
+If all bits are set, the location referenced by
+.Fa value
+is set to \-1.
+.Pp
+The arguments to bit string macros are evaluated only once and may safely
+have side effects.
+.Sh EXAMPLES
+.Bd -literal -offset indent
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <sys/bitstring.h>
+
+\&...
+#define LPR_BUSY_BIT 0
+#define LPR_FORMAT_BIT 1
+#define LPR_DOWNLOAD_BIT 2
+\&...
+#define LPR_AVAILABLE_BIT 9
+#define LPR_MAX_BITS 10
+
+make_lpr_available()
+{
+ bitstr_t bit_decl(bitlist, LPR_MAX_BITS);
+ ...
+ bit_nclear(bitlist, 0, LPR_MAX_BITS - 1);
+ ...
+ if (!bit_test(bitlist, LPR_BUSY_BIT)) {
+ bit_clear(bitlist, LPR_FORMAT_BIT);
+ bit_clear(bitlist, LPR_DOWNLOAD_BIT);
+ bit_set(bitlist, LPR_AVAILABLE_BIT);
+ }
+}
+.Ed
+.Sh SEE ALSO
+.Xr malloc 9
+.Sh HISTORY
+The
+.Nm bitstring
+functions first appeared in
+.Bx 4.4 .
Index: sys/dev/xen/blkback/blkback.c
===================================================================
--- sys/dev/xen/blkback/blkback.c
+++ sys/dev/xen/blkback/blkback.c
@@ -3026,10 +3026,6 @@
return 0;
}
-/* Needed to make bit_alloc() macro work */
-#define calloc(count, size) malloc((count)*(size), M_XENBLOCKBACK, \
- M_NOWAIT|M_ZERO);
-
/**
* Size KVA and pseudo-physical address allocations based on negotiated
* values for the size and number of I/O requests, and the size of our
@@ -3048,7 +3044,8 @@
xbb->kva_size = xbb->reqlist_kva_size +
(xbb->ring_config.ring_pages * PAGE_SIZE);
- xbb->kva_free = bit_alloc(xbb->reqlist_kva_pages);
+ xbb->kva_free = bit_alloc(xbb->reqlist_kva_pages,
+ M_XENBLOCKBACK, M_WAITOK);
if (xbb->kva_free == NULL)
return (ENOMEM);
Index: sys/kern/subr_unit.c
===================================================================
--- sys/kern/subr_unit.c
+++ sys/kern/subr_unit.c
@@ -68,7 +68,6 @@
*/
#include <sys/types.h>
-#include <sys/bitstring.h>
#include <sys/_unrhdr.h>
#ifdef _KERNEL
@@ -77,6 +76,7 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/systm.h>
+#include <sys/bitstring.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -101,6 +101,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
+#include <bitstring.h>
#define KASSERT(cond, arg) \
do { \
@@ -164,7 +166,7 @@
* element:
* If ptr is NULL, it represents a run of free items.
* If ptr points to the unrhdr it represents a run of allocated items.
- * Otherwise it points to an bitstring of allocated items.
+ * Otherwise it points to a bitstring of allocated items.
*
* For runs the len field is the length of the run.
* For bitmaps the len field represents the number of allocated items.
@@ -177,15 +179,55 @@
void *ptr;
};
-struct unrb {
- u_char busy;
- bitstr_t map[sizeof(struct unr) - 1];
+union unrb {
+ bitstr_t map[sizeof(struct unr) / sizeof(bitstr_t)];
+ u_char bytes[sizeof(struct unr)];
};
-CTASSERT(sizeof(struct unr) == sizeof(struct unrb));
+CTASSERT((sizeof(struct unr) % sizeof(bitstr_t)) == 0);
+
+/*
+ * Number of bits we can store in the bitmap and still
+ * leave space for ub_busy.
+ */
+#define NBITS ((sizeof(union unrb) - 1) * 8)
-/* Number of bits in the bitmap */
-#define NBITS ((int)sizeof(((struct unrb *)NULL)->map) * 8)
+/*
+ * The location of the bitmap busy count within the last 8 bits
+ * of the declared bitmap.
+ */
+static inline u_char *
+ub_busy_ptr(union unrb *ub)
+{
+ if (BYTE_ORDER == LITTLE_ENDIAN)
+ return (&ub->bytes[sizeof(ub->bytes) - 1]);
+ else
+ return (&ub->bytes[sizeof(ub->bytes) - sizeof(bitstr_t)]);
+}
+
+static inline u_char
+ub_busy_get(union unrb *ub)
+{
+ return (*ub_busy_ptr(ub));
+}
+
+static inline void
+ub_busy_set(union unrb *ub, u_char value)
+{
+ *ub_busy_ptr(ub) = value;
+}
+
+static inline void
+ub_busy_inc(union unrb *ub, u_char value)
+{
+ *ub_busy_ptr(ub) += value;
+}
+
+static inline void
+ub_busy_dec(union unrb *ub, u_char value)
+{
+ *ub_busy_ptr(ub) -= value;
+}
#if defined(DIAGNOSTIC) || !defined(_KERNEL)
/*
@@ -199,7 +241,7 @@
check_unrhdr(struct unrhdr *uh, int line)
{
struct unr *up;
- struct unrb *ub;
+ union unrb *ub;
u_int x, y, z, w;
y = uh->first;
@@ -209,16 +251,16 @@
if (up->ptr != uh && up->ptr != NULL) {
ub = up->ptr;
KASSERT (up->len <= NBITS,
- ("UNR inconsistency: len %u max %d (line %d)\n",
+ ("UNR inconsistency: len %u max %zd (line %d)\n",
up->len, NBITS, line));
z++;
w = 0;
for (x = 0; x < up->len; x++)
if (bit_test(ub->map, x))
w++;
- KASSERT (w == ub->busy,
+ KASSERT (w == ub_busy_get(ub),
("UNR inconsistency: busy %u found %u (line %d)\n",
- ub->busy, w, line));
+ ub_busy_get(ub), w, line));
y += w;
} else if (up->ptr != NULL)
y += up->len;
@@ -365,7 +407,7 @@
optimize_unr(struct unrhdr *uh)
{
struct unr *up, *uf, *us;
- struct unrb *ub, *ubf;
+ union unrb *ub, *ubf;
u_int a, l, ba;
/*
@@ -412,10 +454,10 @@
a = us->len;
l = us->ptr == uh ? 1 : 0;
ub = (void *)us;
- ub->busy = 0;
+ ub_busy_set(ub, 0);
if (l) {
bit_nset(ub->map, 0, a);
- ub->busy += a;
+ ub_busy_inc(ub, a);
} else {
bit_nclear(ub->map, 0, a);
}
@@ -424,7 +466,7 @@
bit_nclear(ub->map, a, a + uf->len - 1);
} else {
bit_nset(ub->map, a, a + uf->len - 1);
- ub->busy += uf->len;
+ ub_busy_inc(ub, uf->len);
}
uf->ptr = ub;
uf->len += a;
@@ -434,7 +476,7 @@
for (l = 0; l < uf->len; l++, a++) {
if (bit_test(ubf->map, l)) {
bit_set(ub->map, a);
- ub->busy++;
+ ub_busy_inc(ub, 1);
} else {
bit_clear(ub->map, a);
}
@@ -459,7 +501,7 @@
delete_unr(uh, uf);
} else if (uf->ptr == uh) {
bit_nset(ub->map, us->len, us->len + uf->len - 1);
- ub->busy += uf->len;
+ ub_busy_inc(ub, uf->len);
us->len += uf->len;
TAILQ_REMOVE(&uh->head, uf, list);
delete_unr(uh, uf);
@@ -468,7 +510,7 @@
for (l = 0; l < uf->len; l++, us->len++) {
if (bit_test(ubf->map, l)) {
bit_set(ub->map, us->len);
- ub->busy++;
+ ub_busy_inc(ub, 1);
} else {
bit_clear(ub->map, us->len);
}
@@ -489,15 +531,15 @@
collapse_unr(struct unrhdr *uh, struct unr *up)
{
struct unr *upp;
- struct unrb *ub;
+ union unrb *ub;
/* If bitmap is all set or clear, change it to runlength */
if (is_bitmap(uh, up)) {
ub = up->ptr;
- if (ub->busy == up->len) {
+ if (ub_busy_get(ub) == up->len) {
delete_unr(uh, up->ptr);
up->ptr = uh;
- } else if (ub->busy == 0) {
+ } else if (ub_busy_get(ub) == 0) {
delete_unr(uh, up->ptr);
up->ptr = NULL;
}
@@ -561,7 +603,7 @@
alloc_unrl(struct unrhdr *uh)
{
struct unr *up;
- struct unrb *ub;
+ union unrb *ub;
u_int x;
int y;
@@ -595,11 +637,11 @@
up->len--;
} else { /* bitmap */
ub = up->ptr;
- KASSERT(ub->busy < up->len, ("UNR bitmap confusion"));
+ KASSERT(ub_busy_get(ub) < up->len, ("UNR bitmap confusion"));
bit_ffc(ub->map, up->len, &y);
KASSERT(y != -1, ("UNR corruption: No clear bit in bitmap."));
bit_set(ub->map, y);
- ub->busy++;
+ ub_busy_inc(ub, 1);
x += y;
}
uh->busy++;
@@ -623,7 +665,7 @@
alloc_unr_specificl(struct unrhdr *uh, u_int item, void **p1, void **p2)
{
struct unr *up, *upn;
- struct unrb *ub;
+ union unrb *ub;
u_int i, last, tl;
mtx_assert(uh->mtx, MA_OWNED);
@@ -683,7 +725,7 @@
ub = up->ptr;
if (bit_test(ub->map, i) == 0) {
bit_set(ub->map, i);
- ub->busy++;
+ ub_busy_inc(ub, 1);
goto done;
} else
return (-1);
@@ -754,7 +796,7 @@
free_unrl(struct unrhdr *uh, u_int item, void **p1, void **p2)
{
struct unr *up, *upp, *upn;
- struct unrb *ub;
+ union unrb *ub;
u_int pl;
KASSERT(item >= uh->low && item <= uh->high,
@@ -802,7 +844,7 @@
("UNR: Freeing free item %d (bitmap)\n", item));
bit_clear(ub->map, item);
uh->busy--;
- ub->busy--;
+ ub_busy_dec(ub, 1);
collapse_unr(uh, up);
return;
}
@@ -887,7 +929,7 @@
print_unr(struct unrhdr *uh, struct unr *up)
{
u_int x;
- struct unrb *ub;
+ union unrb *ub;
printf(" %p len = %5u ", up, up->len);
if (up->ptr == NULL)
@@ -896,7 +938,7 @@
printf("alloc\n");
else {
ub = up->ptr;
- printf("bitmap(%d) [", ub->busy);
+ printf("bitmap(%d) [", ub_busy_get(ub));
for (x = 0; x < up->len; x++) {
if (bit_test(ub->map, x))
printf("#");
@@ -981,9 +1023,9 @@
srandomdev();
fprintf(stderr, "sizeof(struct unr) %zu\n", sizeof(struct unr));
- fprintf(stderr, "sizeof(struct unrb) %zu\n", sizeof(struct unrb));
+ fprintf(stderr, "sizeof(union unrb) %zu\n", sizeof(union unrb));
fprintf(stderr, "sizeof(struct unrhdr) %zu\n", sizeof(struct unrhdr));
- fprintf(stderr, "NBITS %d\n", NBITS);
+ fprintf(stderr, "NBITS %zd\n", NBITS);
x = 1;
for (m = 0; m < NN * 100; m++) {
j = random();
Index: sys/netgraph/bluetooth/socket/ng_btsocket.c
===================================================================
--- sys/netgraph/bluetooth/socket/ng_btsocket.c
+++ sys/netgraph/bluetooth/socket/ng_btsocket.c
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/bitstring.h>
#include <sys/errno.h>
#include <sys/domain.h>
Index: sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c
===================================================================
--- sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c
+++ sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/bitstring.h>
#include <sys/domain.h>
#include <sys/endian.h>
@@ -41,7 +42,6 @@
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
-#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/priv.h>
Index: sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
===================================================================
--- sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
+++ sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/bitstring.h>
#include <sys/domain.h>
#include <sys/endian.h>
@@ -41,7 +42,6 @@
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
-#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/protosw.h>
Index: sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
===================================================================
--- sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
+++ sys/netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/bitstring.h>
#include <sys/domain.h>
#include <sys/errno.h>
@@ -40,7 +41,6 @@
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
-#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/priv.h>
Index: sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
===================================================================
--- sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
+++ sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/bitstring.h>
#include <sys/domain.h>
#include <sys/endian.h>
@@ -41,7 +42,6 @@
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
-#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/proc.h>
Index: sys/netgraph/bluetooth/socket/ng_btsocket_sco.c
===================================================================
--- sys/netgraph/bluetooth/socket/ng_btsocket_sco.c
+++ sys/netgraph/bluetooth/socket/ng_btsocket_sco.c
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <sys/bitstring.h>
#include <sys/domain.h>
#include <sys/endian.h>
@@ -41,7 +42,6 @@
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
-#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/protosw.h>
Index: sys/sys/bitstring.h
===================================================================
--- sys/sys/bitstring.h
+++ sys/sys/bitstring.h
@@ -29,118 +29,234 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * Copyright (c) 2014 Spectra Logic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
* $FreeBSD$
*/
#ifndef _SYS_BITSTRING_H_
#define _SYS_BITSTRING_H_
-typedef unsigned char bitstr_t;
+typedef unsigned long bitstr_t;
-/* internal macros */
- /* byte of the bitstring bit is in */
-#define _bit_byte(bit) \
- ((bit) >> 3)
-
- /* mask for the bit within its byte */
-#define _bit_mask(bit) \
- (1 << ((bit)&0x7))
-
-/* external macros */
- /* bytes in a bitstring of nbits bits */
-#define bitstr_size(nbits) \
- (((nbits) + 7) >> 3)
-
- /* allocate a bitstring */
-#define bit_alloc(nbits) \
- (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
+/*---------------------- Private Implementation Details ----------------------*/
+#define _BITSTR_MASK (~0UL)
+#define _BITSTR_BITS (sizeof(bitstr_t) * 8)
+
+/* Index of the bitstr_t in a bit string that contains bit '_bit'. */
+static inline int
+_bit_idx(int _bit)
+{
+ return (_bit / _BITSTR_BITS);
+}
+
+/* Bit number within the bitstr_t at '_bit_idx(_bit)'. */
+static inline int
+_bit_offset(int _bit)
+{
+ return (_bit % _BITSTR_BITS);
+}
+
+/* Mask for the testing/setting '_bit' within its bittstr_t. */
+static inline bitstr_t
+_bit_mask(int _bit)
+{
+ return (1UL << _bit_offset(_bit));
+}
+
+/* Construct a bitstr_t with bits '_start' ... '_stop' inclusive set. */
+static inline bitstr_t
+_bit_make_mask(int _start, int _stop)
+{
+ return ((_BITSTR_MASK << _bit_offset(_start)) &
+ (_BITSTR_MASK >> (_BITSTR_BITS - _bit_offset(_stop) - 1)));
+}
+
+/*----------------------------- Public Interface -----------------------------*/
+/* Number of bytes consumed by a bit string of '_nbits' bits */
+#define bitstr_size(_nbits) (((_nbits) + _BITSTR_BITS - 1) / 8)
+
+/* Allocate a bit string of size '_nbits', initialized with no bits set. */
+#ifdef _KERNEL
+static inline bitstr_t *
+bit_alloc(int _nbits, struct malloc_type *_type, int _flags)
+{
+ return ((bitstr_t *)malloc(bitstr_size(_nbits), _type,
+ _flags | M_ZERO));
+}
+#else
+static inline bitstr_t *
+bit_alloc(int _nbits)
+{
+ return ((bitstr_t *)calloc(bitstr_size(_nbits), 1));
+}
+#endif
- /* allocate a bitstring on the stack */
+/* Declare a bit string, for stack or datastructure use, of size '_nbits'. */
#define bit_decl(name, nbits) \
- ((name)[bitstr_size(nbits)])
+ ((name)[bitstr_size(nbits) / sizeof(bitstr_t)])
- /* is bit N of bitstring name set? */
-#define bit_test(name, bit) \
- ((name)[_bit_byte(bit)] & _bit_mask(bit))
-
- /* set bit N of bitstring name */
-#define bit_set(name, 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))
-
- /* clear bits start ... stop in bitstring */
-#define bit_nclear(name, start, stop) do { \
- register bitstr_t *_name = (name); \
- register int _start = (start), _stop = (stop); \
- register int _startbyte = _bit_byte(_start); \
- register int _stopbyte = _bit_byte(_stop); \
- if (_startbyte == _stopbyte) { \
- _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \
- (0xff << ((_stop&0x7) + 1))); \
- } else { \
- _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \
- while (++_startbyte < _stopbyte) \
- _name[_startbyte] = 0; \
- _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \
- } \
-} while (0)
-
- /* set bits start ... stop in bitstring */
-#define bit_nset(name, start, stop) do { \
- register bitstr_t *_name = (name); \
- register int _start = (start), _stop = (stop); \
- register int _startbyte = _bit_byte(_start); \
- register int _stopbyte = _bit_byte(_stop); \
- if (_startbyte == _stopbyte) { \
- _name[_startbyte] |= ((0xff << (_start&0x7)) & \
- (0xff >> (7 - (_stop&0x7)))); \
- } else { \
- _name[_startbyte] |= 0xff << ((_start)&0x7); \
- while (++_startbyte < _stopbyte) \
- _name[_startbyte] = 0xff; \
- _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \
- } \
-} while (0)
-
- /* find first bit clear in name */
-#define bit_ffc(name, nbits, value) do { \
- register bitstr_t *_name = (name); \
- register int _byte, _nbits = (nbits); \
- register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
- if (_nbits > 0) \
- for (_byte = 0; _byte <= _stopbyte; ++_byte) \
- if (_name[_byte] != 0xff) { \
- bitstr_t _lb; \
- _value = _byte << 3; \
- for (_lb = _name[_byte]; (_lb&0x1); \
- ++_value, _lb >>= 1); \
- break; \
- } \
- if (_value >= nbits) \
- _value = -1; \
- *(value) = _value; \
-} while (0)
-
- /* find first bit set in name */
-#define bit_ffs(name, nbits, value) do { \
- register bitstr_t *_name = (name); \
- register int _byte, _nbits = (nbits); \
- register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
- if (_nbits > 0) \
- for (_byte = 0; _byte <= _stopbyte; ++_byte) \
- if (_name[_byte]) { \
- bitstr_t _lb; \
- _value = _byte << 3; \
- for (_lb = _name[_byte]; !(_lb&0x1); \
- ++_value, _lb >>= 1); \
- break; \
- } \
- if (_value >= nbits) \
- _value = -1; \
- *(value) = _value; \
-} while (0)
+/* Is bit '_bit' of bit string '_bitstr' set? */
+static inline int
+bit_test(const bitstr_t *_bitstr, int _bit)
+{
+ return ((_bitstr[_bit_idx(_bit)] & _bit_mask(_bit)) != 0);
+}
+
+/* Set bit '_bit' of bit string '_bitstr'. */
+static inline void
+bit_set(bitstr_t *_bitstr, int _bit)
+{
+ _bitstr[_bit_idx(_bit)] |= _bit_mask(_bit);
+}
+
+/* Clear bit '_bit' of bit string '_bitstr'. */
+static inline void
+bit_clear(bitstr_t *_bitstr, int _bit)
+{
+ _bitstr[_bit_idx(_bit)] &= ~_bit_mask(_bit);
+}
+
+/* Set bits '_start' ... '_stop' inclusive in bit string '_bitstr'. */
+static inline void
+bit_nset(bitstr_t *_bitstr, int _start, int _stop)
+{
+ bitstr_t *_stopbitstr;
+
+ _stopbitstr = _bitstr + _bit_idx(_stop);
+ _bitstr += _bit_idx(_start);
+
+ if (_bitstr == _stopbitstr) {
+ *_bitstr |= _bit_make_mask(_start, _stop);
+ } else {
+ *_bitstr |= _bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (++_bitstr < _stopbitstr)
+ *_bitstr = _BITSTR_MASK;
+ *_stopbitstr |= _bit_make_mask(0, _stop);
+ }
+}
+
+/* Clear bits '_start' ... '_stop' inclusive in bit string '_bitstr'. */
+static inline void
+bit_nclear(bitstr_t *_bitstr, int _start, int _stop)
+{
+ bitstr_t *_stopbitstr;
+
+ _stopbitstr = _bitstr + _bit_idx(_stop);
+ _bitstr += _bit_idx(_start);
+
+ if (_bitstr == _stopbitstr) {
+ *_bitstr &= ~_bit_make_mask(_start, _stop);
+ } else {
+ *_bitstr &= ~_bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (++_bitstr < _stopbitstr)
+ *_bitstr = 0;
+ *_stopbitstr &= ~_bit_make_mask(0, _stop);
+ }
+}
+
+/*
+ * Find the first bit set in bit string '_bitstr', at or after
+ * bit '_start'.
+ */
+static inline void
+bit_ffs_at(bitstr_t *_bitstr, int _start, int _nbits, int *_result)
+{
+ bitstr_t *_curbitstr;
+ bitstr_t *_stopbitstr;
+ bitstr_t _test;
+ int _value, _offset;
+
+ if (_nbits > 0) {
+ _curbitstr = _bitstr + _bit_idx(_start);
+ _stopbitstr = _bitstr + _bit_idx(_nbits - 1);
+
+ _test = *_curbitstr;
+ if (_bit_offset(_start) != 0)
+ _test &= _bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (_test == 0 && _curbitstr < _stopbitstr)
+ _test = *(++_curbitstr);
+
+ _offset = ffsl(_test);
+ _value = ((_curbitstr - _bitstr) * _BITSTR_BITS) + _offset - 1;
+ if (_offset == 0 || _value >= _nbits)
+ _value = -1;
+ } else {
+ _value = -1;
+ }
+ *_result = _value;
+}
+
+/*
+ * Find the first bit clear in bit string '_bitstr', at or after
+ * bit '_start'.
+ */
+static inline void
+bit_ffc_at(bitstr_t *_bitstr, int _start, int _nbits, int *_result)
+{
+ bitstr_t *_curbitstr;
+ bitstr_t *_stopbitstr;
+ bitstr_t _test;
+ int _value, _offset;
+
+ if (_nbits > 0) {
+ _curbitstr = _bitstr + _bit_idx(_start);
+ _stopbitstr = _bitstr + _bit_idx(_nbits - 1);
+
+ _test = *_curbitstr;
+ if (_bit_offset(_start) != 0)
+ _test |= _bit_make_mask(0, _start - 1);
+ while (_test == _BITSTR_MASK && _curbitstr < _stopbitstr)
+ _test = *(++_curbitstr);
+
+ _offset = ffsl(~_test);
+ _value = ((_curbitstr - _bitstr) * _BITSTR_BITS) + _offset - 1;
+ if (_offset == 0 || _value >= _nbits)
+ _value = -1;
+ } else {
+ _value = -1;
+ }
+ *_result = _value;
+}
+
+/* Find the first bit set in bit string '_bitstr'. */
+static inline void
+bit_ffs(bitstr_t *_bitstr, int _nbits, int *_result)
+{
+ bit_ffs_at(_bitstr, /*start*/0, _nbits, _result);
+}
+
+/* Find the first bit clear in bit string '_bitstr'. */
+static inline void
+bit_ffc(bitstr_t *_bitstr, int _nbits, int *_result)
+{
+ bit_ffc_at(_bitstr, /*start*/0, _nbits, _result);
+}
-#endif /* !_SYS_BITSTRING_H_ */
+#endif /* _SYS_BITSTRING_H_ */
Index: tests/sys/Makefile
===================================================================
--- tests/sys/Makefile
+++ tests/sys/Makefile
@@ -7,6 +7,7 @@
TESTS_SUBDIRS+= kern
TESTS_SUBDIRS+= netinet
TESTS_SUBDIRS+= opencrypto
+TESTS_SUBDIRS+= sys
# Items not integrated into kyua runs by default
SUBDIR+= pjdfstest
Index: tests/sys/sys/Makefile
===================================================================
--- /dev/null
+++ tests/sys/sys/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/sys
+
+ATF_TESTS_C= bitstring_test
+
+WARNS?= 5
+
+.include <bsd.test.mk>
Index: tests/sys/sys/bitstring_test.c
===================================================================
--- /dev/null
+++ tests/sys/sys/bitstring_test.c
@@ -0,0 +1,360 @@
+/*-
+ * Copyright (c) 2014 Spectra Logic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+
+#include <sys/bitstring.h>
+
+typedef void (testfunc_t)(bitstr_t *bstr, int nbits, const char *memloc);
+
+static void
+bitstring_run_stack_test(testfunc_t *test, int nbits)
+{
+ bitstr_t bit_decl(bitstr, nbits);
+
+ test(bitstr, nbits, "stack");
+}
+
+static void
+bitstring_run_heap_test(testfunc_t *test, int nbits)
+{
+ bitstr_t *bitstr = bit_alloc(nbits);
+
+ test(bitstr, nbits, "heap");
+}
+
+static void
+bitstring_test_runner(testfunc_t *test)
+{
+ const int bitstr_sizes[] = {
+ 0,
+ 1,
+ _BITSTR_BITS - 1,
+ _BITSTR_BITS,
+ _BITSTR_BITS + 1,
+ 2 * _BITSTR_BITS - 1,
+ 2 * _BITSTR_BITS,
+ 1023,
+ 1024
+ };
+
+ for (unsigned long i = 0; i < nitems(bitstr_sizes); i++) {
+ bitstring_run_stack_test(test, bitstr_sizes[i]);
+ bitstring_run_heap_test(test, bitstr_sizes[i]);
+ }
+}
+
+#define BITSTRING_TC_DEFINE(name) \
+ATF_TC_WITHOUT_HEAD(name); \
+static testfunc_t name ## _test; \
+ \
+ATF_TC_BODY(name, tc) \
+{ \
+ bitstring_test_runner(name ## _test); \
+} \
+ \
+static void \
+name ## _test(bitstr_t *bitstr, int nbits, const char *memloc)
+
+#define BITSTRING_TC_ADD(tp, name) \
+do { \
+ ATF_TP_ADD_TC(tp, name); \
+} while (0)
+
+ATF_TC_WITHOUT_HEAD(bitstr_in_struct);
+ATF_TC_BODY(bitstr_in_struct, tc)
+{
+ struct bitstr_containing_struct {
+ bitstr_t bit_decl(bitstr, 8);
+ } test_struct;
+
+ bit_nclear(test_struct.bitstr, 0, 8);
+}
+
+BITSTRING_TC_DEFINE(bit_set)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ memset(bitstr, 0, bitstr_size(nbits));
+
+ for (int i = 0; i < nbits; i++) {
+ bit_set(bitstr, i);
+
+ for (int j = 0; j < nbits; j++) {
+ ATF_REQUIRE_MSG(bit_test(bitstr, j) == (j == i) ? 1 : 0,
+ "bit_set_%d_%s: Failed on bit %d",
+ nbits, memloc, i);
+ }
+
+ bit_clear(bitstr, i);
+ }
+}
+
+BITSTRING_TC_DEFINE(bit_clear)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ int i, j;
+
+ memset(bitstr, 0xFF, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_clear(bitstr, i);
+
+ for (j = 0; j < nbits; j++) {
+ ATF_REQUIRE_MSG(bit_test(bitstr, j) == (j == i) ? 0 : 1,
+ "bit_clear_%d_%s: Failed on bit %d",
+ nbits, memloc, i);
+ }
+
+ bit_set(bitstr, i);
+ }
+}
+
+BITSTRING_TC_DEFINE(bit_ffs)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ int i;
+ int found_set_bit;
+
+ memset(bitstr, 0, bitstr_size(nbits));
+ bit_ffs(bitstr, nbits, &found_set_bit);
+ ATF_REQUIRE_MSG(found_set_bit == -1,
+ "bit_ffs_%d_%s: Failed all clear bits.", nbits, memloc);
+
+ for (i = 0; i < nbits; i++) {
+ memset(bitstr, 0xFF, bitstr_size(nbits));
+ if (i > 0)
+ bit_nclear(bitstr, 0, i - 1);
+
+ bit_ffs(bitstr, nbits, &found_set_bit);
+ ATF_REQUIRE_MSG(found_set_bit == i,
+ "bit_ffs_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_set_bit);
+ }
+}
+
+BITSTRING_TC_DEFINE(bit_ffc)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ int i;
+ int found_clear_bit;
+
+ memset(bitstr, 0xFF, bitstr_size(nbits));
+ bit_ffc(bitstr, nbits, &found_clear_bit);
+ ATF_REQUIRE_MSG(found_clear_bit == -1,
+ "bit_ffc_%d_%s: Failed all set bits.", nbits, memloc);
+
+ for (i = 0; i < nbits; i++) {
+ memset(bitstr, 0, bitstr_size(nbits));
+ if (i > 0)
+ bit_nset(bitstr, 0, i - 1);
+
+ bit_ffc(bitstr, nbits, &found_clear_bit);
+ ATF_REQUIRE_MSG(found_clear_bit == i,
+ "bit_ffc_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_clear_bit);
+ }
+}
+
+BITSTRING_TC_DEFINE(bit_ffs_at)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ int i;
+ int found_set_bit;
+
+ memset(bitstr, 0xFF, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffs_at(bitstr, i, nbits, &found_set_bit);
+ ATF_REQUIRE_MSG(found_set_bit == i,
+ "bit_ffs_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_set_bit);
+ }
+
+ memset(bitstr, 0, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffs_at(bitstr, i, nbits, &found_set_bit);
+ ATF_REQUIRE_MSG(found_set_bit == -1,
+ "bit_ffs_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_set_bit);
+ }
+
+ memset(bitstr, 0x55, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffs_at(bitstr, i, nbits, &found_set_bit);
+ if (i == nbits - 1 && (nbits & 1) == 0) {
+ ATF_REQUIRE_MSG(found_set_bit == -1,
+ "bit_ffs_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_set_bit);
+ } else {
+ ATF_REQUIRE_MSG(found_set_bit == i + (i & 1),
+ "bit_ffs_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_set_bit);
+ }
+ }
+
+ memset(bitstr, 0xAA, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffs_at(bitstr, i, nbits, &found_set_bit);
+ if (i == nbits - 1 && (nbits & 1) != 0) {
+ ATF_REQUIRE_MSG(found_set_bit == -1,
+ "bit_ffs_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_set_bit);
+ } else {
+ ATF_REQUIRE_MSG(
+ found_set_bit == i + ((i & 1) ? 0 : 1),
+ "bit_ffs_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_set_bit);
+ }
+ }
+}
+
+BITSTRING_TC_DEFINE(bit_ffc_at)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ int i;
+ int found_clear_bit;
+
+ memset(bitstr, 0, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffc_at(bitstr, i, nbits, &found_clear_bit);
+ ATF_REQUIRE_MSG(found_clear_bit == i,
+ "bit_ffc_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_clear_bit);
+ }
+
+ memset(bitstr, 0xFF, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffc_at(bitstr, i, nbits, &found_clear_bit);
+ ATF_REQUIRE_MSG(found_clear_bit == -1,
+ "bit_ffc_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_clear_bit);
+ }
+
+ memset(bitstr, 0x55, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffc_at(bitstr, i, nbits, &found_clear_bit);
+ if (i == nbits - 1 && (nbits & 1) != 0) {
+ ATF_REQUIRE_MSG(found_clear_bit == -1,
+ "bit_ffc_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_clear_bit);
+ } else {
+ ATF_REQUIRE_MSG(
+ found_clear_bit == i + ((i & 1) ? 0 : 1),
+ "bit_ffc_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_clear_bit);
+ }
+ }
+
+ memset(bitstr, 0xAA, bitstr_size(nbits));
+ for (i = 0; i < nbits; i++) {
+ bit_ffc_at(bitstr, i, nbits, &found_clear_bit);
+ if (i == nbits - 1 && (nbits & 1) == 0) {
+ ATF_REQUIRE_MSG(found_clear_bit == -1,
+ "bit_ffc_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_clear_bit);
+ } else {
+ ATF_REQUIRE_MSG(found_clear_bit == i + (i & 1),
+ "bit_ffc_at_%d_%s: Failed on bit %d, Result %d",
+ nbits, memloc, i, found_clear_bit);
+ }
+ }
+}
+
+BITSTRING_TC_DEFINE(bit_nclear)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ int i, j;
+ int found_set_bit;
+ int found_clear_bit;
+
+ for (i = 0; i < nbits; i++) {
+ for (j = i; j < nbits; j++) {
+ memset(bitstr, 0xFF, bitstr_size(nbits));
+ bit_nclear(bitstr, i, j);
+
+ bit_ffc(bitstr, nbits, &found_clear_bit);
+ ATF_REQUIRE_MSG(
+ found_clear_bit == i,
+ "bit_nclear_%d_%d_%d%s: Failed with result %d",
+ nbits, i, j, memloc, found_clear_bit);
+
+ bit_ffs_at(bitstr, i, nbits, &found_set_bit);
+ ATF_REQUIRE_MSG(
+ (j + 1 < nbits) ? found_set_bit == j + 1 : -1,
+ "bit_nset_%d_%d_%d%s: Failed with result %d",
+ nbits, i, j, memloc, found_set_bit);
+ }
+ }
+}
+
+BITSTRING_TC_DEFINE(bit_nset)
+/* bitstr_t *bitstr, int nbits, const char *memloc */
+{
+ int i, j;
+ int found_set_bit;
+ int found_clear_bit;
+
+ for (i = 0; i < nbits; i++) {
+ for (j = i; j < nbits; j++) {
+ memset(bitstr, 0, bitstr_size(nbits));
+ bit_nset(bitstr, i, j);
+
+ bit_ffs(bitstr, nbits, &found_set_bit);
+ ATF_REQUIRE_MSG(
+ found_set_bit == i,
+ "bit_nset_%d_%d_%d%s: Failed with result %d",
+ nbits, i, j, memloc, found_set_bit);
+
+ bit_ffc_at(bitstr, i, nbits, &found_clear_bit);
+ ATF_REQUIRE_MSG(
+ (j + 1 < nbits) ? found_clear_bit == j + 1 : -1,
+ "bit_nset_%d_%d_%d%s: Failed with result %d",
+ nbits, i, j, memloc, found_clear_bit);
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, bitstr_in_struct);
+ BITSTRING_TC_ADD(tp, bit_set);
+ BITSTRING_TC_ADD(tp, bit_clear);
+ BITSTRING_TC_ADD(tp, bit_ffs);
+ BITSTRING_TC_ADD(tp, bit_ffc);
+ BITSTRING_TC_ADD(tp, bit_ffs_at);
+ BITSTRING_TC_ADD(tp, bit_ffc_at);
+ BITSTRING_TC_ADD(tp, bit_nclear);
+ BITSTRING_TC_ADD(tp, bit_nset);
+ return atf_no_error();
+}
Index: usr.sbin/cron/cron/cron.h
===================================================================
--- usr.sbin/cron/cron/cron.h
+++ usr.sbin/cron/cron/cron.h
@@ -30,7 +30,6 @@
#include <sys/param.h>
#include "compat.h"
-#include <bitstring.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -38,6 +37,9 @@
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <bitstring.h>
#include <time.h>
#include <sys/wait.h>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, May 20, 11:58 PM (11 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33364245
Default Alt Text
D1408.id2943.diff (42 KB)
Attached To
Mode
D1408: Improve performance and add "find at" APIs to bitstring(3)
Attached
Detach File
Event Timeline
Log In to Comment