bio
 
Loading...
Searching...
No Matches
internal.h
1#ifndef BIO_INTERNAL_H
2#define BIO_INTERNAL_H
3
46#ifndef BIO_DEFAULT_NUM_CLS_BUCKETS
47# define BIO_DEFAULT_NUM_CLS_BUCKETS 4
48#endif
49
51#ifndef BIO_DEFAULT_THREAD_POOL_SIZE
52# define BIO_DEFAULT_THREAD_POOL_SIZE 2
53#endif
54
56#ifndef BIO_DEFAULT_THREAD_POOL_QUEUE_SIZE
57# define BIO_DEFAULT_THREAD_POOL_QUEUE_SIZE 2
58#endif
59
62#if defined(__linux__)
63# include "linux/platform.h"
64#elif defined(_WIN32)
65# include "windows/platform.h"
66#elif defined(__FreeBSD__)
67# include "freebsd/platform.h"
68#else
69# error "Unsupported platform"
70#endif
71
72#include <bio/bio.h>
73#include <stdio.h>
74#include "array.h"
75
76#ifdef __GNUC__
77# define BIO_LIKELY(X) __builtin_expect(!!(X), 1)
78#else
79# define BIO_LIKELY(X) (X)
80#endif
81
82#define BIO_DEFINE_LIST_LINK(NAME) \
83 typedef struct NAME##_s { \
84 struct NAME##_s* next; \
85 struct NAME##_s* prev; \
86 } NAME##_t
87
88#define BIO_LIST_APPEND(list, item) \
89 do { \
90 (item)->next = (list); \
91 (item)->prev = (list)->prev; \
92 (list)->prev->next = (item); \
93 (list)->prev = (item); \
94 } while (0)
95
96#define BIO_LIST_REMOVE(item) \
97 do { \
98 if ((item)->next != NULL) { \
99 (item)->next->prev = (item)->prev; \
100 (item)->prev->next = (item)->next; \
101 (item)->next = NULL; \
102 (item)->prev = NULL; \
103 } \
104 } while (0)
105
106#define BIO_LIST_IS_EMPTY(list) \
107 ((list)->next == (list) || (list)->next == NULL)
108
109#define BIO_LIST_INIT(list) \
110 do { \
111 (list)->next = (list); \
112 (list)->prev = (list); \
113 } while (0)
114
115#define BIO_LIST_POP(list) \
116 BIO_LIST_REMOVE((list)->next)
117
118#define BIO_CONTAINER_OF(ptr, type, member) \
119 ((type *)((char *)(1 ? (ptr) : &((type *)0)->member) - offsetof(type, member)))
120
121#ifdef _MSC_VER
122# define BIO_ALIGN_TYPE long double
123#else
124# define BIO_ALIGN_TYPE max_align_t
125#endif
126
127typedef struct {
128 const bio_tag_t* tag;
129 void* obj;
130
131 int32_t gen;
132 int32_t next_handle_slot;
134
135typedef struct mco_coro mco_coro;
136
137BIO_DEFINE_LIST_LINK(bio_signal_link);
138BIO_DEFINE_LIST_LINK(bio_logger_link);
139BIO_DEFINE_LIST_LINK(bio_monitor_link);
140BIO_DEFINE_LIST_LINK(bio_cls_link);
141
142typedef struct bio_coro_impl_s bio_coro_impl_t;
143
144typedef struct {
145 bio_signal_link_t link;
146
147 bio_coro_impl_t* owner;
148 bio_handle_t handle;
149
150 int wait_counter;
152
153typedef struct {
154 bio_cls_link_t link;
155 const bio_cls_t* spec;
156
157 _Alignas(BIO_ALIGN_TYPE) char data[];
159
160typedef struct {
161 bio_signal_t signal;
162 bio_exit_reason_t reason;
164
166 mco_coro* impl;
167 bio_entrypoint_t entrypoint;
168 bool daemon;
169 void* userdata;
170 void* extra_data;
171 const bio_tag_t* extra_data_tag;
172 const char* name;
173 bio_cls_link_t* cls_buckets;
174
175 bio_handle_t handle;
176 bio_coro_state_t state;
177
178 bio_signal_link_t pending_signals;
179 bio_monitor_link_t monitors;
180
181 int num_blocking_signals;
182 int wait_counter;
183};
184
185typedef struct {
186 bio_monitor_link_t link;
187 bio_handle_t handle;
188 bio_signal_t signal;
190
191typedef struct bio_worker_thread_s bio_worker_thread_t;
192
193typedef struct {
194 bio_time_t due_time_ms;
195 bio_signal_t signal;
197
198typedef struct {
199 char* ptr;
200 int len;
202
203typedef struct {
204 bio_options_t options;
205 bool is_terminating;
206 BIO_ARRAY(bio_exit_info_t*) exit_handlers;
207
208 // Handle table
209 bio_handle_slot_t* handle_slots;
210 int32_t handle_capacity;
211 int32_t next_handle_slot;
212 int32_t num_handles;
213
214 // Timer
215 bio_timer_entry_t* timer_entries;
216 int32_t timer_capacity;
217 int32_t num_timers;
218 bio_time_t current_time_ms;
219
220 // Scheduler
221 BIO_ARRAY(bio_coro_impl_t*) current_ready_coros;
222 BIO_ARRAY(bio_coro_impl_t*) next_ready_coros;
223 int32_t num_coros;
224 int32_t num_daemons;
225
226 // Logging
227 bio_logger_link_t loggers;
228 int log_prefix_len;
229
230 // Thread pool
231 bio_worker_thread_t* thread_pool;
232 int32_t num_running_async_jobs;
233
234 // Platform specific
235 bio_platform_t platform;
236} bio_ctx_t;
237
238typedef enum {
239 BIO_PLATFORM_UPDATE_NO_WAIT,
240 BIO_PLATFORM_UPDATE_WAIT_INDEFINITELY,
241 BIO_PLATFORM_UPDATE_WAIT_NOTIFIABLE,
242} bio_platform_update_type_t;
243
244extern bio_ctx_t bio_ctx;
245
246static inline void*
247bio_realloc(void* ptr, size_t size) {
248 return bio_ctx.options.allocator.realloc(ptr, size, bio_ctx.options.allocator.ctx);
249}
250
251static inline void*
252bio_malloc(size_t size) {
253 return bio_realloc(NULL, size);
254}
255
256static inline void
257bio_free(void* ptr) {
258 bio_realloc(ptr, 0);
259}
260
261static inline uint32_t
262bio_next_pow2(uint32_t v) {
263 uint32_t next = v;
264 next--;
265 next |= next >> 1;
266 next |= next >> 2;
267 next |= next >> 4;
268 next |= next >> 8;
269 next |= next >> 16;
270 next++;
271
272 return next;
273}
274
275static inline int
276bio_vfmt(bio_fmt_buf_t* buf, const char* fmt, va_list args) {
277 va_list args_copy;
278 va_copy(args_copy, args);
279 int num_chars = vsnprintf(buf->ptr, (size_t)buf->len, fmt, args_copy);
280 va_end(args_copy);
281
282 if (num_chars < 0) { return num_chars; } // Format error
283
284 if (num_chars >= (int)buf->len) {
285 bio_free(buf->ptr);
286 buf->ptr = bio_malloc(num_chars + 1);
287 buf->len = num_chars + 1;
288
289 vsnprintf(buf->ptr, (size_t)buf->len, fmt, args);
290 }
291
292 buf->ptr[num_chars] = '\0';
293 return num_chars;
294}
295
296BIO_FORMAT_ATTRIBUTE(2, 3)
297static inline int
298bio_fmt(bio_fmt_buf_t* buf, const char* fmt, ...) {
299 va_list args;
300 va_start(args, fmt);
301 int num_chars = bio_vfmt(buf, fmt, args);
302 va_end(args);
303 return num_chars;
304}
305
306void
307bio_set_core_error(bio_error_t* error, bio_core_error_code_t code, const char* file, int line);
308
309#define bio_set_core_error(error, code) bio_set_core_error(error, code, __FILE__, __LINE__)
310
316// Platform
317
319void
321
323void
325
346void
347bio_platform_update(bio_time_t wait_timeout_ms, bool notifiable);
348
356void
358
366
368void
370
372void
374
381void
383
389void
391
393void
395
396// File
397
399void
401
403void
405
406// Net
407
409void
411
413void
415
418// Handle table
419
420void
421bio_handle_table_init(void);
422
423void
424bio_handle_table_cleanup(void);
425
426// Timer
427
428void
429bio_timer_init(void);
430
431void
432bio_timer_cleanup(void);
433
434void
435bio_timer_update(void);
436
438bio_time_until_next_timer(void);
439
440// Scheduler
441
442void
443bio_scheduler_init(void);
444
445void
446bio_scheduler_cleanup(void);
447
448// Thread
449
450void
451bio_thread_init(void);
452
453void
454bio_thread_cleanup(void);
455
456void
457bio_thread_update(void);
458
459int32_t
460bio_num_running_async_jobs(void);
461
462// Logging
463
464void
465bio_logging_init(void);
466
467void
468bio_logging_cleanup(void);
469
470#endif
void(* bio_entrypoint_t)(void *userdata)
Entrypoint for a coroutine.
Definition bio.h:120
bio_coro_state_t
State of a coroutine.
Definition bio.h:504
bio_core_error_code_t
Core error codes.
Definition bio.h:616
void bio_net_cleanup(void)
Cleanup the Network I/O subsystem.
void bio_platform_unblock_exit_signal(void)
Unblock exit signals from the OS.
void bio_net_init(void)
Initialize the Network I/O subsystem.
void bio_platform_end_create_thread_pool(void)
Called after the async thread pool is created.
void bio_platform_update(bio_time_t wait_timeout_ms, bool notifiable)
Check on I/O completion status.
void bio_platform_block_exit_signal(void)
Block exit signals from the OS.
void bio_handle_exit_signal(void)
Callback for a platform implementation to notify bio of exit signal.
bio_time_t bio_platform_current_time_ms(void)
Return the current time in milliseconds.
void bio_platform_cleanup(void)
Cleanup the platform layer.
void bio_platform_init(void)
Initialize the platform layer.
void bio_platform_begin_create_thread_pool(void)
Called before the async thread pool is created.
void bio_platform_notify(void)
Make bio_platform_update return.
void bio_fs_cleanup(void)
Cleanup the File I/O subsystem.
void bio_fs_init(void)
Initialize the File I/O subsystem.
bio_exit_reason_t
Result for bio_wait_for_exit.
Definition bio.h:520
int64_t bio_time_t
A timestamp.
Definition bio.h:213
void *(* realloc)(void *ptr, size_t size, void *ctx)
Allocation function.
Definition bio.h:308
void * ctx
Allocator context.
Definition bio.h:290
Definition internal.h:153
Coroutine-local storage (CLS) specification.
Definition bio.h:317
Definition internal.h:165
Definition internal.h:203
An error returned from a function.
Definition bio.h:468
Definition internal.h:160
Definition internal.h:198
Definition internal.h:127
Definition bio.h:126
Definition internal.h:185
Initialization options.
Definition bio.h:408
bio_allocator_t allocator
Custom allocator. Defaults to stdlib if not provided.
Definition bio.h:410
Definition platform.h:41
Definition internal.h:144
Handle to a signal.
Definition bio.h:147
A unique tag.
Definition bio.h:189
Definition internal.h:193