+/* Always inline for __builtin_return_address(0). */
+static inline __attribute__((always_inline))
+int rseq_percpu_pool_range_destroy(struct rseq_percpu_pool *pool,
+ struct rseq_percpu_pool_range *range)
+{
+ destroy_alloc_bitmap(pool, range);
+ return pool->attr.munmap_func(pool->attr.mmap_priv, range->base,
+ pool->percpu_len * pool->max_nr_cpus);
+}
+
+static
+struct rseq_percpu_pool_range *rseq_percpu_pool_range_create(struct rseq_percpu_pool *pool)
+{
+ struct rseq_percpu_pool_range *range;
+ void *base;
+
+ range = calloc(1, sizeof(struct rseq_percpu_pool_range));
+ if (!range)
+ return NULL;
+ range->pool = pool;
+
+ base = pool->attr.mmap_func(pool->attr.mmap_priv, pool->percpu_len * pool->max_nr_cpus);
+ if (!base)
+ goto error_alloc;
+ range->base = base;
+ if (pool->attr.robust_set) {
+ if (create_alloc_bitmap(pool, range))
+ goto error_alloc;
+ }
+ return range;
+
+error_alloc:
+ (void) rseq_percpu_pool_range_destroy(pool, range);
+ return NULL;
+}
+