Initial commit

lean
Avril 5 years ago
commit 01f12fba2e
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -0,0 +1,10 @@
all: clean shuffle3
clean:
rm -f build/*
shuffle3:
gcc src/*.c -Iinclude/ -g -Wall -pedantic --std=gnu11 -o build/$@ -lm
./build/$@

@ -0,0 +1,59 @@
#ifndef _PTR_STORE_H
#define _PTR_STORE_H
#include <stddef.h>
typedef struct store_link {
void* ptr;
int is_obj;
struct store_link* next;
} store_t;
typedef struct store_obj {
void* state;
void (*constructor)(struct store_obj* this);
void (*destructor)(struct store_obj* this);
void (*copy_to)(struct store_obj* this, struct store_obj* other);
} object;
store_t *new_store();
void* store_malloc(store_t *store, size_t sz);
void store_free(store_t* store, void* ptr);
void destroy_store(store_t *store);
void* store_ptr(store_t *store, void *heap);
void store_collect(store_t *store);
store_t* _store_first_empty(store_t *store, int setobj);
object* copy_object(object* from, object* to);
object* clone_object(store_t* store, object *from);
object *new_object_unmanaged(object prototype);
void free_object_unmanaged(object* obj);
object* store_object(store_t* store, object prototype);
void free_object(store_t *store,object *obj);
object object_prototype();
extern const object OBJ_PROTO;
#define strack _store_first_empty(__internal_store, 0)->ptr =
#define strack_obj _store_first_empty(__internal_store, 1)->ptr =
#define S_LEXENV store_t* __internal_store
#define S_LEXCALL(f, ...) f(__internal_store, __VA_ARGS__)
#define LEXENV __internal_store
#define scollect() store_collect(__internal_store)
#define smalloc(sz) store_malloc(__internal_store, sz)
#define sdelete(ptr) _Generic((ptr), object*: free_object, default: store_free)(__internal_store, ptr)
#define snew(type) ((type*)smalloc(sizeof(type)))
#define snew_obj(proto) store_object(__internal_store, proto)
#define MANAGED(var) { \
store_t * __internal_store = new_store(); \
var; \
destroy_store(__internal_store); \
}
#define STORE_LEXBIND(type, name) type name = *((type*)store_malloc(__internal_store, sizeof(type)));
#endif /* _PTR_STORE_H */

@ -0,0 +1,25 @@
#ifndef _RNG_H
#define _RNG_H
typedef struct rng_algo *RNG; //RNG algorithm reference
#define rng_reinterpret(rng, value, type) (*((type*)rng_next(rng, &value, sizeof(type))))
#define rng_reinterpret_new(rng, value, type) (*((type*)rng_next(rng, malloc(sizeof(type)), sizeof(type))))
#define rng_reinterpret_stackalloc(rng, value, type) rng_reinterpret(rng, alloca(sizeof(type)), type)
#define RNG_LEXBIND(rng, type, name) type name = rng_reinterpret(rng, name, type)
double rng_next_double(RNG algo);
int rng_next_int_bounded(RNG algo, int min, int max);
int rng_next_int(RNG algo, int max);
void* rng_next(RNG algo, void* data, int len);
int rng_chance(RNG algo, double d);
void rng_free(RNG algo);
void rng_seed(RNG algo, void* seed);
RNG rng_new(RNG (*instantiate)(void));
#define RNG_IMPL_DEFINITION(name) RNG __rng_impl_ ## name(void)
#define RNG_ALGO(name) &__rng_impl_ ## name
#define RNG_NEW(name) rng_new(RNG_ALGO(name))
#endif /* _RNG_H */

@ -0,0 +1,14 @@
#ifndef _RNG_ALGOS_H
#define _RNG_ALGOS_H
#include "rng.h"
RNG_IMPL_DEFINITION(xoroshiro128plus);
void xoro_jump();
void xoro_long_jump();
RNG_IMPL_DEFINITION(frng);
RNG_IMPL_DEFINITION(drng);
#endif /* _RNG_ALGOS_H */

@ -0,0 +1,17 @@
#ifndef _RNG_IMPL_H
#define _RNG_IMPL_H
#include "rng.h"
#include <stdlib.h>
struct rng_algo {
void (*seed)(const void* state);
double (*sample)(void);
void (*construct)(void);
void (*destruct)(void);
}; //*RNG
RNG rng_new_impl(const struct rng_algo *from);
#endif /* _RNG_IMPL_H */

@ -0,0 +1,24 @@
#include <rng_impl.h>
#include <string.h>
#include <stdlib.h>
static void _seed(const void* seed)
{
srand(*((const unsigned int*)seed));
}
static double _next()
{
return (double)rand() / (double)RAND_MAX;
}
RNG_IMPL_DEFINITION(drng)
{
struct rng_algo algo;
memset(&algo,0,sizeof(algo));
algo.seed= &_seed;
algo.sample = &_next;
return rng_new_impl(&algo);
}

@ -0,0 +1,68 @@
#include <rng_impl.h>
#include <math.h>
#include <string.h>
double vec[2];
static void _seed(const void* from)
{
memcpy(vec, from, sizeof(double)*2);
}
double fract(double x)
{
return x - floor(x);
}
double dot(double *v, double *u, int n)
{
register double res = 0;
for(register int i=0;i<n;i++)
{
res += v[i]*u[i];
}
return res;
}
static double sample_double(double vec[2])
{
static double vec2[2] = { 12.9898, 78.223 };
double res = fract(sin(dot(vec, vec2, 2)) * 43758.5453);
return res;
}
static void next(double r)
{
float v1 = vec[0];
float v2 = vec[1];
double nvec[2];
nvec[0] = r;
nvec[1] = v2;
vec[0] = sample_double(nvec);
nvec[1] = v1;
vec[1] = sample_double(nvec);
}
static double _sample()
{
double res = sample_double(vec);
next(res);
return res;
}
RNG_IMPL_DEFINITION(frng)
{
struct rng_algo rng;
memset(&rng,0,sizeof(rng));
rng.seed = &_seed;
rng.sample = &_sample;
return rng_new_impl(&rng);
}

@ -0,0 +1,159 @@
#include <stdio.h>
#include <float.h>
#include <stdint.h>
#include <rng.h>
#include <rng_algos.h>
#include <ptr_store.h>
/*void test_destructor(object* ptr)
{
printf("die\n");
}*/
void _rng_object_destructor(object* obj)
{
rng_free(obj->state);
}
RNG rng_object(S_LEXENV, RNG rng)
{
object proto = OBJ_PROTO;
proto.state = rng;
proto.destructor = &_rng_object_destructor;
return snew_obj(proto)->state;
}
void shuffle_longs(RNG with, long *data, int n)
{
register long temp;
for(register int i= n-1;i>0;i--)
{
int j = rng_next_int(with, i);
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
void shuffle_floats(RNG with, float* data, int n)
{
register float temp;
for(register int i=n-1;i>0;i--)
{
int j = rng_next_int(with,i);
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
void shuffle_bytes(RNG with, unsigned char* data, int n)
{
register unsigned char temp;
for(int i=n-1;i>0;i--)
{
int j = rng_next_int(with, i);
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
void minmax_longs(long* min, long* max, const long* data, int n)
{
for(register int i=0;i<n;i++)
{
if(data[i] > *max) *max = data[i];
if(data[i] < *min) *min = data[i];
}
}
void minmax_floats(float* min, float* max, const float* data, int n)
{
for(register int i=0;i<n;i++)
{
if(data[i] > *max) *max = data[i];
if(data[i] < *min) *min = data[i];
}
}
void minmax_sbytes(signed char* min, signed char* max, const signed char* data,int n)
{
for(register int i=0;i<n;i++)
{
if(data[i] > *max) *max = data[i];
if(data[i] < *min) *min = data[i];
}
}
void print_array(unsigned char* data, int len)
{
for(register int i=0;i<len;i++)
printf("%d ", (int)data[i]);
printf("\n");
}
void shuffle3(S_LEXENV, void* data, int raw_len)
{
RNG xoro = S_LEXCALL(rng_object, rng_new(RNG_ALGO(xoroshiro128plus)));
RNG frng = S_LEXCALL(rng_object, rng_new(RNG_ALGO(frng)));
RNG drng = S_LEXCALL(rng_object, rng_new(RNG_ALGO(drng)));
long min = INT64_MAX;
long max = INT64_MIN;
float fmin = (float)DBL_MAX;
float fmax = (float)-DBL_MAX;
signed char bmax = INT8_MIN;
signed char bmin = INT8_MAX;
minmax_longs(&min, &max, data, raw_len/sizeof(long));
uint64_t xseed[2];
xseed[0] = min;
xseed[1] = max;
rng_seed(xoro, xseed);
shuffle_longs(xoro, data, raw_len/sizeof(long));
minmax_floats(&fmin, &fmax, data, raw_len/sizeof(float));
double fseed[2];
fseed[0] = fmin;
fseed[1] = fmax;
rng_seed(frng, fseed);
shuffle_floats(frng, data, raw_len/sizeof(float));
minmax_sbytes(&bmin, &bmax, data, raw_len);
unsigned int seed = (0xfffa << 16) | (bmin<<8) | bmax;
rng_seed(drng, &seed);
shuffle_bytes(drng, data, raw_len);
}
int main()
{
MANAGED({
void * data = smalloc(255);
int raw_len = 255;
for(int i=0;i<raw_len;i++)
((unsigned char*)data)[i] = i;
print_array(data,raw_len);
shuffle3(LEXENV, data, raw_len);
print_array(data,raw_len);
/*char* buffer = smalloc(32);
int* nw = snew(int);
object proto = OBJ_PROTO;
proto.destructor = &test_destructor;
proto.constructor = &test_destructor;
object* obj = snew_obj(proto);
*nw=22;
sprintf(buffer, "hello %d\n", *nw);
sdelete(nw);
sdelete(obj);
printf("%s", buffer);*/
});
return 0;
}

@ -0,0 +1,215 @@
#include <ptr_store.h>
#include <string.h>
#include <stdlib.h>
store_t *new_store()
{
store_t *s = malloc(sizeof(store_t));
memset(s,0,sizeof(store_t));
return s;
}
void* store_malloc(store_t *store, size_t sz)
{
void ** sptr;
if(store->ptr == NULL)
sptr = &store->ptr;
else if (store->next == NULL) {
store->next = new_store();
return store_malloc(store->next, sz);
} else {
return store_malloc(store->next, sz);
}
*sptr = malloc(sz);
memset(*sptr, 0, sz);
return *sptr;
}
void store_free(store_t* store, void* ptr)
{
if(store->ptr == ptr)
{
if(store->is_obj)
{
object* obj = store->ptr;
if(obj->destructor!=NULL)
obj->destructor(obj);
}
free(ptr);
store->ptr = NULL;
store->is_obj=0;
} else if (store->next) {
store_free(store->next,ptr);
}
}
store_t* _store_first_empty(store_t *store, int obj)
{
if(!store->ptr) { store->is_obj=obj; return store; }
else if(store->next) return _store_first_empty(store->next, obj);
else {
store->next = new_store();
store->next->is_obj = obj;
return store->next;
}
}
static store_t* _store_ptr(store_t *store, void* heap)
{
if(!store->ptr)
store->ptr = heap;
else if(store->next)
return _store_ptr(store->next, heap);
else {
store->next = new_store();
return _store_ptr(store->next, heap);
}
return store;
}
void* store_ptr(store_t *store, void *heap)
{
if(!store->ptr)
store->ptr = heap;
else if(store->next)
return store_ptr(store->next, heap);
else {
store->next = new_store();
return store_ptr(store->next, heap);
}
return store->ptr;
}
void destroy_store(store_t *store)
{
while(store)
{
if(store->ptr)
{
if(store->is_obj)
{
object *obj = store->ptr;
if(obj->destructor!=NULL)
obj->destructor(obj);
}
free(store->ptr);
}
store_t *next = store->next;
free(store);
store = next;
}
}
void store_collect(store_t *store)
{
int first=1;
while(store)
{
if(store->ptr)
{
if(store->is_obj)
{
object *obj = store->ptr;
if(obj->destructor!=NULL)
obj->destructor(obj);
}
free(store->ptr);
}
store_t *next = store->next;
store->is_obj=0;
if(!first) free(store);
first=0;
store=next;
}
}
object *new_object_unmanaged(object prototype)
{
object* ret = malloc(sizeof(object));
memcpy(ret, &prototype, sizeof(object));
if(ret->constructor!=NULL)
ret->constructor(ret);
return ret;
}
void free_object_unmanaged(object* obj)
{
if(obj->destructor!=NULL)
obj->destructor(obj);
free(obj);
}
object* store_object(store_t* store, object prototype)
{
object* obj = new_object_unmanaged(prototype);
store_t* s = _store_ptr(store, obj);
s->is_obj = 1;
return obj;
}
object* copy_object(object* from, object* to)
{
to->constructor = from->constructor;
to->destructor = from->destructor;
to->copy_to(from, to);
return to;
}
object* clone_object(store_t* store, object *from)
{
object* new = malloc(sizeof(object));
from->constructor(new);
copy_object(from, new);
if(store)
{
store_t* s = _store_ptr(store, new);
s->is_obj = 1;
}
return new;
}
void free_object(store_t *store,object *obj)
{
if(store->ptr == obj)
{
if(obj->destructor!=NULL)
obj->destructor(obj);
free(obj);
store->ptr = NULL;
store->is_obj=0;
} else if (store->next) {
free_object(store->next,obj);
}
}
object object_prototype()
{
object o;
memset(&o, 0, sizeof(object));
return o;
}
static void _copy_object_default(object* f, object* t)
{
t->state = f->state;
}
const object OBJ_PROTO = {NULL,NULL,NULL, &_copy_object_default};

@ -0,0 +1,65 @@
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <rng.h>
#include <rng_impl.h>
RNG rng_new_impl(const struct rng_algo *from)
{
RNG algo = malloc(sizeof(struct rng_algo));
memcpy(algo, from, sizeof(struct rng_algo));
if(algo->construct!=NULL)
algo->construct();
return algo;
}
RNG rng_new(RNG (*instantiate)(void))
{
return instantiate();
}
void rng_free(RNG algo)
{
if(algo->destruct!=NULL)
algo->destruct();
free(algo);
}
void rng_seed(RNG algo, void* seed)
{
if(algo->seed!=NULL)
algo->seed(seed);
}
double rng_next_double(RNG algo)
{
return algo->sample();
}
int rng_next_int_bounded(RNG algo, int min, int max)
{
return (int)floor(algo->sample() * (double)(max-min))+min;
}
int rng_next_int(RNG algo, int max)
{
return (int)floor(algo->sample() * (double)max);
}
void* rng_next(RNG algo, void* data, int len)
{
uint8_t *buffer = data;
for(register int i=0;i<len;i++)
{
buffer[i] = (uint8_t)rng_next_int(algo, 255);
}
return data;
}
int rng_chance(RNG algo, double d)
{
if(d<=0) return 0;
return algo->sample()<=d;
}

@ -0,0 +1,103 @@
#include <rng_impl.h>
#include <stdint.h>
/* Written in 2016-2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
static inline uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}
_Atomic static uint64_t s[2];
static uint64_t next(void) {
const uint64_t s0 = s[0];
uint64_t s1 = s[1];
const uint64_t result = s0 + s1;
s1 ^= s0;
s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
s[1] = rotl(s1, 37); // c
return result;
}
static void jump(void) {
static const uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc };
uint64_t s0 = 0;
uint64_t s1 = 0;
for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
for(int b = 0; b < 64; b++) {
if (JUMP[i] & UINT64_C(1) << b) {
s0 ^= s[0];
s1 ^= s[1];
}
next();
}
s[0] = s0;
s[1] = s1;
}
static void long_jump(void) {
static const uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
uint64_t s0 = 0;
uint64_t s1 = 0;
for(int i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++)
for(int b = 0; b < 64; b++) {
if (LONG_JUMP[i] & UINT64_C(1) << b) {
s0 ^= s[0];
s1 ^= s[1];
}
next();
}
s[0] = s0;
s[1] = s1;
}
static void seed(uint64_t s0, uint64_t s1) {
s[0] = s0;
s[1] = s1;
}
void _seed(const void* from)
{
const uint64_t *ptr = from;
seed(ptr[0], ptr[1]);
}
double _sample()
{
return (next() & ((1L << 53) - 1)) * (1.00 / (1L << 53));
}
RNG_IMPL_DEFINITION(xoroshiro128plus)
{
struct rng_algo algo;
algo.sample = &_sample;
algo.seed = &_seed;
algo.construct=NULL;
algo.destruct=NULL;
return rng_new_impl(&algo);
}
void xoro_jump()
{
jump();
}
void xoro_long_jump()
{
long_jump();
}
Loading…
Cancel
Save