Added internal visibility modifier to internal C APIs

Fortune for cpprng's current commit: Future small blessing − 末小吉
lib
Avril 3 years ago
parent 8e20b86365
commit b35c0f705d
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -9,6 +9,17 @@ extern "C" {
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#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 DEF(s, n) typedef s ## int ## n ## _t s ## n
#define DEFINT(n) typedef uint ## n ## _t u ## n; \ #define DEFINT(n) typedef uint ## n ## _t u ## n; \
typedef int ## n ## _t i ## n typedef int ## n ## _t i ## n

@ -6,8 +6,9 @@
#include "crand.h" #include "crand.h"
typedef unsigned short uint48_t[3]; #define internal _export(internal)
typedef unsigned short uint48_t[3];
struct jr_state struct jr_state
{ {
@ -17,7 +18,8 @@ struct jr_state
}; };
struct drand48_data data; struct drand48_data data;
union { union {
unsigned short xsubi[3]; //unsigned short xsubi[3];
uint48_t xsubi;
struct { struct {
uint64_t xsubh : 48; uint64_t xsubh : 48;
uint16_t _xsub : 16; uint16_t _xsub : 16;
@ -25,52 +27,51 @@ struct jr_state
uint64_t xsubl; uint64_t xsubl;
} st; } 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(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_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; return state->st.xsubi;
} }
__attribute__((nonnull, returns_nonnull))
static unsigned short* _impl__jr_st_resolv__high(struct jr_state* restrict state) static unsigned short* IFUNC_IMPL(_jr_st_resolv, high) (struct jr_state* restrict state)
{ {
return state->st.xsubi+1; return state->st.xsubi+1;
} }
__attribute__((returns_nonnull))
static unsigned short* (*_ifun__jr_st_resolv (void)) (struct jr_state* restrict state) static unsigned short* IFUNC_RESOLVER(_jr_st_resolv) (struct jr_state* restrict state)
{ {
struct jr_state chk = {0}; struct jr_state chk = {0};
chk.st.xsubh = JR_MAX; chk.st.xsubh = JR_MAX;
return chk.st._xsub return chk.st._xsub
? &_impl__jr_st_resolv__high ? & IFUNC_IMPL(_jr_st_resolv, high)
: &_impl__jr_st_resolv__low; : & 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) internal void _jr_seed(struct jr_state* restrict state, unsigned long with)
__attribute__((ifunc("_ifun__jr_st_resolv")));
void _jr_seed(struct jr_state* restrict state, unsigned long with)
{ {
state->st.xsubh = with; state->st.xsubh = with;
seed48_r(_jr_st_resolv(state), &state->data); 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); jrand48_r(_jr_st_resolv(state), &state->data, &state->result);
return state->result; return state->result;
} }
//TODO: a version of _jr_proc that uses use `erand48_r()` to return between 0..1.0 for _sample() internal double _jr_procf(struct jr_state* restrict state)
double _jr_procf(struct jr_state* restrict state)
{ {
erand48_r(_jr_st_resolv(state), &state->data, &state->fresult); erand48_r(_jr_st_resolv(state), &state->data, &state->fresult);
return 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)); struct jr_state* bx = aligned_alloc(_Alignof(struct jr_state), sizeof(struct jr_state));
memset(bx, 0, sizeof(struct jr_state)); memset(bx, 0, sizeof(struct jr_state));
@ -78,19 +79,18 @@ struct jr_state* _jr_alloc()
return bx; 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(); struct jr_state* state = _jr_alloc();
_jr_seed(state, with); _jr_seed(state, with);
return state; return state;
} }
void _jr_free(struct jr_state* restrict state) internal void _jr_free(struct jr_state* restrict state)
{ {
free(state); free(state);
} }
//TODO: Use test macros from tracemac, run with attr(ctor) if `-DTEST` is provided.
void __TEST__jr_test() void __TEST__jr_test()
{ {
struct jr_state* st = _jr_alloc(); struct jr_state* st = _jr_alloc();

@ -11,15 +11,13 @@ extern "C" {
struct jr_state; 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); struct jr_state* _jr_new(unsigned long with) _export(internal);
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);
#ifdef __cplusplus #ifdef __cplusplus
} }

Loading…
Cancel
Save