This allows you to declare that the given address marks the edge of some * pool memory that is no longer needed. Any extents that hold only data * older than the boundary address are freed. NOTE: You MUST NOT USE BOTH * pool_free() and pool_free_old() on the same pool!! */
| 256 | * older than the boundary address are freed. NOTE: You MUST NOT USE BOTH |
| 257 | * pool_free() and pool_free_old() on the same pool!! */ |
| 258 | void |
| 259 | pool_free_old(alloc_pool_t p, void *addr) |
| 260 | { |
| 261 | struct alloc_pool *pool = (struct alloc_pool *)p; |
| 262 | struct pool_extent *cur, *prev, *next; |
| 263 | |
| 264 | if (!pool || !addr) |
| 265 | return; |
| 266 | |
| 267 | for (prev = NULL, cur = pool->extents; cur; prev = cur, cur = cur->next) { |
| 268 | if (addr >= cur->start |
| 269 | && addr < PTR_ADD(cur->start, pool->size)) |
| 270 | break; |
| 271 | } |
| 272 | if (!cur) |
| 273 | return; |
| 274 | |
| 275 | if (addr == PTR_ADD(cur->start, cur->free)) { |
| 276 | if (prev) { |
| 277 | prev->next = NULL; |
| 278 | next = cur; |
| 279 | } else { |
| 280 | /* The most recent live extent can just be reset. */ |
| 281 | if (pool->flags & POOL_CLEAR) |
| 282 | memset(addr, 0, pool->size - cur->free); |
| 283 | cur->free = pool->size; |
| 284 | cur->bound = 0; |
| 285 | next = cur->next; |
| 286 | cur->next = NULL; |
| 287 | } |
| 288 | } else { |
| 289 | next = cur->next; |
| 290 | cur->next = NULL; |
| 291 | } |
| 292 | |
| 293 | while ((cur = next) != NULL) { |
| 294 | next = cur->next; |
| 295 | if (pool->flags & POOL_PREPEND) |
| 296 | free(PTR_SUB(cur->start, sizeof (struct pool_extent))); |
| 297 | else { |
| 298 | free(cur->start); |
| 299 | free(cur); |
| 300 | } |
| 301 | pool->e_freed++; |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | /* If the current extent doesn't have "len" free space in it, mark it as full |
| 306 | * so that the next alloc will start a new extent. If len is (size_t)-1, this |