41 #ifndef LELY_EV_FIBER_MAX_UNUSED
43 #define LELY_EV_FIBER_MAX_UNUSED 16
87 &ev_fiber_exec_on_task_init,
88 &ev_fiber_exec_on_task_fini,
89 &ev_fiber_exec_dispatch,
119 static void ev_fiber_exec_func(
struct ev_task *task);
124 static int ev_fiber_exec_post_ctx(
struct ev_fiber_exec *exec);
144 static void ev_fiber_ctx_destroy(
struct ev_fiber_ctx *ctx);
147 static void ev_fiber_ctx_task_func(
struct ev_task *
task);
152 static void ev_fiber_return(
void);
203 static void ev_fiber_cnd_wake(
struct slnode *node);
241 while ((ctx = thr->
unused)) {
250 ev_fiber_exec_alloc(
void)
266 ev_fiber_exec_free(
void *ptr)
269 free(ev_fiber_exec_from_exec(ptr));
284 exec->inner_exec, &ev_fiber_exec_func);
308 ev_fiber_exec_abort(exec_, NULL);
316 assert(exec->
posted == 0);
345 ev_fiber_exec_free((
void *)exec);
355 ev_fiber_exec_fini(exec);
356 ev_fiber_exec_free((
void *)exec);
452 assert(impl->
locked < SIZE_MAX);
458 ev_fiber_mtx_lock_func, impl);
460 assert(impl->
locked == 1);
463 assert(impl->
ctx == NULL);
500 assert(impl->
locked < SIZE_MAX);
513 assert(impl->
ctx == NULL);
621 ev_fiber_cnd_wake(node);
646 ev_fiber_cnd_wake(node);
686 assert(impl->
locked == 1);
695 ev_fiber_exec_on_task_init(
ev_exec_t *exec_)
703 ev_fiber_exec_on_task_fini(
ev_exec_t *exec_)
721 ev_fiber_exec_post(exec_,
task);
745 ev_fiber_exec_on_task_init(exec_);
762 ev_fiber_exec_post_ctx(exec);
779 ev_fiber_exec_post(exec_,
task);
785 ev_fiber_exec_on_task_init(exec_);
823 ev_fiber_exec_on_task_fini(exec_);
847 ev_fiber_exec_post_ctx(exec);
851 ev_fiber_exec_from_exec(
const ev_exec_t *exec)
882 assert(exec->
thr == thr);
907 exec->inner_exec, &ev_fiber_ctx_task_func);
967 ev_fiber_exec_on_task_fini(
exec);
981 ev_fiber_ctx_task_func(
struct ev_task *task)
1006 #if !LELY_NO_THREADS
1010 #if !LELY_NO_THREADS
1014 ev_fiber_exec_post_ctx(exec);
1036 ev_fiber_return(
void)
1055 ev_fiber_ctx_destroy(ctx);
1070 #if !LELY_NO_THREADS
1094 #if !LELY_NO_THREADS
1098 #if !LELY_NO_THREADS
1103 mtx_impl->
ctx = NULL;
1104 assert(mtx_impl->
locked == 1);
1110 #if !LELY_NO_THREADS
1121 ev_fiber_cnd_wake(
struct slnode *node)
1133 #if !LELY_NO_THREADS
1143 #if !LELY_NO_THREADS
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_PERM
Operation not permitted.
@ ERRNUM_INVAL
Invalid argument.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
This header file is part of the event library; it contains the abstract task executor interface.
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...
void ev_exec_post(ev_exec_t *exec, struct ev_task *task)
Submits *task to *exec for execution.
void ev_exec_on_task_fini(ev_exec_t *exec)
Undoes the effect of a previous call to ev_exec_on_task_init().
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.
#define _Thread_local
An object whose identifier is declared with the storage-class specifier _Thread_local has thread stor...
#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 * 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...
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...
int fiber_thrd_init(int flags)
Initializes the fiber associated with the calling thread.
fiber_t * fiber_resume(fiber_t *fiber)
Equivalent to fiber_resume_with(fiber, NULL, NULL).
void fiber_thrd_fini(void)
Finalizes the fiber associated with the calling thread.
void fiber_destroy(fiber_t *fiber)
Destroys the specified fiber.
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...
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.
int ev_fiber_mtx_lock(ev_fiber_mtx_t *mtx)
Suspends the currently running fiber until it locks the fiber mutex at mtx.
void ev_fiber_thrd_fini(void)
Finalizes the calling thread and prevents further use by fiber executors.
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 ev_fiber_thrd_init(int flags, size_t stack_size, size_t max_unused)
Initializes the calling thread for use by fiber executors.
int ev_fiber_mtx_unlock(ev_fiber_mtx_t *mtx)
Unlocks the fiber mutex at mtx.
void ev_fiber_cnd_destroy(ev_fiber_cnd_t *cond)
Releases all resources used by the fiber condition variable at cond.
void ev_fiber_mtx_destroy(ev_fiber_mtx_t *mtx)
Releases any resources used by the fiber mutex at mtx.
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...
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 ev_fiber_cnd_init(ev_fiber_cnd_t *cond)
Creates a fiber condition variable.
void ev_fiber_exec_destroy(ev_exec_t *exec)
Destroys a fiber executor.
void ev_fiber_await(ev_future_t *future)
Suspends a currently running fiber until the specified future becomes ready (or is cancelled).
#define LELY_EV_FIBER_MAX_UNUSED
The maximum number of unused fibers per thread.
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...
int ev_fiber_mtx_trylock(ev_fiber_mtx_t *mtx)
Endeavors to lock the fiber mutex at mtx.
ev_exec_t * ev_fiber_exec_create(ev_exec_t *inner_exec)
Creates a fiber executor.
This header file is part of the event library; it contains the fiber executor, mutex and condition va...
@ ev_fiber_nomem
Indicates that the requested operation failed because it was unable to allocate memory.
@ ev_fiber_busy
Indicates that the requested operation failed because a resource requested by a test and return funct...
@ ev_fiber_error
Indicates that the requested operation failed.
@ ev_fiber_success
Indicates that the requested operation succeeded.
@ ev_fiber_mtx_recursive
A fiber mutex type that supports recursive locking.
void ev_future_submit(ev_future_t *future, struct ev_task *task)
Submits a task to be executed once the specified future is ready.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
This is the public header file of the utilities library.
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
void sllist_init(struct sllist *list)
Initializes 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.
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
This is the internal header file of the event library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdint....
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
The implementation of a fiber condition variable.
struct sllist queue
The queue of fibers waiting for the condition variable to be signaled.
mtx_t mtx
The mutex protecting queue.
A synchronization primitive (similar to the standard C11 condition variable) that can be used to bloc...
The context of a wait operation on a fiber condition variable.
struct slnode node
The node in the queue of fibers waiting on cond.
ev_fiber_cnd_t * cond
A pointer to the condition variable passed to ev_fiber_cnd_wait().
ev_fiber_mtx_t * mtx
A pointer to the mutex passed to ev_fiber_cnd_wait().
struct ev_task * task
A pointer to the task (in ev_fiber_ctx) used to wake up the fiber.
The context of a fiber used for executing tasks.
struct sllist queue
The queue of deferred tasks.
fiber_t * fiber
A pointer to the fiber containing this context.
struct ev_fiber_ctx * next
A pointer to the next fiber in the list of unused fibers.
struct ev_task task
The task used to resume the fiber.
struct ev_fiber_exec * exec
The executor using this fiber.
The implementation of a fiber executor.
struct ev_fiber_thrd * thr
A pointer to the ev_fiber_thrd instance for this executor.
ev_exec_t * inner_exec
A pointer to the inner executor.
struct sllist queue
The queue of tasks submitted to this executor.
int posted
A flag indicating whether task has been posted to inner_exec.
struct ev_task task
The task used to create new fibers.
const struct ev_exec_vtbl * exec_vptr
A pointer to the virtual table for the executor interface.
mtx_t mtx
The mutex protecting posted and queue.
size_t pending
The number of pending fibers available to execute a task.
The implementation of a fiber mutex.
int type
The type of mutex: ev_fiber_mtx_plain or ev_fiber_mtx_recursive.
struct sllist queue
The queue of fibers waiting to acquire the lock.
struct ev_fiber_ctx * ctx
A pointer to the fiber holding the lock.
size_t locked
The number of times the mutex has been recursively locked.
mtx_t mtx
The mutex protecting locked and queue.
A synchronization primitive (similar to the standard C11 mutex) that can be used to protect shared da...
The parameters used for creating fibers on this thread and the list of unused fibers.
size_t max_unused
The maximum number of unused fibers for this thread.
size_t num_unused
The number of unused fibers.
size_t stack_size
The size (in bytes) of the stack frame allocated for each fiber.
struct ev_fiber_ctx * curr
A pointer to the currently running fiber.
struct ev_fiber_ctx * unused
The list of unused fibers.
fiber_t * prev
A pointer to the previously running (suspended) fiber.
size_t refcnt
The number of invocations of ev_fiber_thrd_init() minus the the number of invocation of ev_fiber_thrd...
int flags
The flags used when creating each fiber.
ev_task_func_t * func
The function to be invoked when the task is run.
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
A node in a singly-linked list.
This header file is part of the event library; it contains the task declarations.
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.
#define EV_TASK_INIT(exec, func)
The static initializer for ev_task.
This header file is part of the C11 and POSIX compatibility library; it includes <threads....
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:
int mtx_lock(mtx_t *mtx)
Blocks until it locks the mutex at mtx.
@ thrd_success
Indicates that the requested operation succeeded.
@ thrd_nomem
Indicates that the requested operation failed because it was unable to allocate memory.
@ thrd_error
Indicates that the requested operation failed.
int mtx_unlock(mtx_t *mtx)
Unlocks the mutex at mtx.
pthread_mutex_t mtx_t
A complete object type that holds an identifier for a mutex.
void mtx_destroy(mtx_t *mtx)
Releases any resources used by the mutex at mtx.
@ mtx_plain
A mutex type that supports neither timeout nor test and return.