Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
engine.h File Reference
#include <stdatomic.h>
#include <stddef.h>
#include <stdint.h>
#include "serene/rt/configuration.h"
#include "serene/rt/impl/hashmap.h"
#include "serene/utils.h"
Include dependency graph for engine.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  srn_engine_t
 Engine is a structure to own the long living and main pieces of the compiler. More...

Macros

#define SRN_HASH_TYPE   uint32_t
#define SRN_SEED_TYPE   uint32_t
#define ENGINE_FIRST_OBJECT_ID   100
 Start allocating IDs from 100, earlier IDs are reserved.

Typedefs

typedef struct srn_scheduler_t srn_scheduler_t
typedef struct srn_reactor_t srn_reactor_t
 The implementation is internal to the runtime.
typedef struct srn_sm_t srn_sm_t
typedef uint64_t srn_object_id_t
typedef struct srn_engine_t srn_engine_t
 Engine is a structure to own the long living and main pieces of the compiler.

Functions

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.
void srn_engine_shutdown (srn_engine_t *engine)
srn_object_id_t srn_allocate_object_id (srn_engine_t *engine)
srn_hash_t srn_hash (const srn_engine_t *engine, const void *data, size_t len)

Macro Definition Documentation

◆ ENGINE_FIRST_OBJECT_ID

#define ENGINE_FIRST_OBJECT_ID   100

Start allocating IDs from 100, earlier IDs are reserved.

Definition at line 47 of file engine.h.

◆ SRN_HASH_TYPE

#define SRN_HASH_TYPE   uint32_t

Definition at line 29 of file engine.h.

◆ SRN_SEED_TYPE

#define SRN_SEED_TYPE   uint32_t

Definition at line 30 of file engine.h.

Typedef Documentation

◆ srn_engine_t

typedef struct srn_engine_t srn_engine_t

Engine is a structure to own the long living and main pieces of the compiler.

There will be only oe instance of the engine at anytime.

◆ srn_object_id_t

typedef uint64_t srn_object_id_t

Definition at line 45 of file engine.h.

◆ srn_reactor_t

typedef struct srn_reactor_t srn_reactor_t

The implementation is internal to the runtime.

Definition at line 41 of file engine.h.

◆ srn_scheduler_t

typedef struct srn_scheduler_t srn_scheduler_t

Definition at line 40 of file engine.h.

◆ srn_sm_t

typedef struct srn_sm_t srn_sm_t

Definition at line 42 of file engine.h.

Function Documentation

◆ srn_allocate_object_id()

srn_object_id_t srn_allocate_object_id ( srn_engine_t * engine)

Definition at line 193 of file engine.c.

193 {
194 PANIC_IF_NULL(engine);
195 return atomic_fetch_add_explicit(&engine->object_id_counter, 1, memory_order_relaxed);
196}
_Atomic srn_object_id_t object_id_counter
An unsigned counter to allocate object ids atomically.
Definition engine.h:60
#define PANIC_IF_NULL(ptr)
Definition utils.h:66
Here is the caller graph for this function:

◆ srn_engine_make()

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.

Pass nullptr for config to use the defaults. config is read only during the call, so the caller may pass a stack value.

Definition at line 103 of file engine.c.

