From b35c0f705dc112164308c0dda2a243b3c2e00a08 Mon Sep 17 00:00:00 2001 From: Avril Date: Fri, 1 Oct 2021 17:54:37 +0100 Subject: [PATCH] Added internal visibility modifier to internal C APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for cpprng's current commit: Future small blessing − 末小吉 --- include/common.h | 11 +++++++++++ src/rng/crand.c | 42 +++++++++++++++++++++--------------------- src/rng/crand.h | 14 ++++++-------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/include/common.h b/include/common.h index cc80bd8..7c4fb64 100644 --- a/include/common.h +++ b/include/common.h @@ -9,6 +9,17 @@ extern "C" { #include #include +#define IFUNC_IMPL(name, ver) _impl__ ## name ## __ ## ver +#define IFUNC_RESOLVER(name) (*_ifun__ ## name (void)) +#define IFUNC_DEF(name, params) name params __attribute__((__ifunc__("_ifun__" #name))) + +#define _export(kind) __attribute__((visibility(#kind))) +#define v_internal _export(internal) +#define v_protected _export(protected) +#define v_hidden _export(hidden) + +#define _rng_internal v_internal + #define DEF(s, n) typedef s ## int ## n ## _t s ## n #define DEFINT(n) typedef uint ## n ## _t u ## n; \ typedef int ## n ## _t i ## n diff --git a/src/rng/crand.c b/src/rng/crand.c index d4501ae..24f3274 100644 --- a/src/rng/crand.c +++ b/src/rng/crand.c @@ -6,8 +6,9 @@ #include "crand.h" -typedef unsigned short uint48_t[3]; +#define internal _export(internal) +typedef unsigned short uint48_t[3]; struct jr_state { @@ -17,7 +18,8 @@ struct jr_state }; struct drand48_data data; union { - unsigned short xsubi[3]; + //unsigned short xsubi[3]; + uint48_t xsubi; struct { uint64_t xsubh : 48; uint16_t _xsub : 16; @@ -25,52 +27,51 @@ struct jr_state uint64_t xsubl; } st; }; +typedef __typeof(((struct jr_state*)NULL)->st) jr_xsub_t; + _Static_assert( sizeof(uint48_t) == (sizeof(uint16_t) * 3), "bad uint48 (ushort[3])"); _Static_assert( sizeof(((struct jr_state*)NULL)->st) == sizeof(uint64_t), "bad uint64 (union st)"); -static unsigned short* _impl__jr_st_resolv__low(struct jr_state* restrict state) + __attribute__((nonnull, returns_nonnull)) +static unsigned short* IFUNC_IMPL(_jr_st_resolv, low) (struct jr_state* restrict state) { return state->st.xsubi; } - -static unsigned short* _impl__jr_st_resolv__high(struct jr_state* restrict state) + __attribute__((nonnull, returns_nonnull)) +static unsigned short* IFUNC_IMPL(_jr_st_resolv, high) (struct jr_state* restrict state) { return state->st.xsubi+1; } - -static unsigned short* (*_ifun__jr_st_resolv (void)) (struct jr_state* restrict state) +__attribute__((returns_nonnull)) +static unsigned short* IFUNC_RESOLVER(_jr_st_resolv) (struct jr_state* restrict state) { struct jr_state chk = {0}; chk.st.xsubh = JR_MAX; return chk.st._xsub - ? &_impl__jr_st_resolv__high - : &_impl__jr_st_resolv__low; + ? & IFUNC_IMPL(_jr_st_resolv, high) + : & IFUNC_IMPL(_jr_st_resolv, low); } +static unsigned short* IFUNC_DEF(_jr_st_resolv, (struct jr_state* restrict state) __attribute__((nonnull, returns_nonnull))); -static unsigned short* _jr_st_resolv(struct jr_state* restrict state) - __attribute__((ifunc("_ifun__jr_st_resolv"))); - -void _jr_seed(struct jr_state* restrict state, unsigned long with) +internal void _jr_seed(struct jr_state* restrict state, unsigned long with) { state->st.xsubh = with; seed48_r(_jr_st_resolv(state), &state->data); } -long _jr_proc(struct jr_state* restrict state) +internal long _jr_proc(struct jr_state* restrict state) { jrand48_r(_jr_st_resolv(state), &state->data, &state->result); return state->result; } -//TODO: a version of _jr_proc that uses use `erand48_r()` to return between 0..1.0 for _sample() - -double _jr_procf(struct jr_state* restrict state) +internal double _jr_procf(struct jr_state* restrict state) { erand48_r(_jr_st_resolv(state), &state->data, &state->fresult); return state->fresult; } -struct jr_state* _jr_alloc() +internal struct jr_state* _jr_alloc() { struct jr_state* bx = aligned_alloc(_Alignof(struct jr_state), sizeof(struct jr_state)); memset(bx, 0, sizeof(struct jr_state)); @@ -78,19 +79,18 @@ struct jr_state* _jr_alloc() return bx; } -struct jr_state* _jr_new(unsigned long with) +internal struct jr_state* _jr_new(unsigned long with) { struct jr_state* state = _jr_alloc(); _jr_seed(state, with); return state; } -void _jr_free(struct jr_state* restrict state) +internal void _jr_free(struct jr_state* restrict state) { free(state); } -//TODO: Use test macros from tracemac, run with attr(ctor) if `-DTEST` is provided. void __TEST__jr_test() { struct jr_state* st = _jr_alloc(); diff --git a/src/rng/crand.h b/src/rng/crand.h index 2da1611..9667b34 100644 --- a/src/rng/crand.h +++ b/src/rng/crand.h @@ -11,15 +11,13 @@ extern "C" { struct jr_state; -//TODO: make all these functions visibility("internal") +void _jr_seed(struct jr_state* restrict state, unsigned long with) _export(internal); +long _jr_proc(struct jr_state* restrict state) _export(internal); +double _jr_procf(struct jr_state* restrict state) _export(internal); +struct jr_state* _jr_alloc() _export(internal); +void _jr_free(struct jr_state* restrict state) _export(internal); -void _jr_seed(struct jr_state* restrict state, unsigned long with); -long _jr_proc(struct jr_state* restrict state); -double _jr_procf(struct jr_state* restrict state); -struct jr_state* _jr_alloc(); -void _jr_free(struct jr_state* restrict state); - -struct jr_state* _jr_new(unsigned long with); +struct jr_state* _jr_new(unsigned long with) _export(internal); #ifdef __cplusplus }