Page MenuHomeFreeBSD

D1408.id2943.diff
No OneTemporary

D1408.id2943.diff

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

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)

Event Timeline