Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
02_yield.c
Go to the documentation of this file.
1/* -*- C -*-
2 * Serene programming language
3 * Copyright (C) 2019-2026 Sameer Rahmani <[email protected]>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19// Example 02 -- cooperative yielding.
20//
21// Fibers are cooperative. A fiber keeps the thread until it gives it up, and
22// `srn_fiber_yield` is the polite way to do that: the running fiber goes to the
23// back of the ready queue and the next ready fiber runs. There is no
24// preemption, so a fiber that never yields and never finishes would hold the
25// worker forever.
26//
27// Three fibers each count to three, yielding after every step. Running on a
28// single worker, they take turns. The printed order makes the interleaving
29// visible.
30
31#include <stdio.h>
32
33#include <serene/runtime.h>
34
35static srn_fiber_result_t counter(srn_context_t *ctx, void *arg) {
36 (void)ctx;
37 // The argument carries the fiber's label, passed as a small integer.
38 long id = (long)(intptr_t)arg;
39 for (int step = 1; step <= 3; step++) {
40 printf("fiber %ld: step %d\n", id, step);
41 // Hand the worker to the next ready fiber. This fiber resumes here on its
42 // next turn.
44 }
45 printf("fiber %ld: done\n", id);
46 return nullptr;
47}
48
49int main(void) {
50 SERENE_RUNTIME_INIT_WITH_SCHED(engine, sched, nullptr);
51 srn_context_t *ctx = srn_context_make(engine);
52
53 for (long id = 1; id <= 3; id++) {
54 (void)srn_fiber_spawn(ctx, counter, (void *)(intptr_t)id);
55 }
56
57 // One worker, so the turn taking is deterministic and the output interleaves
58 // the three fibers a step at a time.
59 srn_sched_run(sched, 1);
60
63 return 0;
64}
static srn_fiber_result_t counter(srn_context_t *ctx, void *arg)
Definition 02_yield.c:35
int main(void)
Definition 02_yield.c:49
srn_context_t * srn_context_make(srn_engine_t *engine)
Make an empty context, by allocating a new memory block.
Definition context.c:39
int srn_context_release(srn_context_t *ctx)
Definition context.c:64
srn_fiber_t * srn_fiber_spawn(srn_context_t *ctx, srn_fiber_entry_t entry, void *arg)
Make and schedule a fiber with every default, the engine's scheduler, the configured stack size,...
Definition fiber.c:247
void * srn_fiber_result_t
What a fiber's entry produces, type-erased.
Definition fiber.h:157
#define SERENE_RUNTIME_SHUTDOWN(engine)
Tear down what SERENE_RUNTIME_INIT brought up, in reverse order, the engine (reactor,...
Definition runtime.h:58
#define SERENE_RUNTIME_INIT_WITH_SCHED(engine, sched, config)
SERENE_RUNTIME_INIT plus a sched variable bound to the engine's scheduler, which every run and fiber ...
Definition runtime.h:46
void srn_sched_run(srn_scheduler_t *sched, size_t nworkers)
Run the scheduler with nworkers os threads draining it, returning once the pool goes quiescent (every...
Definition scheduler.c:843
void srn_fiber_yield(void)
Yield cooperatively, re-enqueue the running fiber and run the next ready one.
Definition scheduler.c:1000