|
12 | 12 | #pragma intrinsic (_BitScanReverse)
|
13 | 13 | #endif
|
14 | 14 |
|
| 15 | +#include "util.h" |
| 16 | + |
| 17 | +/** See the definitions for details. */ |
| 18 | +void * |
| 19 | +matras_allocator_alloc(struct matras_allocator *allocator); |
| 20 | + |
| 21 | +void |
| 22 | +matras_allocator_free(struct matras_allocator *allocator, void *ext); |
| 23 | + |
| 24 | +int |
| 25 | +matras_allocator_reserve(struct matras_allocator *allocator, int count); |
| 26 | + |
15 | 27 | /**
|
16 | 28 | * Dummy thread-local matras_stats struct used if matras_stats wasn't
|
17 | 29 | * passed to matras_create().
|
@@ -364,6 +376,30 @@ matras_touch_reserve(struct matras *m, int count)
|
364 | 376 | return matras_allocator_reserve(m->allocator, max_extents_required);
|
365 | 377 | }
|
366 | 378 |
|
| 379 | +/** |
| 380 | + * Reserve the max amount of extents required to successfully allocate @p count |
| 381 | + * blocks. The extents are reserved in the allocator given on construction. |
| 382 | + */ |
| 383 | +int |
| 384 | +matras_alloc_reserve(struct matras *m, int count) |
| 385 | +{ |
| 386 | + assert(count >= 0); |
| 387 | + |
| 388 | + /* No allocations planned. */ |
| 389 | + if (count == 0) |
| 390 | + return 0; |
| 391 | + |
| 392 | + /* |
| 393 | + * This reserves up to 3 extents more than required, but it should be OK |
| 394 | + * since the reserved memory is generic for all matras_allocator users. |
| 395 | + */ |
| 396 | + int l3_count = SMALL_DIV_ROUND_UP(m->block_size * count, |
| 397 | + m->allocator->extent_size); |
| 398 | + int l2_count = SMALL_DIV_ROUND_UP(l3_count * sizeof(void *), |
| 399 | + m->allocator->extent_size); |
| 400 | + return matras_allocator_reserve(m->allocator, l3_count + l2_count + 1); |
| 401 | +} |
| 402 | + |
367 | 403 | /**
|
368 | 404 | * Return the number of allocated extents (of size m->extent_size each)
|
369 | 405 | */
|
|
0 commit comments