+static void smalloc_print_bitmap(struct pool *pool)
+{
+ size_t nr_blocks = pool->nr_blocks;
+ unsigned int *bitmap = pool->bitmap;
+ unsigned int i, j;
+ char *buffer;
+
+ if (!enable_smalloc_debug)
+ return;
+
+ buffer = malloc(SMALLOC_BPI + 1);
+ if (!buffer)
+ return;
+ buffer[SMALLOC_BPI] = '\0';
+
+ for (i = 0; i < nr_blocks; i++) {
+ unsigned int line = bitmap[i];
+
+ /* skip completely full lines */
+ if (line == -1U)
+ continue;
+
+ for (j = 0; j < SMALLOC_BPI; j++)
+ if ((1 << j) & line)
+ buffer[SMALLOC_BPI-1-j] = '1';
+ else
+ buffer[SMALLOC_BPI-1-j] = '0';
+
+ log_err("smalloc: bitmap %5u, %s\n", i, buffer);
+ }
+
+ free(buffer);
+}
+
+void smalloc_debug(size_t size)
+{
+ unsigned int i;
+ size_t alloc_size = size_to_alloc_size(size);
+ size_t alloc_blocks;
+
+ alloc_blocks = size_to_blocks(alloc_size);
+
+ if (size)
+ log_err("smalloc: size = %lu, alloc_size = %lu, blocks = %lu\n",
+ (unsigned long) size, (unsigned long) alloc_size,
+ (unsigned long) alloc_blocks);
+ for (i = 0; i < nr_pools; i++) {
+ log_err("smalloc: pool %u, free/total blocks %u/%u\n", i,
+ (unsigned int) (mp[i].free_blocks),
+ (unsigned int) (mp[i].nr_blocks*sizeof(unsigned int)*8));
+ if (size && mp[i].free_blocks >= alloc_blocks) {
+ void *ptr = smalloc_pool(&mp[i], size);
+ if (ptr) {
+ sfree(ptr);
+ last_pool = i;
+ log_err("smalloc: smalloc_pool %u succeeded\n", i);
+ } else {
+ log_err("smalloc: smalloc_pool %u failed\n", i);
+ log_err("smalloc: next_non_full=%u, nr_blocks=%u\n",
+ (unsigned int) mp[i].next_non_full, (unsigned int) mp[i].nr_blocks);
+ smalloc_print_bitmap(&mp[i]);
+ }
+ }
+ }
+}
+