38 #ifndef LELY_EV_FIBER_MAX_UNUSED 39 #define LELY_EV_FIBER_MAX_UNUSED 16 84 &ev_fiber_exec_on_task_init,
85 &ev_fiber_exec_on_task_fini,
86 &ev_fiber_exec_dispatch,
116 static void ev_fiber_exec_func(
struct ev_task *task);
121 static int ev_fiber_exec_post_ctx(
struct ev_fiber_exec *exec);
141 static void ev_fiber_ctx_destroy(
struct ev_fiber_ctx *ctx);
144 static void ev_fiber_ctx_task_func(
struct ev_task *
task);
149 static void ev_fiber_return(
void);
200 static void ev_fiber_cnd_wake(
struct slnode *node);
238 while ((ctx = thr->
unused)) {
247 ev_fiber_exec_alloc(
void)
257 ev_fiber_exec_free(
void *ptr)
260 free(ev_fiber_exec_from_exec(ptr));
275 exec->inner_exec, &ev_fiber_exec_func);
299 ev_fiber_exec_abort(exec_, NULL);
307 assert(exec->
posted == 0);
326 ev_exec_t *tmp = ev_fiber_exec_init(exec, inner_exec);
336 ev_fiber_exec_free((
void *)exec);
346 ev_fiber_exec_fini(exec);
347 ev_fiber_exec_free((
void *)exec);
443 assert(impl->
locked < SIZE_MAX);
449 ev_fiber_mtx_lock_func, impl);
451 assert(impl->
locked == 1);
454 assert(impl->
ctx == NULL);
491 assert(impl->
locked < SIZE_MAX);
504 assert(impl->
ctx == NULL);
612 ev_fiber_cnd_wake(node);
637 ev_fiber_cnd_wake(node);
677 assert(impl->
locked == 1);
686 ev_fiber_exec_on_task_init(
ev_exec_t *exec_)
694 ev_fiber_exec_on_task_fini(
ev_exec_t *exec_)
707 assert(!task->
exec || task->
exec == exec_);
711 if (!ctx || ctx->
exec != exec) {
712 ev_fiber_exec_post(exec_, task);
732 assert(!task->
exec || task->
exec == exec_);
736 ev_fiber_exec_on_task_init(exec_);
753 ev_fiber_exec_post_ctx(exec);
765 assert(!task->
exec || task->
exec == exec_);
769 if (!ctx || ctx->
exec != exec) {
770 ev_fiber_exec_post(exec_, task);
776 ev_fiber_exec_on_task_init(exec_);
792 if (ctx && ctx->
exec == exec) {
814 ev_fiber_exec_on_task_fini(exec_);
821 ev_fiber_exec_func(
struct ev_task *task)
838 ev_fiber_exec_post_ctx(exec);
842 ev_fiber_exec_from_exec(
const ev_exec_t *exec)
873 assert(exec->
thr == thr);
898 exec->inner_exec, &ev_fiber_ctx_task_func);
958 ev_fiber_exec_on_task_fini(exec);
972 ev_fiber_ctx_task_func(
struct ev_task *task)
985 ev_fiber_resume(
fiber_t *fiber)
1001 #if !LELY_NO_THREADS 1005 ev_fiber_exec_post_ctx(exec);
1012 ev_fiber_await_func(
fiber_t *fiber,
void *arg)
1027 ev_fiber_return(
void)
1036 ev_fiber_return_func(
fiber_t *fiber,
void *arg)
1046 ev_fiber_ctx_destroy(ctx);
1052 ev_fiber_mtx_lock_func(
fiber_t *fiber,
void *arg)
1061 #if !LELY_NO_THREADS 1070 ev_fiber_cnd_wait_func(
fiber_t *fiber,
void *arg)
1085 #if !LELY_NO_THREADS 1089 #if !LELY_NO_THREADS 1094 mtx_impl->
ctx = NULL;
1095 assert(mtx_impl->
locked == 1);
1101 #if !LELY_NO_THREADS 1112 ev_fiber_cnd_wake(
struct slnode *node)
1124 #if !LELY_NO_THREADS 1134 #if !LELY_NO_THREADS struct ev_task task
The task used to resume the fiber.
void ev_exec_post(ev_exec_t *exec, struct ev_task *task)
Submits *task to *exec for execution.
fiber_t * fiber_resume(fiber_t *fiber)
Equivalent to fiber_resume_with(fiber, NULL, NULL).
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
struct ev_fiber_thrd * thr
A pointer to the ev_fiber_thrd instance for this executor.
Indicates that the requested operation succeeded.
The implementation of a fiber mutex.
size_t refcnt
The number of invocations of ev_fiber_thrd_init() minus the the number of invocation of ev_fiber_thrd...
ev_exec_t * ev_fiber_exec_create(ev_exec_t *inner_exec)
Creates a fiber executor.
Indicates that the requested operation failed because a resource requested by a test and return funct...
void mtx_destroy(mtx_t *mtx)
Releases any resources used by the mutex at mtx.
The context of a wait operation on a fiber condition variable.
ev_fiber_mtx_t * mtx
A pointer to the mutex passed to ev_fiber_cnd_wait().
struct ev_task task
The task used to create new fibers.
struct ev_task * task
A pointer to the task (in ev_fiber_ctx) used to wake up the fiber.
void ev_fiber_mtx_destroy(ev_fiber_mtx_t *mtx)
Releases any resources used by the fiber mutex at mtx.
void ev_fiber_await(ev_future_t *future)
Suspends a currently running fiber until the specified future becomes ready (or is cancelled)...
fiber_t * fiber
A pointer to the fiber containing this context.
The implementation of a fiber condition variable.
A synchronization primitive (similar to the standard C11 condition variable) that can be used to bloc...
size_t num_unused
The number of unused fibers.
A synchronization primitive (similar to the standard C11 mutex) that can be used to protect shared da...
const struct ev_exec_vtbl * exec_vptr
A pointer to the virtual table for the executor interface.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Indicates that the requested operation succeeded.
void ev_exec_on_task_fini(ev_exec_t *exec)
Undoes the effect of a previous call to ev_exec_on_task_init().
size_t ev_exec_abort(ev_exec_t *exec, struct ev_task *task)
Aborts the specified task submitted to *exec, if it has not yet begun executing, or all pending tasks...
A node in a singly-linked list.
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
Indicates that the requested operation failed.
mtx_t mtx
The mutex protecting queue.
fiber_t * prev
A pointer to the previously running (suspended) fiber.
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
A mutex type that supports neither timeout nor test and return.
struct sllist queue
The queue of tasks submitted to this executor.
ev_exec_t * inner_exec
A pointer to the inner executor.
int type
The type of mutex: ev_fiber_mtx_plain or ev_fiber_mtx_recursive.
int ev_fiber_mtx_lock(ev_fiber_mtx_t *mtx)
Suspends the currently running fiber until it locks the fiber mutex at mtx.
int mtx_unlock(mtx_t *mtx)
Unlocks the mutex at mtx.
void ev_fiber_exec_destroy(ev_exec_t *exec)
Destroys a fiber executor.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Indicates that the requested operation failed.
Indicates that the requested operation failed because it was unable to allocate memory.
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
fiber_t * fiber_create(fiber_func_t *func, void *arg, int flags, size_t data_size, size_t stack_size)
Creates a new fiber, allocates a stack and sets up a calling environment to begin executing the speci...
The implementation of a fiber executor.
struct ev_fiber_ctx * unused
The list of unused fibers.
This header file is part of the C11 and POSIX compatibility library; it includes <threads.h>, if it exists, and defines any missing functionality.
int mtx_lock(mtx_t *mtx)
Blocks until it locks the mutex at mtx.
size_t stack_size
The size (in bytes) of the stack frame allocated for each fiber.
int posted
A flag indicating whether task has been posted to inner_exec.
pthread_mutex_t mtx_t
A complete object type that holds an identifier for a mutex.
int fiber_thrd_init(int flags)
Initializes the fiber associated with the calling thread.
This header file is part of the utilities library; it contains the native and platform-independent er...
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
struct ev_fiber_ctx * ctx
A pointer to the fiber holding the lock.
fiber_t * fiber_resume_with(fiber_t *fiber, fiber_func_t *func, void *arg)
Suspends the calling fiber and resumes the specified fiber, optionally executing a function before re...
#define FIBER_GUARD_STACK
A flag specifying a fiber to add a guard page when allocating the stack frame so that the kernel gene...
void ev_exec_on_task_init(ev_exec_t *exec)
Indicates to the specified executor that a task will be submitted for execution in the future...
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
int ev_fiber_mtx_trylock(ev_fiber_mtx_t *mtx)
Endeavors to lock the fiber mutex at mtx.
struct sllist queue
The queue of fibers waiting for the condition variable to be signaled.
ev_fiber_cnd_t * cond
A pointer to the condition variable passed to ev_fiber_cnd_wait().
void fiber_destroy(fiber_t *fiber)
Destroys the specified fiber.
struct sllist queue
The queue of deferred tasks.
void ev_fiber_cnd_destroy(ev_fiber_cnd_t *cond)
Releases all resources used by the fiber condition variable at cond.
void * fiber_data(const fiber_t *fiber)
Returns a pointer to the data region of the specified fiber, or of the calling fiber if fiber is NULL...
int ev_fiber_mtx_init(ev_fiber_mtx_t *mtx, int type)
Creates a fiber mutex object with properties indicated by type, which must have one of the four value...
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
Indicates that the requested operation failed because it was unable to allocate memory.
struct sllist queue
The queue of fibers waiting to acquire the lock.
int ev_fiber_cnd_init(ev_fiber_cnd_t *cond)
Creates a fiber condition variable.
mtx_t mtx
The mutex protecting locked and queue.
struct ev_fiber_exec * exec
The executor using this fiber.
struct slnode node
The node in the queue of fibers waiting on cond.
The context of a fiber used for executing tasks.
int ev_fiber_cnd_wait(ev_fiber_cnd_t *cond, ev_fiber_mtx_t *mtx)
Atomically unlocks the fiber mutex at mtx and endeavors to block until the fiber condition variable a...
This header file is part of the C11 and POSIX compatibility library; it includes <stdint.h> and defines any missing functionality.
int ev_fiber_thrd_init(int flags, size_t stack_size, size_t max_unused)
Initializes the calling thread for use by fiber executors.
This header file is part of the event library; it contains the task declarations. ...
size_t max_unused
The maximum number of unused fibers for this thread.
int ev_fiber_mtx_unlock(ev_fiber_mtx_t *mtx)
Unlocks the fiber mutex at mtx.
#define LELY_EV_FIBER_MAX_UNUSED
The maximum number of unused fibers per thread.
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
This header file is part of the event library; it contains the abstract task executor interface...
size_t pending
The number of pending fibers available to execute a task.
#define _Thread_local
An object whose identifier is declared with the storage-class specifier _Thread_local has thread stor...
size_t locked
The number of times the mutex has been recursively locked.
The parameters used for creating fibers on this thread and the list of unused fibers.
struct ev_task * ev_task_from_node(struct slnode *node)
Converts a pointer to a node in a queue to the address of the task containing the node...
void fiber_thrd_fini(void)
Finalizes the fiber associated with the calling thread.
ev_task_func_t * func
The function to be invoked when the task is run.
ev_exec_t * ev_fiber_exec_get_inner_exec(const ev_exec_t *exec_)
Returns a pointer to the inner executor of a fiber executor.
This header file is part of the event library; it contains the fiber executor, mutex and condition va...
int ev_fiber_cnd_broadcast(ev_fiber_cnd_t *cond)
Unblocks all of the fibers that are blocked on the fiber condition variable at cond at the time of th...
int flags
The flags used when creating each fiber.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
This is the internal header file of the event library.
void ev_fiber_thrd_fini(void)
Finalizes the calling thread and prevents further use by fiber executors.
int ev_fiber_cnd_signal(ev_fiber_cnd_t *cond)
Unblocks one of the fibers that are blocked on the fiber condition variable at cond at the time of th...
mtx_t mtx
The mutex protecting posted and queue.
A fiber mutex type that supports recursive locking.
struct ev_fiber_ctx * curr
A pointer to the currently running fiber.
This is the public header file of the utilities library.
void ev_future_submit(ev_future_t *future, struct ev_task *task)
Submits a task to be executed once the specified future is ready.
int mtx_init(mtx_t *mtx, int type)
Creates a mutex object with properties indicated by type, which must have one of the four values: ...
struct ev_fiber_ctx * next
A pointer to the next fiber in the list of unused fibers.