2014-01-26 01:34:20

by Anderson Lizardo

[permalink] [raw]
Subject: [PATCH BlueZ 1/2] unit/test-ringbuf: Fix indentation

---
unit/test-ringbuf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/unit/test-ringbuf.c b/unit/test-ringbuf.c
index a19216f..e63321c 100644
--- a/unit/test-ringbuf.c
+++ b/unit/test-ringbuf.c
@@ -41,7 +41,8 @@ static unsigned int nlpo2(unsigned int x)
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
- return x + 1;
+
+ return x + 1;
}

static unsigned int align_power2(unsigned int u)
--
1.8.3.2



2014-01-27 17:56:11

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH BlueZ 1/2] unit/test-ringbuf: Fix indentation

Hi Lizardo,

On Sat, Jan 25, 2014, Anderson Lizardo wrote:
> ---
> unit/test-ringbuf.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)

Both patches have been applied. Thanks.

Johan

2014-01-26 01:34:21

by Anderson Lizardo

[permalink] [raw]
Subject: [PATCH BlueZ 2/2] shared: Fix undefined behavior when calculating next power of two

According to GCC documentation, __builtin_clz() is undefined if argument
is zero. The following problem was detected when compiling with -O0:

ERROR:unit/test-ringbuf.c:70:test_power2: assertion failed: (size1 ==
size2)

Also refactor align_power2() so the internal "find last set bit"
operation is in its own fls() function (similar to how kernel does).
fls() checks if argument is zero before calling __builtin_clz().
---
src/shared/ringbuf.c | 9 ++++++++-
unit/test-ringbuf.c | 7 ++++++-
2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/shared/ringbuf.c b/src/shared/ringbuf.c
index 3e5c7d3..f9c4376 100644
--- a/src/shared/ringbuf.c
+++ b/src/shared/ringbuf.c
@@ -48,9 +48,16 @@ struct ringbuf {

#define RINGBUF_RESET 0

+/* Find last (most siginificant) set bit */
+static inline unsigned int fls(unsigned int x)
+{
+ return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
+}
+
+/* Round up to nearest power of two */
static inline unsigned int align_power2(unsigned int u)
{
- return 1 << ((sizeof(u) * 8) - __builtin_clz(u - 1));
+ return 1 << fls(u - 1);
}

struct ringbuf *ringbuf_new(size_t size)
diff --git a/unit/test-ringbuf.c b/unit/test-ringbuf.c
index e63321c..75be3a3 100644
--- a/unit/test-ringbuf.c
+++ b/unit/test-ringbuf.c
@@ -45,9 +45,14 @@ static unsigned int nlpo2(unsigned int x)
return x + 1;
}

+static unsigned int fls(unsigned int x)
+{
+ return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
+}
+
static unsigned int align_power2(unsigned int u)
{
- return 1 << ((sizeof(u) * 8) - __builtin_clz(u - 1));
+ return 1 << fls(u - 1);
}

static void test_power2(void)
--
1.8.3.2