Yes, Maxim I'll revise and send an updated version tomorrow.
Thanks and best regards, Yi On 9 January 2017 at 21:05, Maxim Uvarov <maxim.uva...@linaro.org> wrote: > On 01/05/17 12:12, Yi He wrote: > > O, missing this mail > > > > Hi, Maxim, for the error and warnings it seems the checkpatch.pl > > <http://checkpatch.pl> cannot recognize function pointers usage in macro > > definition, but it is a must in this generic programming practice. For > > those checks are only one space or parenthesize, trying to make code > > looks more clear and easy-reading. > > > > Can we accept these? > > > > Thanks and best regards, Yi > > > > > Hello Yi, sorry for long response I was on winter holidays. > > how about removing METHOD_DECLARE define and declare functions natively? > > Patch for your patch: > > --- /dev/null > +++ b/platform/linux-generic/include/odp_bitmap_internal.h > -@@ -0,0 +1,320 @@ > +@@ -0,0 +1,317 @@ > +/* Copyright (c) 2016, Linaro Limited > + * All rights reserved. > + * > @@ -197,16 +197,13 @@ index 0000000..192c6f9 > + * ...operations on this bit index... > + * } > + */ > -+#define METHOD_DECLARE(_return, _name, _impl, ...) \ > -+ _return (*_name)(struct _impl ## _bitmap_ ## iterator *this) > -+ > +typedef struct wapl_bitmap_iterator { > + int _start, _next, _nbits; > + wapl_bitmap_t _base; > + > -+ METHOD_DECLARE(void, start, wapl); > -+ METHOD_DECLARE(bool, has_next, wapl); > -+ METHOD_DECLARE(unsigned int, next, wapl); > ++ void (*start)(struct wapl_bitmap_iterator *this); > ++ bool (*has_next)(struct wapl_bitmap_iterator *this); > ++ unsigned int (*next)(struct wapl_bitmap_iterator *this); > +} wapl_bitmap_iterator_t; > + > +/* > @@ -298,9 +295,9 @@ index 0000000..192c6f9 > + int _start, _next, _nbits; > + sparse_bitmap_t _base; > + > -+ METHOD_DECLARE(void, start, sparse); > -+ METHOD_DECLARE(bool, has_next, sparse); > -+ METHOD_DECLARE(unsigned int, next, sparse); > ++ void (*start)(struct sparse_bitmap_iterator *this); > ++ bool (*has_next)(struct sparse_bitmap_iterator *this); > ++ unsigned int (*next)(struct sparse_bitmap_iterator *this); > +} sparse_bitmap_iterator_t; > + > +/* > @@ -334,7 +331,7 @@ index 0000000..192c6f9 > +{ > + unsigned long tmp; > + > -+ if (start >= (int) nbits) > ++ if (start >= (int)nbits) > + start = 0; > + > + tmp = addr[BIT_WORD(start)]; > @@ -345,7 +342,7 @@ index 0000000..192c6f9 > + > + while (!tmp) { > + start += BITS_PER_LONG; > -+ if (start >= (int) nbits) > ++ if (start >= (int)nbits) > + start = 0; > + > + tmp = addr[BIT_WORD(start)]; > @@ -366,7 +363,7 @@ index 0000000..192c6f9 > +#endif > diff --git a/platform/linux-generic/odp_bitmap.c > b/platform/linux-generic/odp_bitmap.c > new file mode 100644 > -index 0000000..0f4d051 > +index 0000000..b991114 > --- /dev/null > +++ b/platform/linux-generic/odp_bitmap.c > @@ -0,0 +1,315 @@ > @@ -587,7 +584,7 @@ index 0000000..0f4d051 > + */ > +static void __sparse_iterator_start(sparse_bitmap_iterator_t *this) > +{ > -+ this->_nbits = (int) *(this->_base.last); > ++ this->_nbits = *this->_base.last; > + > + /* Advance to next queue index to start this > + * new round iteration. > > > > > > > > > > > > > > > > On 5 January 2017 at 03:16, Maxim Uvarov <maxim.uva...@linaro.org > > <mailto:maxim.uva...@linaro.org>> wrote: > > > > > > Using patch: 0003-linux-gen-add-generic-bitmaps-and-iterators.patch > > Trying to apply patch > > Patch applied > > WARNING: Prefer ARRAY_SIZE(array) > > #77: FILE: platform/linux-generic/include/odp_bitmap_internal.h:30: > > +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) > > > > ERROR: Macros with complex values should be enclosed in parentheses > > #201: FILE: platform/linux-generic/include/odp_bitmap_internal.h: > 154: > > +#define METHOD_DECLARE(_return, _name, _impl, ...) \ > > + _return (*_name)(struct _impl ## _bitmap_ ## iterator *this) > > > > WARNING: space prohibited between function name and open parenthesis > '(' > > #202: FILE: platform/linux-generic/include/odp_bitmap_internal.h: > 155: > > + _return (*_name)(struct _impl ## _bitmap_ ## iterator *this) > > > > CHECK: No space is necessary after a cast > > #338: FILE: platform/linux-generic/include/odp_bitmap_internal.h: > 291: > > + if (start >= (int) nbits) > > > > CHECK: No space is necessary after a cast > > #349: FILE: platform/linux-generic/include/odp_bitmap_internal.h: > 302: > > + if (start >= (int) nbits) > > > > CHECK: No space is necessary after a cast > > #591: FILE: platform/linux-generic/odp_bitmap.c:218: > > + this->_nbits = (int) *(this->_base.last); > > > > CHECK: Unnecessary parentheses around this->_base.last > > #591: FILE: platform/linux-generic/odp_bitmap.c:218: > > + this->_nbits = (int) *(this->_base.last); > > > > total: 1 errors, 2 warnings, 4 checks, 649 lines checked > > > > NOTE: Ignored message types: BIT_MACRO COMPARISON_TO_NULL > > DEPRECATED_VARIABLE NEW_TYPEDEFS SPLIT_STRING SSCANF_TO_KSTRTO > > > > 0001-linux-gen-add-generic-bitmaps-and-iterators.patch has style > > problems, please review. > > > > > > > > On 12/09/16 13:51, Yi He wrote: > > > Add C++ template alike bitmap<size> to allow > > > instantiate bitmap data structure of any size, > > > and provide iterators to help walking through > > > the bitmap objects. > > > > > > Signed-off-by: Yi He <yi...@linaro.org <mailto:yi...@linaro.org>> > > > --- > > > platform/linux-generic/Makefile.am | 2 + > > > .../linux-generic/include/odp_bitmap_internal.h | 320 > > +++++++++++++++++++++ > > > platform/linux-generic/odp_bitmap.c | 315 > > ++++++++++++++++++++ > > > 3 files changed, 637 insertions(+) > > > create mode 100644 > > platform/linux-generic/include/odp_bitmap_internal.h > > > create mode 100644 platform/linux-generic/odp_bitmap.c > > > > > > diff --git a/platform/linux-generic/Makefile.am > > b/platform/linux-generic/Makefile.am > > > index adbe24d..a6e62ef 100644 > > > --- a/platform/linux-generic/Makefile.am > > > +++ b/platform/linux-generic/Makefile.am > > > @@ -128,6 +128,7 @@ noinst_HEADERS = \ > > > ${srcdir}/include/odp_align_internal.h \ > > > ${srcdir}/include/odp_atomic_internal.h \ > > > ${srcdir}/include/odp_buffer_inlines.h \ > > > + ${srcdir}/include/odp_bitmap_internal.h \ > > > ${srcdir}/include/odp_buffer_internal.h \ > > > ${srcdir}/include/odp_classification_datamodel.h \ > > > ${srcdir}/include/odp_classification_inlines.h \ > > > @@ -171,6 +172,7 @@ __LIB__libodp_linux_la_SOURCES = \ > > > _ishmphy.c \ > > > odp_atomic.c \ > > > odp_barrier.c \ > > > + odp_bitmap.c \ > > > odp_buffer.c \ > > > odp_byteorder.c \ > > > odp_classification.c \ > > > diff --git a/platform/linux-generic/include/odp_bitmap_internal.h > > b/platform/linux-generic/include/odp_bitmap_internal.h > > > new file mode 100644 > > > index 0000000..192c6f9 > > > --- /dev/null > > > +++ b/platform/linux-generic/include/odp_bitmap_internal.h > > > @@ -0,0 +1,320 @@ > > > +/* Copyright (c) 2016, Linaro Limited > > > + * All rights reserved. > > > + * > > > + * SPDX-License-Identifier: BSD-3-Clause > > > + */ > > > + > > > +/** > > > + * @file > > > + * > > > + * ODP generic bitmap types and operations. > > > + */ > > > + > > > +#ifndef ODP_BITMAP_INTERNAL_H_ > > > +#define ODP_BITMAP_INTERNAL_H_ > > > + > > > +#ifdef __cplusplus > > > +extern "C" { > > > +#endif > > > + > > > +#include <stdint.h> > > > +#include <stdbool.h> > > > +#include <string.h> > > > +#include <odp/api/hints.h> > > > + > > > +/* Generate unique identifier for instantiated class */ > > > +#define TOKENIZE(template, line) \ > > > + template ## _ ## line ## _ ## __COUNTER__ > > > + > > > +/* Array size in general */ > > > +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) > > > + > > > +#define BITS_PER_BYTE (8) > > > +#define BITS_PER_LONG __WORDSIZE > > > +#define BYTES_PER_LONG (BITS_PER_LONG / BITS_PER_BYTE) > > > + > > > +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) > > > +#define BITS_TO_LONGS(nr) BIT_WORD(nr + BITS_PER_LONG - 1) > > > + > > > +#define BITMAP_FIRST_WORD_MASK(start) \ > > > + (~0UL << ((start) & (BITS_PER_LONG - 1))) > > > +#define BITMAP_LAST_WORD_MASK(nbits) \ > > > + (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) > > > + > > > +/* WAPL bitmap base class */ > > > +typedef struct { > > > + unsigned int nwords; > > > + unsigned int *pl; > > > + unsigned long *ul; > > > +} wapl_bitmap_t; > > > + > > > +/* > > > + * Word-Aligned Position List (WAPL) bitmap, which actually > > > + * is not a compression, but with an extra list of non-empty > > > + * word positions. > > > + * > > > + * WAPL accelerates bitwise operations and iterations by > > > + * applying only to non-empty positions instead of walking > > > + * through the whole bitmap. > > > + * > > > + * WAPL uses [1 ~ N] instead of [0 ~ N - 1] as position > > > + * values and an extra 0 as end indicator for position list. > > > + * This is the reason to allocate one extra room below. > > > + */ > > > +#define instantiate_wapl_bitmap(line, nbits) \ > > > + struct TOKENIZE(wapl_bitmap, line) { \ > > > + unsigned int pl[BITS_TO_LONGS(nbits) + 1]; \ > > > + unsigned long ul[BITS_TO_LONGS(nbits) + 1]; \ > > > + } > > > + > > > +#define WAPL_BITMAP(nbits) instantiate_wapl_bitmap(__LINE__, > nbits) > > > + > > > +/* > > > + * Upcast any derived WAPL bitmap class to its base class > > > + */ > > > +#define __wapl_upcast(base, derived) \ > > > + do { \ > > > + __typeof__(derived) p = derived; \ > > > + base.pl <http://base.pl> = p->pl; > > \ > > > + base.ul = p->ul; \ > > > + base.nwords = ARRAY_SIZE(p->ul) - 1; \ > > > + } while (0) > > > + > > > +/* > > > + * WAPL base class bitmap operations > > > + */ > > > +void __wapl_bitmap_and(wapl_bitmap_t *dst, > > > + wapl_bitmap_t *src, wapl_bitmap_t *and); > > > + > > > +void __wapl_bitmap_or(wapl_bitmap_t *dst, wapl_bitmap_t *or); > > > + > > > +void __wapl_bitmap_set(wapl_bitmap_t *map, unsigned int bit); > > > + > > > +void __wapl_bitmap_clear(wapl_bitmap_t *map, unsigned int bit); > > > + > > > +/* > > > + * Generic WAPL bitmap operations > > > + */ > > > +#define wapl_bitmap_zero(map) > > \ > > > + ({ \ > > > + __typeof__(map) p = map; \ > > > + memset((void *)p, 0, sizeof(__typeof__(*p))); \ > > > + }) > > > + > > > +#define wapl_bitmap_copy(dst, src) \ > > > + ({ \ > > > + __typeof__(dst) d = dst; \ > > > + __typeof__(src) s = src; \ > > > + if (d != s) \ > > > + memcpy((void *)d, (void *)s, \ > > > + sizeof(__typeof__(*d))); \ > > > + }) > > > + > > > +#define wapl_bitmap_and(dst, src, and) > > \ > > > + ({ \ > > > + wapl_bitmap_t d, s, a; \ > > > + __wapl_upcast(d, dst); \ > > > + __wapl_upcast(s, src); \ > > > + __wapl_upcast(a, and); \ > > > + __wapl_bitmap_and(&d, &s, &a); \ > > > + }) > > > + > > > +#define wapl_bitmap_or(dst, src, or) \ > > > + ({ \ > > > + wapl_bitmap_t d, o; \ > > > + wapl_bitmap_copy(dst, src); \ > > > + __wapl_upcast(d, dst); \ > > > + __wapl_upcast(o, or); \ > > > + __wapl_bitmap_or(&d, &o); \ > > > + }) > > > + > > > +#define wapl_bitmap_set(map, bit) \ > > > + ({ \ > > > + wapl_bitmap_t b; \ > > > + __wapl_upcast(b, map); \ > > > + __wapl_bitmap_set(&b, bit); \ > > > + }) > > > + > > > +#define wapl_bitmap_clear(map, bit) \ > > > + ({ \ > > > + wapl_bitmap_t b; \ > > > + __wapl_upcast(b, map); \ > > > + __wapl_bitmap_clear(&b, bit); \ > > > + }) > > > + > > > +/* > > > + * Round robin iterator runs upon a WAPL bitmap: > > > + * > > > + * wapl_bitmap_iterator(iterator, WAPL bitmap); > > > + * for (iterator->start(); iterator->has_next(); ) { > > > + * unsigned int bit_index = iterator->next(); > > > + * ...operations on this bit index... > > > + * } > > > + */ > > > +#define METHOD_DECLARE(_return, _name, _impl, ...) \ > > > + _return (*_name)(struct _impl ## _bitmap_ ## iterator *this) > > > + > > > +typedef struct wapl_bitmap_iterator { > > > + int _start, _next, _nbits; > > > + wapl_bitmap_t _base; > > > + > > > + METHOD_DECLARE(void, start, wapl); > > > + METHOD_DECLARE(bool, has_next, wapl); > > > + METHOD_DECLARE(unsigned int, next, wapl); > > > +} wapl_bitmap_iterator_t; > > > + > > > +/* > > > + * WAPL bitmap iterator constructor > > > + */ > > > +void __wapl_bitmap_iterator(wapl_bitmap_iterator_t *this); > > > + > > > +/* > > > + * Generic constructor accepts any derived WAPL bitmap class > > > + */ > > > +#define wapl_bitmap_iterator(iterator, map) \ > > > + ({ \ > > > + __typeof__(iterator) __it = iterator; \ > > > + __wapl_upcast(__it->_base, map); \ > > > + __wapl_bitmap_iterator(__it); \ > > > + }) > > > + > > > +/* Sparse bitmap base class */ > > > +typedef struct { > > > + unsigned int nbits; > > > + unsigned int *last, *pl, *il; > > > +} sparse_bitmap_t; > > > + > > > +/* > > > + * Sparse bitmap, lists all bit indexes directly as an array. > > > + * Expected to be significantly straightforward iteration. > > > + */ > > > +#define instantiate_sparse_bitmap(line, nbits) > > \ > > > + struct TOKENIZE(sparse_bitmap, line) { \ > > > + unsigned int last; \ > > > + unsigned int pl[nbits]; \ > > > + unsigned int il[nbits]; \ > > > + } > > > + > > > +#define SPARSE_BITMAP(nbits) instantiate_sparse_bitmap(__LINE__, > > nbits) > > > + > > > +/* > > > + * Upcast any derived sparse bitmap class to its base class > > > + */ > > > +#define __sparse_upcast(base, derived) > > \ > > > + do { \ > > > + __typeof__(derived) p = derived; \ > > > + base.pl <http://base.pl> = p->pl; > > \ > > > + base.il <http://base.il> = p->il; > > \ > > > + base.last = &p->last; \ > > > + base.nbits = ARRAY_SIZE(p->il); \ > > > + } while (0) > > > + > > > +/* > > > + * Sparse base class bitmap operations > > > + */ > > > +void __sparse_bitmap_set(sparse_bitmap_t *map, unsigned int bit); > > > + > > > +void __sparse_bitmap_clear(sparse_bitmap_t *map, unsigned int > bit); > > > + > > > +/* > > > + * Generic sparse bitmap operations > > > + */ > > > +#define sparse_bitmap_zero(map) > > \ > > > + ({ \ > > > + __typeof__(map) p = map; \ > > > + memset((void *)p, 0, sizeof(__typeof__(*p))); \ > > > + }) > > > + > > > +#define sparse_bitmap_set(map, bit) \ > > > + ({ \ > > > + sparse_bitmap_t b; \ > > > + __sparse_upcast(b, map); \ > > > + __sparse_bitmap_set(&b, bit); \ > > > + }) > > > + > > > +#define sparse_bitmap_clear(map, bit) > > \ > > > + ({ \ > > > + sparse_bitmap_t b; \ > > > + __sparse_upcast(b, map); \ > > > + __sparse_bitmap_clear(&b, bit); \ > > > + }) > > > + > > > +/* > > > + * Round robin iterator runs upon a sparse bitmap: > > > + * > > > + * sparse_bitmap_iterator(iterator, SPARSE bitmap); > > > + * for (iterator->start(); iterator->has_next(); ) { > > > + * unsigned int bit_index = iterator->next(); > > > + * ...operations on this bit index... > > > + * } > > > + */ > > > +typedef struct sparse_bitmap_iterator { > > > + int _start, _next, _nbits; > > > + sparse_bitmap_t _base; > > > + > > > + METHOD_DECLARE(void, start, sparse); > > > + METHOD_DECLARE(bool, has_next, sparse); > > > + METHOD_DECLARE(unsigned int, next, sparse); > > > +} sparse_bitmap_iterator_t; > > > + > > > +/* > > > + * Sparse bitmap iterator constructor > > > + */ > > > +void __sparse_bitmap_iterator(sparse_bitmap_iterator_t *this); > > > + > > > +/* > > > + * Generic constructor accepts any derived sparse bitmap class. > > > + */ > > > +#define sparse_bitmap_iterator(iterator, map) > > \ > > > + ({ \ > > > + __typeof__(iterator) __it = iterator; \ > > > + __sparse_upcast(__it->_base, map); \ > > > + __sparse_bitmap_iterator(__it); \ > > > + }) > > > + > > > +/* > > > + * Raw bitmap atomic set and clear. > > > + */ > > > +void raw_bitmap_set(unsigned long *map, unsigned int bit); > > > + > > > +void raw_bitmap_clear(unsigned long *map, unsigned int bit); > > > + > > > +/* > > > + * It will enter infinite loop incase that all bits are zero, > > > + * so please make sure the bitmap at least has one set. > > > + */ > > > +static inline int __bitmap_wraparound_next( > > > + unsigned long *addr, unsigned int nbits, int start) > > > +{ > > > + unsigned long tmp; > > > + > > > + if (start >= (int) nbits) > > > + start = 0; > > > + > > > + tmp = addr[BIT_WORD(start)]; > > > + > > > + /* Handle 1st word. */ > > > + tmp &= BITMAP_FIRST_WORD_MASK(start); > > > + start = start & ~(BITS_PER_LONG - 1); > > > + > > > + while (!tmp) { > > > + start += BITS_PER_LONG; > > > + if (start >= (int) nbits) > > > + start = 0; > > > + > > > + tmp = addr[BIT_WORD(start)]; > > > + } > > > + > > > + start += __builtin_ffsl(tmp) - 1; > > > + return start; > > > +} > > > + > > > +/** > > > + * @} > > > + */ > > > + > > > +#ifdef __cplusplus > > > +} > > > +#endif > > > + > > > +#endif > > > diff --git a/platform/linux-generic/odp_bitmap.c > > b/platform/linux-generic/odp_bitmap.c > > > new file mode 100644 > > > index 0000000..0f4d051 > > > --- /dev/null > > > +++ b/platform/linux-generic/odp_bitmap.c > > > @@ -0,0 +1,315 @@ > > > +/* Copyright (c) 2016, Linaro Limited > > > + * All rights reserved. > > > + * > > > + * SPDX-License-Identifier: BSD-3-Clause > > > + */ > > > + > > > +#include <string.h> > > > +#include <unistd.h> > > > +#include <odp/api/std_types.h> > > > +#include <odp/api/byteorder.h> > > > +#include <odp_bitmap_internal.h> > > > + > > > +/* > > > + * WAPL base class bitmap operations > > > + */ > > > +static inline void __wapl_add_pos( > > > + wapl_bitmap_t *map, unsigned int p) > > > +{ > > > + unsigned int s, k = 0; > > > + unsigned int *pl = map->pl; > > > + > > > + while (pl[k] && p > pl[k]) > > > + k++; > > > + > > > + if (p == pl[k]) > > > + return; > > > + > > > + /* sorted insertion */ > > > + for (; pl[k] && p < pl[k]; k++) { > > > + s = pl[k]; > > > + pl[k] = p; > > > + p = s; > > > + } > > > + > > > + if (k < map->nwords) > > > + pl[k++] = p; > > > + > > > + pl[k] = 0; > > > +} > > > + > > > +static inline void __wapl_remove_pos( > > > + wapl_bitmap_t *map, unsigned int p) > > > +{ > > > + unsigned int k = 0; > > > + unsigned int *pl = map->pl; > > > + > > > + while (pl[k] && p != pl[k]) > > > + k++; > > > + > > > + for (; pl[k]; k++) > > > + pl[k] = pl[k + 1]; > > > +} > > > + > > > +void __wapl_bitmap_and(wapl_bitmap_t *dst, > > > + wapl_bitmap_t *src, wapl_bitmap_t *and) > > > +{ > > > + unsigned int k = 0, p; > > > + unsigned int *pl = src->pl; > > > + > > > + while ((p = *pl++) != 0) { > > > + dst->ul[p] = src->ul[p] & and->ul[p]; > > > + if (dst->ul[p]) > > > + dst->pl[k++] = p; > > > + } > > > + > > > + dst->pl[k] = 0; > > > +} > > > + > > > +void __wapl_bitmap_or(wapl_bitmap_t *dst, wapl_bitmap_t *or) > > > +{ > > > + unsigned int p; > > > + unsigned int *pl = or->pl; > > > + > > > + while ((p = *pl++) != 0) { > > > + if (dst->ul[p] == 0) > > > + __wapl_add_pos(dst, p); > > > + > > > + dst->ul[p] |= or->ul[p]; > > > + } > > > +} > > > + > > > +void __wapl_bitmap_set(wapl_bitmap_t *map, unsigned int bit) > > > +{ > > > + unsigned int p = BIT_WORD(bit) + 1; > > > + unsigned long set = 1UL << (bit & (BITS_PER_LONG - 1)); > > > + > > > + if (p > map->nwords) > > > + return; > > > + > > > + if (map->ul[p] == 0) > > > + __wapl_add_pos(map, p); > > > + > > > + map->ul[p] |= set; > > > +} > > > + > > > +void __wapl_bitmap_clear(wapl_bitmap_t *map, unsigned int bit) > > > +{ > > > + unsigned int p = BIT_WORD(bit) + 1; > > > + unsigned long clear = 1UL << (bit & (BITS_PER_LONG - 1)); > > > + > > > + if (p > map->nwords) > > > + return; > > > + > > > + map->ul[p] &= ~clear; > > > + > > > + if (map->ul[p] == 0) > > > + __wapl_remove_pos(map, p); > > > +} > > > + > > > +/* > > > + * WAPL bitmap iterator implementation > > > + */ > > > +static void __wapl_iterator_start(wapl_bitmap_iterator_t *this) > > > +{ > > > + this->_nbits = this->_base.nwords * BITS_PER_LONG; > > > + > > > + /* Advance to next queue index to start this > > > + * new round iteration. > > > + */ > > > + if (this->_base.pl <http://base.pl>[0] == 0) > > > + this->_start = -1; > > > + else > > > + this->_start = __bitmap_wraparound_next( > > > + &this->_base.ul[1], this->_nbits, > > this->_start + 1); > > > + > > > + this->_next = this->_start; > > > +} > > > + > > > +static bool __wapl_iterator_has_next(wapl_bitmap_iterator_t > *this) > > > +{ > > > + return (this->_next != -1); > > > +} > > > + > > > +static unsigned int __wapl_iterator_next(wapl_bitmap_iterator_t > > *this) > > > +{ > > > + int next = this->_next; > > > + > > > + this->_next = __bitmap_wraparound_next( > > > + &this->_base.ul[1], this->_nbits, > > this->_next + 1); > > > + > > > + if (this->_next == this->_start) > > > + this->_next = -1; > > > + > > > + return next; > > > +} > > > + > > > +void __wapl_bitmap_iterator(wapl_bitmap_iterator_t *this) > > > +{ > > > + this->start = __wapl_iterator_start; > > > + this->has_next = __wapl_iterator_has_next; > > > + this->next = __wapl_iterator_next; > > > + > > > + this->_start = -1; > > > + this->_next = this->_start; > > > +} > > > + > > > +/* > > > + * Sparse base class bitmap operations > > > + */ > > > +void __sparse_bitmap_set(sparse_bitmap_t *map, unsigned int bit) > > > +{ > > > + unsigned int last = *map->last; > > > + > > > + /* Index exceeds */ > > > + if (bit >= map->nbits) > > > + return; > > > + > > > + /* Full bitmap */ > > > + if (last >= map->nbits) > > > + return; > > > + > > > + /* Bit was not set previously, > > > + * also record where we set the bit > > > + */ > > > + if (!map->pl[bit]) { > > > + map->il[last++] = bit; > > > + map->pl[bit] = last; > > > + > > > + *map->last = last; > > > + } > > > +} > > > + > > > +void __sparse_bitmap_clear(sparse_bitmap_t *map, unsigned int > bit) > > > +{ > > > + unsigned int p, i; > > > + unsigned int last = *map->last; > > > + > > > + /* Index exceeds */ > > > + if (bit >= map->nbits) > > > + return; > > > + > > > + /* Empty bitmap */ > > > + if (last == 0) > > > + return; > > > + > > > + /* Bit was set previously */ > > > + if (map->pl[bit]) { > > > + p = map->pl[bit] - 1; > > > + map->pl[bit] = 0; > > > + > > > + last--; > > > + *map->last = last; > > > + > > > + /* Fill the hole with the latest index */ > > > + if (p < last) { > > > + i = map->il[last]; > > > + map->pl[i] = p + 1; > > > + map->il[p] = i; > > > + } > > > + } > > > +} > > > + > > > +/* > > > + * Sparse bitmap iterator implementation > > > + */ > > > +static void __sparse_iterator_start(sparse_bitmap_iterator_t > *this) > > > +{ > > > + this->_nbits = (int) *(this->_base.last); > > > + > > > + /* Advance to next queue index to start this > > > + * new round iteration. > > > + */ > > > + if (this->_nbits == 0) > > > + this->_start = -1; > > > + else > > > + this->_start = (this->_start + 1) & (this->_nbits - > 1); > > > + > > > + this->_next = this->_start; > > > +} > > > + > > > +static bool __sparse_iterator_has_next(sparse_bitmap_iterator_t > > *this) > > > +{ > > > + return (this->_next != -1); > > > +} > > > + > > > +static unsigned int > > __sparse_iterator_next(sparse_bitmap_iterator_t *this) > > > +{ > > > + int next = this->_next; > > > + > > > + this->_next = (this->_next + 1) & (this->_nbits - 1); > > > + if (this->_next == this->_start) > > > + this->_next = -1; > > > + > > > + return this->_base.il <http://base.il>[next]; > > > +} > > > + > > > +void __sparse_bitmap_iterator(sparse_bitmap_iterator_t *this) > > > +{ > > > + this->start = __sparse_iterator_start; > > > + this->has_next = __sparse_iterator_has_next; > > > + this->next = __sparse_iterator_next; > > > + > > > + this->_start = -1; > > > + this->_next = this->_start; > > > +} > > > + > > > +/* > > > + * Generic byte-width atomic set/clear > > > + */ > > > +static inline void atomic_byte_set( > > > + unsigned char *addr, unsigned int bit) > > > +{ > > > + unsigned char load, store; > > > + unsigned char set = 1 << (bit & (BITS_PER_BYTE - 1)); > > > + > > > + do { > > > + load = *addr; > > > + store = load | set; > > > + } while (!__atomic_compare_exchange_n(addr, &load, store, > > > + 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED)); > > > +} > > > + > > > +static inline void atomic_byte_clear( > > > + unsigned char *addr, unsigned int bit) > > > +{ > > > + unsigned char load, store; > > > + unsigned char clear = 1 << (bit & (BITS_PER_BYTE - 1)); > > > + > > > + do { > > > + load = *addr; > > > + store = load & ~clear; > > > + } while (!__atomic_compare_exchange_n(addr, &load, store, > > > + 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED)); > > > +} > > > + > > > +static inline unsigned char *__bit_byte( > > > + unsigned long *word, unsigned int bit) > > > +{ > > > + unsigned int i; > > > + unsigned char *b; > > > + > > > + b = (unsigned char *)word; > > > + > > > + i = bit & (BITS_PER_LONG - 1); > > > + i = i / BITS_PER_BYTE; > > > + > > > +#if (ODP_BYTE_ORDER == ODP_BIG_ENDIAN) > > > + i = BYTES_PER_LONG - 1 - i; > > > +#endif > > > + return &b[i]; > > > +} > > > + > > > +void raw_bitmap_set(unsigned long *map, unsigned int bit) > > > +{ > > > + unsigned long *p = map + BIT_WORD(bit); > > > + > > > + atomic_byte_set(__bit_byte(p, bit), bit); > > > +} > > > + > > > +void raw_bitmap_clear(unsigned long *map, unsigned int bit) > > > +{ > > > + unsigned long *p = map + BIT_WORD(bit); > > > + > > > + atomic_byte_clear(__bit_byte(p, bit), bit); > > > +} > > > -- > > > 2.7.4 > > > > > > > > >