| 112 | } |
| 113 | |
| 114 | void * |
| 115 | pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg) |
| 116 | { |
| 117 | struct alloc_pool *pool = (struct alloc_pool *) p; |
| 118 | if (!pool) |
| 119 | return NULL; |
| 120 | |
| 121 | if (!len) |
| 122 | len = pool->quantum; |
| 123 | else if (pool->flags & POOL_QALIGN_P2) { |
| 124 | if (len & (pool->quantum - 1)) |
| 125 | len += pool->quantum - (len & (pool->quantum - 1)); |
| 126 | } else if (!(pool->flags & POOL_NO_QALIGN)) { |
| 127 | if (len % pool->quantum) |
| 128 | len += pool->quantum - len % pool->quantum; |
| 129 | } |
| 130 | |
| 131 | if (len > pool->size) |
| 132 | goto bomb_out; |
| 133 | |
| 134 | if (!pool->extents || len > pool->extents->free) { |
| 135 | void *start; |
| 136 | size_t asize; |
| 137 | struct pool_extent *ext; |
| 138 | |
| 139 | asize = pool->size; |
| 140 | if (pool->flags & POOL_PREPEND) |
| 141 | asize += sizeof (struct pool_extent); |
| 142 | |
| 143 | if (!(start = new_array(char, asize))) |
| 144 | goto bomb_out; |
| 145 | |
| 146 | if (pool->flags & POOL_CLEAR) |
| 147 | memset(start, 0, asize); |
| 148 | |
| 149 | if (pool->flags & POOL_PREPEND) { |
| 150 | ext = start; |
| 151 | start = PTR_ADD(start, sizeof (struct pool_extent)); |
| 152 | } else if (!(ext = new(struct pool_extent))) |
| 153 | goto bomb_out; |
| 154 | ext->start = start; |
| 155 | ext->free = pool->size; |
| 156 | ext->bound = 0; |
| 157 | ext->next = pool->extents; |
| 158 | pool->extents = ext; |
| 159 | |
| 160 | pool->e_created++; |
| 161 | } |
| 162 | |
| 163 | pool->n_allocated++; |
| 164 | pool->b_allocated += len; |
| 165 | |
| 166 | pool->extents->free -= len; |
| 167 | |
| 168 | return PTR_ADD(pool->extents->start, pool->extents->free); |
| 169 | |
| 170 | bomb_out: |
| 171 | if (pool->bomb) |
no outgoing calls
no test coverage detected