103 {
104 PANIC_IF_NULL(mm);
106
107 if (engine == nullptr) {
108 return nullptr;
109 }
110
111 // A null `config` means "use the defaults"; otherwise copy the caller's
112 // knobs. Either way the engine owns its copy, so the caller's `config` need
113 // not outlive this call. Validating the copy makes a bad knob fail loudly
114 // here, before anything is sized or bounded by it.
115 engine->config = (config != nullptr) ? *config : SRN_CONFIG_DEFAULTS;
116 srn_config_validate(&engine->config);
117
118 engine->seed = srn_generate_seed();
119 // Just reserving 0..100 for any unpredicted needs
120 engine->mm = mm;
121
122#if !defined(_WIN32)
123 // A fiber writing to a peer that has closed its end would otherwise raise
124 // SIGPIPE and take the whole process down. The reactor's WRITE path uses
125 // write(), which cannot pass MSG_NOSIGNAL, so suppress SIGPIPE process-wide
126 // and let the operation fail with -EPIPE instead. Idempotent across engines.
127 // Something to have a look at:
128 // https://stackoverflow.com/questions/8369506/why-does-sigpipe-exist
129 // Also since we're ignoring sigpipe here permanently, we can safely ignore
130 // the returning previous signal handler by the signal function call
131 UNUSED(signal(SIGPIPE, SIG_IGN));
132#endif
133
134#ifdef SRN_WITH_SERENE
135 // engine->jit = srn_jit_create(mm, nullptr);
136 // PANIC_IF_NULL(engine->jit);
137#endif
138 engine->scheduler = srn_sched_init(engine);
139 engine->reactor = srn_reactor_init(engine);
140
141#ifdef SRN_WITH_SERENE
142 // Both registries outlive every user context, so they are pinned to a
143 // context the engine itself owns. Every trie node an insert creates lands
144 // in this context's block chain, which is released only at engine
145 // shutdown.
146 engine->root_context = srn_context_make(engine);
147
148 // Each registry head is an immutable, heap allocated map that readers load
149 // atomically without a lock. Writers replace the head under the matching
150 // mutex, so the mutexes live in the same context as the heads. Nothing
151 // else can see the engine yet, so the atomics are initialized instead of stored.
152 hmap_t *namespaces = ALLOC_OR_PANIC(engine->root_context, hmap_t);
153 *namespaces = hmap_empty(engine->root_context);
154 atomic_init(&engine->namespaces, namespaces);
155
156 engine->ns_lock = ALLOC_OR_PANIC(engine->root_context, srn_fiber_mutex_t);
157 srn_fiber_mutex_init(engine->ns_lock);
158
159 hmap_t *keywords = ALLOC_OR_PANIC(engine->root_context, hmap_t);
160 *keywords = hmap_empty(engine->root_context);
161 atomic_init(&engine->keywords, keywords);
162
163 engine->keywords_lock = ALLOC_OR_PANIC(engine->root_context, srn_fiber_mutex_t);
164 srn_fiber_mutex_init(engine->keywords_lock);
165#endif
166 atomic_init(&engine->object_id_counter, ENGINE_FIRST_OBJECT_ID);
167
168 // TODO(lxsameer): Should we create a sub context out of root?
169 engine->source_manager = srn_sm_init(engine->root_context);
170
171 return engine;
172}
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.
Definition context.c:39
#define ALLOC_OR_PANIC(ctx, T)
Definition context.h:98
static srn_seed_t srn_generate_seed()
Definition engine.c:67
#define ENGINE_FIRST_OBJECT_ID
Start allocating IDs from 100, earlier IDs are reserved.
Definition engine.h:47
hmap_t hmap_empty(const srn_context_t *ctx)
Create, initialize and return a new hashmap pinned to ctx.
Definition hashmap.c:655
#define srn_mm_immortal_allocate(mm, T)
Definition interface.h:188
void srn_fiber_mutex_init(srn_fiber_mutex_t *m)
Initialise m to the unlocked state.
Definition mutex.c:76
srn_reactor_t * srn_reactor_init(srn_engine_t *engine)
Allocate the IO reactor from the engine.
Definition reactor.c:34
srn_scheduler_t * srn_sched_init(srn_engine_t *engine)
Definition scheduler.c:263
srn_sm_t * srn_sm_init(srn_context_t *ctx)
Initialize the source manager, as an immortal data structure.
Engine is a structure to own the long living and main pieces of the compiler.
Definition engine.h:54
srn_configuration_t config
The runtime's tunable knobs, the single source for every configurable value (see configuration....
Definition engine.h:65
srn_scheduler_t * scheduler
The fiber scheduler, that is the entry point of the fiber subsystem.
Definition engine.h:78
srn_seed_t seed
We use the seed for hashing and the value will be generated at random for each new context.
Definition engine.h:89
srn_mm_t * mm
Memory manager.
Definition engine.h:68
srn_reactor_t * reactor
The I/O reactor, that is in charge of handling everything I/O.
Definition engine.h:81
#define UNUSED(x)
Definition utils.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_engine_shutdown()

void srn_engine_shutdown ( srn_engine_t * engine)

Definition at line 174 of file engine.c.

174 {
175 PANIC_IF_NULL(engine);
176
179 srn_sm_shutdown(engine->source_manager);
180
181#ifdef SRN_WITH_SERENE
182 // srn_jit_destroy(engine->jit);
183 srn_context_release(engine->root_context);
184#endif
185}
int srn_context_release(srn_context_t *ctx)
Definition context.c:64
void srn_reactor_shutdown(srn_reactor_t *reactor)
Tear the reactor down, stop and join the reactor thread and release its channels.
Definition reactor.c:66
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.
Definition scheduler.c:333
void srn_sm_shutdown(srn_sm_t *sm)
Shutdown the source manager freeing all the buffers.
Here is the call graph for this function:

◆ srn_hash()

srn_hash_t srn_hash ( const srn_engine_t * engine,
const void * data,
size_t len )

Definition at line 187 of file engine.c.

187 {
188 // NULL pointers are only valid if the length is zero
189 size_t length = (data == nullptr) ? 0 : len;
190 return XXH32(data, length, engine->seed);
191}
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32(const void *input, size_t length, XXH32_hash_t seed)
Calculates the 32-bit hash of input using xxHash32.
const size_t len
Here is the call graph for this function:
Here is the caller graph for this function: