|
Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
|
Reactor overview. More...
Go to the source code of this file.
Data Structures | |
| struct | srn_reactor_io_request_t |
| A submission, one request a fiber places on its channel. More... | |
| struct | srn_reactor_io_completion_t |
| A completion, the result of one submission, echoed back on the channel. More... | |
Typedefs | |
| typedef enum srn_reactor_io_op_t | srn_reactor_io_op_t |
| The operation a submission asks the reactor to perform. | |
| typedef struct srn_reactor_io_request_t | srn_reactor_io_request_t |
| A submission, one request a fiber places on its channel. | |
| typedef struct srn_reactor_io_completion_t | srn_reactor_io_completion_t |
| A completion, the result of one submission, echoed back on the channel. | |
| typedef void(* | srn_reactor_notify_fn) (srn_scheduler_t *sched, size_t channel) |
| The interface that the scheduler supplies so the reactor can announce that a channel has completions, without the reactor knowing about workers or parking. | |
Enumerations | |
| enum | srn_reactor_io_op_t { SRN_REACTOR_IO_NOP = 0 , SRN_REACTOR_IO_SLEEP , SRN_REACTOR_IO_READ , SRN_REACTOR_IO_WRITE , SRN_REACTOR_IO_CANCEL , SRN_REACTOR_IO_ACCEPT , SRN_REACTOR_IO_CONNECT , SRN_REACTOR_IO_RECVFROM , SRN_REACTOR_IO_SENDTO , SRN_REACTOR_IO_RECVMSG , SRN_REACTOR_IO_SENDMSG , SRN_REACTOR_IO_POLL } |
| The operation a submission asks the reactor to perform. More... | |
Functions | |
| srn_reactor_t * | srn_reactor_init (srn_engine_t *engine) |
| Allocate the IO reactor from the engine. | |
| void | srn_reactor_activate (srn_reactor_t *reactor, size_t nchannels, srn_reactor_notify_fn notify) |
| Bring the reactor up, allocate nchannels channels (one per worker) and start the reactor thread. | |
| void | srn_reactor_shutdown (srn_reactor_t *reactor) |
| Tear the reactor down, stop and join the reactor thread and release its channels. | |
| bool | srn_reactor_submit (srn_reactor_t *reactor, size_t channel, const srn_reactor_io_request_t *request) |
| Place a request on channel's submission queue and rouse the reactor. | |
| size_t | srn_reactor_reap (srn_reactor_t *reactor, size_t channel, srn_reactor_io_completion_t *out, size_t max) |
| Drain up to max completions from channel's completion queue into out, returning how many were taken. | |
| void | srn_reactor_op_done (srn_reactor_t *reactor, size_t channel) |
| Drop channel's and the reactor's in-flight counts by one. | |
| bool | srn_reactor_idle (srn_reactor_t *reactor) |
| Whether the reactor has no operations in flight. | |
| void | srn_reactor_consume (srn_reactor_t *reactor, size_t channel) |
| Drain and act on channel's completions. | |
| bool | srn_reactor_channel_has_completions (srn_reactor_t *reactor, size_t channel) |
| Whether channel's completion queue has unconsumed completions. | |
Reactor overview.
The reactor is in charge of all the IO in the runtime.
It is completion based and modeled after io_uring; a submission describes a whole request, and a completion reports its result. The reactor utilizes different backends for different platforms. A readiness backend such as epoll performs the transfer itself when the descriptor signals readiness and posts the finished result, so the contract is the common subset every platform can honour.
A worker and the reactor talk through a channel: a channel is a pair of submission queue (SQ) and a completion queue (CQ), a SQ carrying requests toward the reactor and a CQ carrying results back. There is one channel per worker. The reactor owns every channel; a worker holds only the channel id and never touches a raw queue.
Each request carries fiber_data, an opaque token the reactor round-trips untouched: it rides in on the submission and comes back out on the completion, and is how a finished result finds the fiber that was waiting.
Definition in file reactor.h.
| typedef struct srn_reactor_io_completion_t srn_reactor_io_completion_t |
A completion, the result of one submission, echoed back on the channel.
It is a fallible value (see errors.h). maybe_error is null on success and points at the failure otherwise, so result/addrlen are meaningful only when there is no error. The backend sets maybe_error from a static IO error to avoid unnecessary memory allocation.
| typedef enum srn_reactor_io_op_t srn_reactor_io_op_t |
The operation a submission asks the reactor to perform.
| typedef struct srn_reactor_io_request_t srn_reactor_io_request_t |
A submission, one request a fiber places on its channel.
The reactor copies it into the submission queue, so the struct itself need not outlive the call; a buffer it points at (buf) must stay valid until the operation completes.
| typedef void(* srn_reactor_notify_fn) (srn_scheduler_t *sched, size_t channel) |
The interface that the scheduler supplies so the reactor can announce that a channel has completions, without the reactor knowing about workers or parking.
The reactor calls it after placing completions on channel; the scheduler wakes that channel's worker if it is parked.
| enum srn_reactor_io_op_t |
The operation a submission asks the reactor to perform.
Definition at line 60 of file reactor.h.
| void srn_reactor_activate | ( | srn_reactor_t * | reactor, |
| size_t | nchannels, | ||
| srn_reactor_notify_fn | notify ) |
Bring the reactor up, allocate nchannels channels (one per worker) and start the reactor thread.
notify is called with the scheduler and the channel id whenever a channel gains completions.
Definition at line 390 of file reactor.c.
|
nodiscard |
Whether channel's completion queue has unconsumed completions.
The worker checks this under the scheduler lock before parking, so a completion landing just before it sleeps is not missed.
Definition at line 237 of file reactor.c.
| void srn_reactor_consume | ( | srn_reactor_t * | reactor, |
| size_t | channel ) |
Drain and act on channel's completions.
Called by the worker that owns the channel, from its loop. Per completion it sets the waiter's result, readies the fiber, and drops the in-flight count.
Drain and act on channel's completions.
Drains this worker's channel and, for each completion, copies the outcome into the waiting fiber's waiter, readies it, and only then drops the inflight count, so quiescence never fires in the gap between a result being produced and its fiber being made runnable. srn_fiber_ready here pushes onto the running worker's own deque, keeping the woken fiber local.
Definition at line 121 of file io.c.
|
nodiscard |
Whether the reactor has no operations in flight.
The scheduler folds this into quiescence, a pool with parked workers and an empty run queue is only truly done when the reactor is idle too.
Definition at line 169 of file reactor.c.
|
nodiscard |
Allocate the IO reactor from the engine.
Definition at line 34 of file reactor.c.
| void srn_reactor_op_done | ( | srn_reactor_t * | reactor, |
| size_t | channel ) |
Drop channel's and the reactor's in-flight counts by one.
The consumer of a completion calls this after it has finished acting on it (for fibers, after the waiting fiber is readied), so that "in flight" reaches zero only once every result has been both produced and handled. Dropping the channel count is also what re-opens the channel's admission window (see srn_reactor_submit).
Definition at line 162 of file reactor.c.
| size_t srn_reactor_reap | ( | srn_reactor_t * | reactor, |
| size_t | channel, | ||
| srn_reactor_io_completion_t * | out, | ||
| size_t | max ) |
Drain up to max completions from channel's completion queue into out, returning how many were taken.
Definition at line 220 of file reactor.c.
| void srn_reactor_shutdown | ( | srn_reactor_t * | reactor | ) |
Tear the reactor down, stop and join the reactor thread and release its channels.
Definition at line 66 of file reactor.c.
|
nodiscard |
Place a request on channel's submission queue and rouse the reactor.
Returns false without submitting when the channel already has a full ring's worth of operations in flight. The condition is transient, it clears as the channel's worker consumes completions, so the caller can fail the operation back with CHANNEL_BUSY and let the fiber retry.
Definition at line 174 of file reactor.c.