41#define XXH_STATIC_LINKING_ONLY
42#define XXH_ENABLE_AUTOVECTORIZE
47#define XXH_NO_LONG_LONG
49#define XXH_IMPLEMENTATION
50#include "third_party/xxhash.h"
52#if defined(__linux__) || defined(__GLIBC__)
53# include <sys/random.h>
54#elif defined(__APPLE__)
60# pragma comment(lib, "bcrypt.lib")
69 for (
int attempt = 0; attempt < 8; attempt++) {
73 auto res = getrandom(&s,
sizeof(s), 0);
75 PANIC(
"Can't get a random number");
77#elif defined(__APPLE__)
78 arc4random_buf(&s,
sizeof(s));
80 NTSTATUS st = BCryptGenRandom(
nullptr, (PUCHAR)&s,
sizeof(s), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
82 PANIC(
"Couldn't allocate a seed");
86 FILE *f = fopen(
"/dev/urandom",
"rb");
88 size_t got = fread(&s,
sizeof(s), 1, f);
90 PANIC_IF(got != 1,
"Couldn't read a seed from /dev/urandom");
98 PANIC(
"Couldn't generate a nonzero seed");
105 if (engine ==
nullptr) {
129 UNUSED(signal(SIGPIPE, SIG_IGN));
132#ifdef SRN_WITH_SERENE
138#ifdef SRN_WITH_SERENE
144 engine->namespaces =
hmap_empty(engine->root_context);
146 engine->keywords =
hmap_empty(engine->root_context);
160#ifdef SRN_WITH_SERENE
168 size_t length = (data ==
nullptr) ? 0 : len;
169 return XXH32(data, length, engine->
seed);
174 return atomic_fetch_add_explicit(&engine->
object_id_counter, 1, memory_order_relaxed);
177#ifdef SRN_WITH_SERENE
188 size_t name_len = strnlen(name, max_len);
193 hmap_key_t lookup = {.data = (
void *)name, .len = name_len};
194 void *found =
hmap_lookup(&engine->keywords, &lookup,
nullptr);
195 if (found !=
nullptr) {
200 if (name_len == max_len) {
202 return srn_errors_make_error(
213 size_t name_alloc_size =
sizeof(
srn_string_t) + name_len + 1;
216 name_str->
len = name_len;
217 name_str->
size = name_len + 1;
218 memcpy(name_str->
buffer, name, name_len);
219 name_str->
buffer[name_len] =
'\0';
232 engine->keywords =
hmap_insert(&engine->keywords, &k, (
void *)v);
void srn_config_validate(const srn_configuration_t *config)
A configuration with every field set to its default.
#define SRN_CONFIG_DEFAULTS
srn_context_t * srn_context_make(srn_engine_t *engine)
Make an empty context, by allocating a new memory block.
int srn_context_release(srn_context_t *ctx)
void * srn_mm_immortal_allocate_aligned(srn_mm_t *mm, size_t size, size_t alignment)
Allocate memory on the importal block which will never gets freed.
void srn_engine_shutdown(srn_engine_t *engine)
srn_engine_t * srn_engine_make(srn_mm_t *mm, const srn_configuration_t *config)
Create the engine over mm, copying config (the runtime's knobs) into it.
srn_hash_t srn_hash(const srn_engine_t *engine, const void *data, size_t len)
static srn_seed_t srn_generate_seed()
srn_object_id_t srn_allocate_object_id(srn_engine_t *engine)
#define ENGINE_FIRST_OBJECT_ID
Start allocating IDs from 100, earlier IDs are reserved.
Error handling for the runtime.
@ STRING_LENGTH_LIMIT_EXCEEDED
AI Generated (🤦) Fiber subsystem overview.
hmap_t hmap_insert(const hmap_t *hmap, hmap_key_t *k, void *v)
Insert the given key k with the value v in the given hash hmap and return the new map.
hmap_t hmap_empty(const srn_context_t *ctx)
Create, initialize and return a new hashmap pinned to ctx.
void * hmap_lookup(const hmap_t *hmap, const hmap_key_t *k, void *default_value)
Lookup the given k in the given hmap and return the value if it's been found.
This is an implementation of Compressed Hash-Array Mapped Prefix-tree, which is a bit-partitioned,...
#define srn_mm_immortal_allocate(mm, T)
int srn_jit_shutdown(srn_jit_t *jit)
srn_jit_t * srn_jit_make(srn_mm_t *mm)
void srn_reactor_shutdown(srn_reactor_t *reactor)
Tear the reactor down, stop and join the reactor thread and release its channels.
srn_reactor_t * srn_reactor_init(srn_engine_t *engine)
Allocate the IO reactor from the engine.
void srn_sched_shutdown(srn_scheduler_t *sched)
The one stop tear down of the fiber subsystem, should be called once srn_sched_run has returned.
srn_scheduler_t * srn_sched_init(srn_engine_t *engine)
Note: For key equality we use the memcpy function.
Every runtime knob, in one place.
srn_limits_config_t limits
srn_engine_t * engine
Long term state of the compiler.
Engine is a structure to own the long living and main pieces of the compiler.
srn_configuration_t config
The runtime's tunable knobs, the single source for every configurable value (see configuration....
_Atomic srn_object_id_t object_id_counter
An unsigned counter to allocate object ids atomically.
srn_scheduler_t * scheduler
The fiber scheduler, that is the entry point of the fiber subsystem.
srn_seed_t seed
We use the seed for hashing and the value will be generated at random for each new context.
srn_mm_t * mm
Memory manager.
srn_reactor_t * reactor
The I/O reactor, that is in charge of handling everything I/O.
size_t string_max_len
Largest string accepted, in bytes.
Main memory manager structure that will own all the allocated blocks and data.
size_t size
Size of the buffer.
uint8_t buffer[]
The buffer that holds the WTF8 sequence.
size_t len
length of the WTF-8 sequence in bytes
srn_metadata_t * metadata
union srn_value_t::@033047061046230251001111174367071167226300135003 as
IMPORTANT NOTE: The size of this union should never be larger than a word.
#define PANIC_IF_NULL(ptr)
static void srn_spinlock_lock(srn_spinlock_t *lock)
#define PANIC_IF(cond, msg)
static void srn_spinlock_unlock(srn_spinlock_t *lock)
static void srn_spinlock_init(srn_spinlock_t *lock)