Fix: Filter bytecode alloc buffer size must be a power of 2
authorChristian Babeux <christian.babeux@efficios.com>
Mon, 27 Aug 2012 18:48:19 +0000 (14:48 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Tue, 4 Sep 2012 15:37:09 +0000 (11:37 -0400)
The current allocation policy for the filter bytecode buffer is to
double the size each time the underlying buffer can no longer contain
the entire bytecode plus padding.

In some cases, the initial allocation length is not a multiple of 2,
thus possibly leading to odd-looking allocation size each time the
buffer size is doubled.

Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Christian Babeux <christian.babeux@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c

index 36d35c558727e6df654a55b3bebc1bee4fb069de..71da21c8a5108a8f0114aa9389c16d92bc54240a 100644 (file)
@@ -38,6 +38,45 @@ static
 int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx,
                struct ir_op *node);
 
+static inline int fls(unsigned int x)
+{
+       int r = 32;
+
+       if (!x)
+               return 0;
+       if (!(x & 0xFFFF0000U)) {
+               x <<= 16;
+               r -= 16;
+       }
+       if (!(x & 0xFF000000U)) {
+               x <<= 8;
+               r -= 8;
+       }
+       if (!(x & 0xF0000000U)) {
+               x <<= 4;
+               r -= 4;
+       }
+       if (!(x & 0xC0000000U)) {
+               x <<= 2;
+               r -= 2;
+       }
+       if (!(x & 0x80000000U)) {
+               x <<= 1;
+               r -= 1;
+       }
+       return r;
+}
+
+static inline int get_count_order(unsigned int count)
+{
+       int order;
+
+       order = fls(count) - 1;
+       if (count & (count - 1))
+               order++;
+       return order;
+}
+
 static
 int bytecode_init(struct lttng_filter_bytecode_alloc **fb)
 {
@@ -58,7 +97,7 @@ int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align
 
        if ((*fb)->b.len + padding + len > (*fb)->alloc_len) {
                uint32_t new_len =
-                       max_t(uint32_t, (*fb)->b.len + padding + len,
+                       max_t(uint32_t, 1U << get_count_order((*fb)->b.len + padding + len),
                                (*fb)->alloc_len << 1);
                uint32_t old_len = (*fb)->alloc_len;
 
This page took 0.025406 seconds and 4 git commands to generate.