Serene Runtime 1.0.0
C runtime for the Serene programming language
Loading...
Searching...
No Matches
05_parallel.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 05 -- many fibers across many worker threads (M:N).
20//
21// The same scheduler runs on more than one OS thread by passing a worker count
22// greater than one to `srn_sched_run`. The fibers are distributed across the
23// workers, which steal work from one another to stay busy, so the fibers run in
24// parallel rather than merely interleaved. The run returns once every worker is
25// idle on an empty queue.
26//
27// Because the fibers run on different threads at the same time, any state they
28// share has to be synchronised. This example keeps it simple with a single
29// atomic counter that every fiber increments once. After the run the total
30// equals the fiber count, with no lost updates.
31
32#include <stdatomic.h>
33#include <stdio.h>
34
35#include <serene/runtime.h>
36
37static int ok;
38
39#define FIBER_COUNT 1000
40#define WORKER_COUNT 4
41
42static atomic_int total;
43
45 (void)ctx;
46 (void)arg;
47 // The one piece of shared state. An atomic add is safe from any worker.
48 atomic_fetch_add(&total, 1);
49 return &ok;
50}
51
52int main(void) {
53 srn_mm_t *mm = srn_mm_init();
54 srn_engine_t *engine = srn_engine_make(mm);
55 srn_context_t *ctx = srn_context_make(engine);
56 srn_scheduler_t *sched = engine->scheduler;
57
58 atomic_store(&total, 0);
59 for (int i = 0; i < FIBER_COUNT; i++) {
60 (void)srn_fiber_make(ctx, sched, increment, nullptr, 0);
61 }
62
63 printf("running %d fibers across %d workers\n", FIBER_COUNT, WORKER_COUNT);
65
66 int counted = atomic_load(&total);
67 printf("counted %d (expected %d): %s\n", counted, FIBER_COUNT,
68 counted == FIBER_COUNT ? "all fibers ran" : "lost an update");
69
71 srn_engine_shutdown(engine);
73 return 0;
74}
static int ok
Definition 01_hello.c:36
#define FIBER_COUNT
Definition 05_parallel.c:39
static srn_fiber_result_t increment(srn_context_t *ctx, void *arg)
Definition 05_parallel.c:44
int main(void)
Definition 05_parallel.c:52
static atomic_int total
Definition 05_parallel.c:42
#define WORKER_COUNT
Definition 05_parallel.c:40
srn_context_t * srn_context_make(srn_engine_t *engine)
Make an empty context, by allocating a new memory block.
Definition context.c:38
int srn_context_release(srn_context_t *ctx)
Definition context.c:63
srn_mm_t * srn_mm_init()
Initialize the memory manager, this function will panic on error.
Definition default.c:294
void srn_mm_shutdown(srn_mm_t *mm)
Shut down the memory manager and release the resources.
Definition default.c:325
srn_engine_t * srn_engine_make(srn_mm_t *mm)
Definition engine.c:92
void srn_engine_shutdown(srn_engine_t *engine)
Definition engine.c:123
srn_fiber_t * srn_fiber_make(srn_context_t *ctx, srn_scheduler_t *sched, srn_fiber_entry_t entry, void *arg, size_t stack_size)
Create a fiber that will run entry(ctx, arg).
Definition fiber.c:169
void * srn_fiber_result_t
Definition fiber.h:117
void srn_sched_run(srn_scheduler_t *sched, int nworkers)
Run the scheduler with nworkers os threads draining it, returning once the pool goes quiescent (every...
Definition scheduler.c:784
Engine is a structure to own the long living and main pieces of the compiler.
Definition engine.h:49
srn_scheduler_t * scheduler
The fiber scheduler, set by srn_sched_init.
Definition engine.h:67
Main memory manager structure that will own all the allocated blocks and data.
Definition interface.h:112