[Bro-Dev] [JIRA] (BIT-1424) Add power of 2 test to file(s) 'cq.c/cq.h' (revises BIT-1423)
Bill Parker (JIRA)
jira at bro-tracker.atlassian.net
Tue Jun 9 10:12:00 PDT 2015
Bill Parker created BIT-1424:
--------------------------------
Summary: Add power of 2 test to file(s) 'cq.c/cq.h' (revises BIT-1423)
Key: BIT-1424
URL: https://bro-tracker.atlassian.net/browse/BIT-1424
Project: Bro Issue Tracker
Issue Type: New Feature
Components: Bro
Affects Versions: 2.3
Environment: Enhancement Request in file cq.c
Reporter: Bill Parker
Attachments: cq.c.patch, cq.h.patch
Subj: Add power of 2 test to file(s) 'cq.c/cq.h' (revised)
*This replaces the cq.c code/patch in BIT-1423..*.
Hello All,
Here is a hunk of code which is a FIXME to the following statement:
/* XXX could check that nbuckets is a power of 2 */
In directory 'src', file 'cq.c'
The patch file which adds this test is below:
--- cq.c.orig 2015-06-06 19:01:58.220926680 -0700
+++ cq.c 2015-06-08 18:36:37.323755402 -0700
@@ -414,6 +414,15 @@
return hp->max_qlen;
}
+int cq_IsPowerOfTwo(unsigned int x)
+{
+ /* This function returns one (1) if val is a power of 2, i.e. */
+ /* 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024...2^31 */
+ /* or zero (0) if it isn't a power of two */
+
+ return ((x != 0) && ((x & (~x + 1)) == x));
+}
+
/* Return without doing anything if we fail to allocate a new bucket array */
static int
cq_resize(register struct cq_handle *hp, register int grow)
@@ -422,6 +431,7 @@
register size_t size;
register struct cq_bucket *bp, *bp2, *buckets, *oldbuckets;
struct cq_handle savedhandle;
+ int power_of_2_result; /* for power of two call */
if (hp->noresize)
return (0);
@@ -444,6 +454,11 @@
/* XXX could check that nbuckets is a power of 2 */
+ power_of_2_result = cq_IsPowerOfTwo((unsigned int)nbuckets);
+
+ if (power_of_2_result == 0) /* If this is zero, nbuckets is NOT a power of 2 */
+ return (-1); /* do we need to print a warning/error here as well? */
+
size = sizeof(*buckets) * nbuckets;
buckets = (struct cq_bucket *)malloc(size);
memory_allocation += size;
====================================================================
The function above is a one-liner that can be found on the Web.
The first half of the expression ensures that x is a positive integer.
The second half of the expression, (x & (~x + 1)) == x, is true only
when x is a power of two. It compares x with its two’s complement.
The two’s complement of x is computed with ~x + 1, which inverts the
bits of x and adds 1 (~x + 1 is equivalent to -x, but negation is
technically illegal for an unsigned integer).
Let n be the position of the leftmost 1 bit if x. If x is a power of
two, its lone 1 bit is in position n. This means ~x has a 0 in
position n and 1s everywhere else. When 1 is added to ~x, all
positions below n become 0 and the 0 at position n becomes 1.
In other words, the carry propagates all the way to position n. So
what happens is this: negating x inverts all its bits, but adding
1 inverts them back, from position n on down. So, (x & (~x + 1))
== x is true.
====================================================================
Here is the modification to file 'cq.h' which adds the function
prototype for cq_IsPowerOfTwo:
--- cq.h.orig 2015-06-09 08:35:29.001007785 -0700
+++ cq.h 2015-06-09 08:36:08.194989138 -0700
@@ -5,6 +5,7 @@
void *cq_remove(struct cq_handle *, double, void *);
int cq_size(struct cq_handle *);
int cq_max_size(struct cq_handle *);
+int cq_IsPowerOfTwo(unsigned int);
unsigned int cq_memory_allocation(void);
#ifdef DEBUG
void cq_debug(struct cq_handle *, int);
====================================================================
I am attaching the patch file(s) to this bug report
Bill Parker (wp02855 at gmail dot com)
--
This message was sent by Atlassian JIRA
(v6.5-OD-05-041#65001)
More information about the bro-dev
mailing list