42 sm->buffer_counts = 0;
54 while (
buffer !=
nullptr) {
56 if (
buffer->data !=
nullptr) {
74 sm->buffer_counts = 0;
87 PANIC(
"Source buffer id is not in the correct range");
100 int fd = open(filepath, O_RDONLY);
106 result.maybe_error =
ERR(
sm->ctx, tag,
"Failed to open the file.");
111 if (fstat(
fd, &st) < 0) {
114 result.maybe_error =
ERR(
sm->ctx, tag,
"Failed to stat the file.");
118 if (S_ISDIR(st.st_mode)) {
125 if (!S_ISREG(st.st_mode)) {
134 if (st.st_size == 0) {
148 while (
total < (
size_t)st.st_size) {
151 r = srn_fiber_read(fd, buf + total, (size_t)st.st_size - total, -1);
176 result.maybe_error =
nullptr;
181 k.
data = (
void *)filepath;
182 k.
len = strnlen(filepath, PATH_MAX);
188 WITH_LOCK(&
sm->write_lock, { snapshot = sm->file_to_id_map; });
204 buf->
data = maybe_buffer.buffer;
205 buf->
len = maybe_buffer.len;
211 bool lost_race =
false;
216 void *again = hmap_lookup(&sm->file_to_id_map, &k, (void *)SRN_SM_NO_ID);
217 if ((uintptr_t)again != SRN_SM_NO_ID) {
218 result.id = (srn_sm_buffer_id_t)(uintptr_t)again;
220 }
else if (
sm->buffer_counts >= UINT16_MAX) {
225 ERR(sm->ctx, SM_BUFFER_ID_EXHAUSTED,
"source manager: buffer ID space exhausted");
230 result.maybe_error = array_list_push(&sm->buffers, buf);
231 if (result.maybe_error == nullptr) {
232 sm->file_to_id_map = hmap_insert(&sm->file_to_id_map, &k, (void *)sm->buffer_counts);
233 result.id = sm->buffer_counts;
264 buf->
data = maybe_new_buffer.buffer;
265 buf->
len = maybe_new_buffer.len;
273 auto update_err = array_list_update(&sm->buffers, buffer_id, buf);
274 PANIC_IF(update_err != nullptr,
"failed to update source buffer slot");
static int const char char buffer[256]
array_list_maybe_element_t array_list_get(const array_list_t *al, array_list_index_t n)
Negative index is not supported.
array_list_t array_list_empty(const srn_context_t *ctx)
Create an empty array list in the given context ctx.
srn_error_t * array_list_for_each(array_list_t *al, array_list_for_each_f_t f)
Run the give function f for every element in the given array list al.
A bit-partitioned trie with a tail buffer, used as a growable indexed sequence in the runtime.
void srn_mm_free(srn_mm_t *mm, void *ptr)
Release a pointer previously returned by srn_mm_malloc or srn_mm_reallocate.
void * srn_mm_malloc(srn_mm_t *mm, size_t size)
Generic allocations that do not participate in the block based pools.
Error handling for the runtime.
#define PUSH_AND_MOVE(ctx, from, to)
#define ERR_FROM(ctx, src)
#define HAS_ERROR(x)
True when x – a value carrying an ERROR_HEADER – has an error attached.
srn_error_tag_t
The kind of a failure.
@ INVALID_ARGUMENT
The request itself is malformed (an empty POLL interest mask, for example), so retrying it unchanged ...
srn_error_tag_t srn_errno_to_tag(int errno_value, srn_error_tag_t default_tag)
Map a POSIX errno to error tag.
#define ERR(ctx, err, msg)
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)
The fiber facing IO API: blocking looking calls a fiber uses to do IO.
#define SRN_WITH_RETRY(err,...)
Run block and retry it (yielding between attempts through srn_fiber_io_retry) while err holds the tra...
void srn_fiber_mutex_init(srn_fiber_mutex_t *m)
Initialise m to the unlocked state.
#define WITH_LOCK(lock, body)
Run body with lock held.
static maybe_buffer_t read_file(srn_sm_t *sm, const char *filepath)
srn_sm_maybe_buffer_t srn_sm_buffer_file(srn_sm_t *sm, const char *filepath, bool reread)
Read and buffer the given filepath into the source manager and return a srn_sm_maybe_buffer_t which e...
void srn_sm_shutdown(srn_sm_t *sm)
Shutdown the source manager freeing all the buffers.
srn_sm_t * srn_sm_init(srn_context_t *ctx)
Initialize the source manager, as an immortal data structure.
srn_sm_buffer_t * srn_sm_get_buffer(srn_sm_t *sm, srn_sm_buffer_id_t id)
Return the buffer pointer of the given id, nullptr if the id does not exists.
static srn_error_t * free_each_buffer_chain(array_list_t *al, size_t n, void *data)
srn_sm_maybe_id_t srn_sm_read_buffer_file(srn_sm_t *sm, const char *filepath, bool reread)
Read and buffer the given filepath into the source manager and return the buffer id.
Source manager is what that read the source files and own the buffer that contains the data.
#define SM_TRACEPOINT(...)
size_t srn_sm_buffer_id_t
const srn_context_t * ctx
The context that owns every allocation the array list retains.
Note: For key equality we use the memcpy function.
void * data
len 0 -> data == nullptr
srn_engine_t * engine
Long term state of the compiler.
srn_mm_t * mm
Memory manager.
A runtime error, a tag classifying the failure and a human-readable message.
The result of a byte transfer op (read/write/sendto/recvmsg/sendmsg).
unsigned char * data
nullptr when the source file was empty (no mapping exists)
struct srn_sm_buffer_t * next
#define PANIC_IF_NULL(ptr)
#define PANIC_IF(cond, msg)
char * srn_dup_str(srn_mm_t *mm, const char *s)
Copy a null terminated C string into a fresh allocation made through mm.