mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2026-02-15 04:03:49 +01:00
144 lines
3.0 KiB
C
144 lines
3.0 KiB
C
#include "neonucleus.h"
|
|
#include "nn_utils.h"
|
|
|
|
#ifndef NN_BAREMETAL
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
#if defined(__STDC_NO_THREADS__) || defined(NN_WINDOWS) // fuck you Windows
|
|
#include "tinycthread.h"
|
|
#else
|
|
#include <threads.h>
|
|
#endif
|
|
#endif
|
|
|
|
void *nn_alloc(nn_Context *ctx, size_t size) {
|
|
if(size == 0) return ctx->alloc;
|
|
return ctx->alloc(ctx->state, NULL, 0, size);
|
|
}
|
|
|
|
void *nn_realloc(nn_Context *ctx, void *memory, size_t oldSize, size_t newSize) {
|
|
if(memory == ctx->alloc) return nn_alloc(memory, newSize);
|
|
if(newSize == 0) {
|
|
nn_free(ctx, memory, oldSize);
|
|
return ctx->alloc;
|
|
}
|
|
return ctx->alloc(ctx->state, memory, oldSize, newSize);
|
|
}
|
|
|
|
void nn_free(nn_Context *ctx, void *memory, size_t size) {
|
|
if(memory == ctx->alloc) return;
|
|
ctx->alloc(ctx->state, memory, size, 0);
|
|
}
|
|
|
|
nn_Lock *nn_createLock(nn_Context *ctx) {
|
|
void *mem = nn_alloc(ctx, ctx->lockSize);
|
|
if(mem == NULL) return NULL;
|
|
ctx->lock(ctx->state, mem, NN_LOCK_INIT);
|
|
return mem;
|
|
}
|
|
|
|
void nn_destroyLock(nn_Context *ctx, nn_Lock *lock) {
|
|
if(lock == NULL) return;
|
|
ctx->lock(ctx->state, lock, NN_LOCK_DEINIT);
|
|
nn_free(ctx, lock, ctx->lockSize);
|
|
}
|
|
|
|
void nn_lock(nn_Context *ctx, nn_Lock *lock) {
|
|
ctx->lock(ctx->state, lock, NN_LOCK_LOCK);
|
|
}
|
|
|
|
void nn_unlock(nn_Context *ctx, nn_Lock *lock) {
|
|
ctx->lock(ctx->state, lock, NN_LOCK_UNLOCK);
|
|
}
|
|
|
|
double nn_currentTime(nn_Context *ctx) {
|
|
return ctx->time(ctx->state);
|
|
}
|
|
|
|
size_t nn_rand(nn_Context *ctx) {
|
|
return ctx->rng(ctx->state);
|
|
}
|
|
|
|
double nn_randf(nn_Context *ctx) {
|
|
double n = (double)nn_rand(ctx);
|
|
return n / (double)(ctx->rngMaximum + 1);
|
|
}
|
|
|
|
double nn_randfi(nn_Context *ctx) {
|
|
double n = (double)nn_rand(ctx);
|
|
return n / (double)ctx->rngMaximum;
|
|
}
|
|
|
|
static void *nn_defaultAlloc(void *_, void *memory, size_t oldSize, size_t newSize) {
|
|
#ifndef NN_BAREMETAL
|
|
if(newSize == 0) {
|
|
free(memory);
|
|
return NULL;
|
|
}
|
|
|
|
return realloc(memory, newSize);
|
|
#else
|
|
// 0 memory available
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
static double nn_defaultTime(void *_) {
|
|
#ifndef NN_BAREMETAL
|
|
// time does not exist... yet!
|
|
return 0;
|
|
#else
|
|
// time does not exist
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
static size_t nn_defaultRng(void *_) {
|
|
#ifndef NN_BAREMETAL
|
|
return rand();
|
|
#else
|
|
// insane levels of RNG
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
static void nn_defaultLock(void *state, void *lock, nn_LockAction action) {
|
|
#ifndef NN_BAREMETAL
|
|
switch(action) {
|
|
case NN_LOCK_INIT:
|
|
mtx_init(lock, mtx_plain);
|
|
break;
|
|
case NN_LOCK_DEINIT:
|
|
mtx_destroy(lock);
|
|
break;
|
|
case NN_LOCK_LOCK:
|
|
mtx_lock(lock);
|
|
break;
|
|
case NN_LOCK_UNLOCK:
|
|
mtx_unlock(lock);
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void nn_initContext(nn_Context *ctx) {
|
|
ctx->state = NULL;
|
|
ctx->alloc = nn_defaultAlloc;
|
|
ctx->time = nn_defaultTime;
|
|
#ifndef NN_BAREMETAL
|
|
// someone pointed out that running this multiple times
|
|
// in 1 second can cause the RNG to loop.
|
|
// However, if you call this function multiple times at all,
|
|
// that's on you.
|
|
srand(time(NULL));
|
|
ctx->rngMaximum = RAND_MAX;
|
|
ctx->lockSize = sizeof(mtx_t);
|
|
#else
|
|
ctx->rngMaximum = 1;
|
|
ctx->lockSize = 0;
|
|
#endif
|
|
ctx->rng = nn_defaultRng;
|
|
ctx->lock = nn_defaultLock;
|
|
}
|