38 #ifndef LELY_EV_FIBER_MAX_UNUSED
40 #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);
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_)
712 ev_fiber_exec_post(exec_,
task);
736 ev_fiber_exec_on_task_init(exec_);
753 ev_fiber_exec_post_ctx(exec);
770 ev_fiber_exec_post(exec_,
task);
776 ev_fiber_exec_on_task_init(exec_);
814 ev_fiber_exec_on_task_fini(exec_);
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)
1001 #if !LELY_NO_THREADS
1005 ev_fiber_exec_post_ctx(exec);
1027 ev_fiber_return(
void)
1046 ev_fiber_ctx_destroy(ctx);
1061 #if !LELY_NO_THREADS
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
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...
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.
#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...
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.