From 06e0b1c08e655c5b6fb855420e31e27c8c4bdbe2 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 8 Mar 2024 16:32:22 -0500 Subject: [PATCH] mempool: Introduce optional stride parameter Signed-off-by: Mathieu Desnoyers Change-Id: Ic7119bb33f86cf72c73c2d50dbe55e4769ce0b22 --- include/rseq/compiler.h | 11 +++++++++++ include/rseq/mempool.h | 32 ++++++++++++++++---------------- src/rseq-mempool.c | 2 +- tests/mempool_test.c | 6 +++--- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/include/rseq/compiler.h b/include/rseq/compiler.h index 3df18cd..9a202cd 100644 --- a/include/rseq/compiler.h +++ b/include/rseq/compiler.h @@ -92,4 +92,15 @@ ) #endif +/* + * RSEQ_PARAM_SELECT_ARG1 + * + * Select second argument. Use inside macros to implement optional last + * macro argument, such as: + * + * #define macro(_a, _b, _c, _optional...) \ + * RSEQ_PARAM_SELECT_ARG1(_, ##_optional, do_default_macro()) + */ +#define RSEQ_PARAM_SELECT_ARG1(_arg0, _arg1, ...) _arg1 + #endif /* _RSEQ_COMPILER_H */ diff --git a/include/rseq/mempool.h b/include/rseq/mempool.h index 58ebbac..f321313 100644 --- a/include/rseq/mempool.h +++ b/include/rseq/mempool.h @@ -31,9 +31,9 @@ extern "C" { * The stride *must* match for all objects belonging to a given pool * between arguments to: * - * - rseq_percpu_pool_create(), - * - __rseq_percpu_free(), - * - __rseq_percpu_ptr(). + * - rseq_mempool_create(), + * - rseq_percpu_ptr(). + * - rseq_percpu_free(), */ #if RSEQ_BITS_PER_LONG == 64 # define RSEQ_PERCPU_STRIDE (1U << 24) /* 64-bit stride: 16MB */ @@ -153,15 +153,16 @@ void __rseq_percpu *rseq_percpu_zmalloc(struct rseq_mempool *pool); * - rseq_percpu_pool_set_malloc(), * - rseq_percpu_pool_set_zmalloc(). * - * The @stride argument to __rseq_percpu_free() is a configurable + * The @stride optional argument to rseq_percpu_free() is a configurable * stride, which must match the stride received by pool creation. - * rseq_percpu_free() uses the default RSEQ_PERCPU_STRIDE stride. + * If the argument is not present, use the default RSEQ_PERCPU_STRIDE. * * This API is MT-safe. */ -void __rseq_percpu_free(void __rseq_percpu *ptr, size_t percpu_stride); +void librseq_percpu_free(void __rseq_percpu *ptr, size_t percpu_stride); -#define rseq_percpu_free(ptr) __rseq_percpu_free(ptr, RSEQ_PERCPU_STRIDE) +#define rseq_percpu_free(_ptr, _stride...) \ + librseq_percpu_free(_ptr, RSEQ_PARAM_SELECT_ARG1(_, ##_stride, RSEQ_PERCPU_STRIDE)) /* * rseq_percpu_ptr: Offset a per-cpu pointer for a given CPU. @@ -175,20 +176,19 @@ void __rseq_percpu_free(void __rseq_percpu *ptr, size_t percpu_stride); * - rseq_percpu_pool_set_malloc(), * - rseq_percpu_pool_set_zmalloc(). * - * The macros rseq_percpu_ptr() and __rseq_percpu_ptr() preserve the - * type of the @ptr parameter for the returned pointer, but removes the - * __rseq_percpu annotation. + * The macro rseq_percpu_ptr() preserves the type of the @ptr parameter + * for the returned pointer, but removes the __rseq_percpu annotation. * - * The macro __rseq_percpu_ptr() takes a configurable @stride argument, - * whereas rseq_percpu_ptr() uses the RSEQ_PERCPU_STRIDE default stride. + * The macro rseq_percpu_ptr() takes an optional @stride argument. If + * the argument is not present, use the default RSEQ_PERCPU_STRIDE. * This must match the stride used for pool creation. * * This API is MT-safe. */ -#define __rseq_percpu_ptr(ptr, cpu, stride) \ - ((__typeof__(*(ptr)) *) ((uintptr_t) (ptr) + ((unsigned int) (cpu) * (uintptr_t) (stride)))) - -#define rseq_percpu_ptr(ptr, cpu) __rseq_percpu_ptr(ptr, cpu, RSEQ_PERCPU_STRIDE) +#define rseq_percpu_ptr(_ptr, _cpu, _stride...) \ + ((__typeof__(*(_ptr)) *) ((uintptr_t) (_ptr) + \ + ((unsigned int) (_cpu) * \ + (uintptr_t) RSEQ_PARAM_SELECT_ARG1(_, ##_stride, RSEQ_PERCPU_STRIDE)))) /* * rseq_mempool_set_create: Create a pool set. diff --git a/src/rseq-mempool.c b/src/rseq-mempool.c index 1681f74..1ece00e 100644 --- a/src/rseq-mempool.c +++ b/src/rseq-mempool.c @@ -655,7 +655,7 @@ void clear_alloc_slot(struct rseq_mempool *pool, size_t item_offset) bitmap[k] &= ~mask; } -void __rseq_percpu_free(void __rseq_percpu *_ptr, size_t percpu_stride) +void librseq_percpu_free(void __rseq_percpu *_ptr, size_t percpu_stride) { uintptr_t ptr = (uintptr_t) _ptr; void *range_base = (void *) (ptr & (~(percpu_stride - 1))); diff --git a/tests/mempool_test.c b/tests/mempool_test.c index 119c18c..39d5b3b 100644 --- a/tests/mempool_test.c +++ b/tests/mempool_test.c @@ -57,7 +57,7 @@ static void test_mempool_fill(size_t stride) if (!ptr) break; /* Link items in cpu 0. */ - cpuptr = __rseq_percpu_ptr(ptr, 0, stride); + cpuptr = rseq_percpu_ptr(ptr, 0, stride); cpuptr->backref = ptr; /* Randomize items in list. */ if (count & 1) @@ -72,7 +72,7 @@ static void test_mempool_fill(size_t stride) list_for_each_entry(iter, &list, node) { ptr = iter->backref; for (i = 0; i < CPU_SETSIZE; i++) { - struct test_data *cpuptr = __rseq_percpu_ptr(ptr, i, stride); + struct test_data *cpuptr = rseq_percpu_ptr(ptr, i, stride); if (cpuptr->value != 0) abort(); @@ -84,7 +84,7 @@ static void test_mempool_fill(size_t stride) list_for_each_entry_safe(iter, tmp, &list, node) { ptr = iter->backref; - __rseq_percpu_free(ptr, stride); + rseq_percpu_free(ptr, stride); } ret = rseq_mempool_destroy(mempool); ok(ret == 0, "Destroy mempool"); -- 2.34.1