| 2159 | } |
| 2160 | |
| 2161 | static void *malloc_impl(struct malloc_pool_s *pool, size_t size, bool lock) |
| 2162 | { |
| 2163 | if (size == 0) |
| 2164 | return MA_ZERO; |
| 2165 | size += sizeof(struct malloc_node_s); |
| 2166 | size_t size128 = size / MA_UNIT + (size % MA_UNIT? 1: 0); |
| 2167 | if (size128 > UINT32_MAX) |
| 2168 | { |
| 2169 | errno = ENOMEM; |
| 2170 | return NULL; |
| 2171 | } |
| 2172 | |
| 2173 | pool = pool_init(pool); |
| 2174 | if (lock && mutex_lock(&pool->mutex) < 0) |
| 2175 | return NULL; |
| 2176 | |
| 2177 | uint32_t n = pool->root, parent = MA_NIL; |
| 2178 | uint32_t lb = MA_POOL_LB(pool), ub = MA_POOL_UB(pool); |
| 2179 | bool left = false; |
| 2180 | while (true) |
| 2181 | { |
| 2182 | if (n == MA_NIL) |
| 2183 | break; |
| 2184 | uint32_t l = MA_LEFT(pool, n), r = MA_RIGHT(pool, n); |
| 2185 | if (size128 <= MA_GAP(pool, n)) |
| 2186 | { |
| 2187 | // Inner |
| 2188 | uint32_t lgap = (l != MA_NIL? |
| 2189 | MA_MAX(MA_GAP(pool, l), n - MA_UB(pool, l)): 0); |
| 2190 | if (size128 <= lgap) |
| 2191 | { |
| 2192 | ub = n; |
| 2193 | parent = n; |
| 2194 | n = l; |
| 2195 | left = true; |
| 2196 | } |
| 2197 | else |
| 2198 | { |
| 2199 | lb = n + MA_SIZE(pool, n); |
| 2200 | parent = n; |
| 2201 | n = r; |
| 2202 | left = false; |
| 2203 | } |
| 2204 | continue; |
| 2205 | } |
| 2206 | else |
| 2207 | { |
| 2208 | // Outer |
| 2209 | if (size128 <= MA_MAX(lb, MA_LB(pool, n)) - lb) |
| 2210 | { |
| 2211 | ub = MA_LB(pool, n); |
| 2212 | parent = n; |
| 2213 | n = l; |
| 2214 | left = true; |
| 2215 | continue; |
| 2216 | } |
| 2217 | if (size128 <= ub - MA_MIN(ub, MA_UB(pool, n))) |
| 2218 | { |
no test coverage detected