zephyr/include/misc
Nicolas Pitre 744df1ef82 mempool: don't over-size the free block bitmap
Currently, the free block bitmap is roughly 4 times larger than it
needs to, wasting memory.

Let's assume maxsz = 128, minsz = 8 and n_max = 40.

Z_MPOOL_LVLS(128, 8) returns 3. The block size for level #0 is 128,
the block size for level #1 is 128/4 = 32, and the block size for
level #2 is 32/4 = 8. Hence levels 0, 1, and 2 for a total of 3 levels.
So far so good.

Now let's look at Z_MPOOL_LBIT_WORDS(). We get:

Z_MPOOL_LBIT_WORDS_UNCLAMPED(40, 0) = ((40 << 0) + 31) / 32 = 2
Z_MPOOL_LBIT_WORDS_UNCLAMPED(40, 1) = ((40 << 2) + 31) / 32 = 5
Z_MPOOL_LBIT_WORDS_UNCLAMPED(40, 2) = ((40 << 4) + 31) / 32 = 20

None of those are < 2 so Z_MPOOL_LBIT_WORDS() takes the results from
Z_MPOOL_LBIT_WORDS_UNCLAMPED().

Finally, let's look at _MPOOL_BITS_SIZE(. It sums all possible levels
with Z_MPOOL_LBIT_BYTES() which is:

  #define Z_MPOOL_LBIT_BYTES(maxsz, minsz, l, n_max)    \
        (Z_MPOOL_LVLS((maxsz), (minsz)) >= (l) ?        \
         4 * Z_MPOOL_LBIT_WORDS((n_max), l) : 0)

Or given what we already have:

Z_MPOOL_LBIT_BYTES(128, 8, 0, 40) = (3 >= 0) ? 4 * 2  : 0 = 8
Z_MPOOL_LBIT_BYTES(128, 8, 1, 40) = (3 >= 1) ? 4 * 5  : 0 = 20
Z_MPOOL_LBIT_BYTES(128, 8, 2, 40) = (3 >= 2) ? 4 * 20 : 0 = 80
Z_MPOOL_LBIT_BYTES(128, 8, 3, 40) = (3 >= 3) ? 4 * ??

Wait... we're missing this one:

Z_MPOOL_LBIT_WORDS_UNCLAMPED(40, 3) = ((40 << 6) + 31) / 32 = 80

then:

Z_MPOOL_LBIT_BYTES(128, 8, 3, 40) = (3 >= 3) ? 4 * 80 : 0 = 320

Further levels yeld (3 >= 4), (3 >= 5), etc. so they're all false and
produce 0.

So this means that we're statically allocating 428 bytes to the bitmap
when clearly only the first 3 Z_MPOOL_LBIT_BYTES() results for the
corresponding 3 levels that we have should be summed e.g. only
108 bytes.

Here the code logic gets confused between level numbers and the number
levels, hence the extra allocation which happens to be exponential.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2019-06-25 23:24:05 -04:00
..
__assert.h all: Update reserved function names 2019-03-11 13:48:42 -04:00
byteorder.h headers: Fix headers across the project 2018-09-17 15:49:26 -04:00
dlist.h include: Make statements evaluate boolean expressions 2019-03-26 22:06:45 -04:00
errno_private.h headers: Fix headers across the project 2018-09-17 15:49:26 -04:00
fdtable.h net: sockets: implement getsockname function 2019-05-17 22:49:32 +03:00
gcov.h tests: coverage: Add Gcov support. 2019-01-16 06:12:33 -05:00
libc-hooks.h libc: rename _zephyr_fputc to zephyr_fputc 2019-03-12 13:59:06 -05:00
list_gen.h include: Make statements evaluate boolean expressions 2019-03-26 22:06:45 -04:00
math_extras_impl.h misc: Implement math_extras.h function with GCC builtins. 2019-05-14 19:53:30 -05:00
math_extras.h misc: Portable math_extras.h implementations. 2019-05-14 19:53:30 -05:00
mempool_base.h mempool: don't over-size the free block bitmap 2019-06-25 23:24:05 -04:00
mempool.h mempool: fix corruption of the free block bitmap and beyond 2019-06-24 12:10:09 -07:00
mutex.h lib: os: add sys_mutex data type 2019-04-03 13:47:45 -04:00
printk.h printk: make it 64-bit compatible 2019-06-17 10:28:44 -07:00
rb.h C++: Fix compilation error "invalid conversion" 2019-05-03 14:27:07 -04:00
reboot.h headers: Fix headers across the project 2018-09-17 15:49:26 -04:00
ring_buffer.h headers: Fix headers across the project 2018-09-17 15:49:26 -04:00
sflist.h sflist: SYS_SFLIST_FLAGS_MASK must be a long not an int 2019-06-25 23:21:39 -04:00
slist.h include: misc: list_gen: Fix possible undefined behavior 2018-12-07 09:06:34 -05:00
speculation.h doc: fix misspelling in docs and API comments 2019-03-27 15:59:09 -04:00
stack.h logging: use os as a domain for low level system debugging 2019-06-04 12:16:40 -07:00
util.h include: misc: macros to perform word/pointer boundary alignment 2019-06-20 08:42:45 -04:00