Ruby: coroutine/ucontext/Context.h Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

Context.h
Go to the documentation of this file.
1/*
2 * This file is part of the "Coroutine" project and released under the MIT License.
3 *
4 * Created by Samuel Williams on 24/6/2019.
5 * Copyright, 2019, by Samuel Williams.
6*/
7
8#pragma once
9
10#include <assert.h>
11#include <stddef.h>
12#include <ucontext.h>
13
14#define COROUTINE __attribute__((noreturn)) void
15
16#if INTPTR_MAX <= INT32_MAX
17#define COROUTINE_LIMITED_ADDRESS_SPACE
18#endif
19
20struct coroutine_context
21{
22 ucontext_t state;
23 struct coroutine_context * from;
24};
25
26 typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
27
28 COROUTINE coroutine_trampoline(void * _start, void * _context);
29
30static inline void coroutine_initialize_main(struct coroutine_context * context) {
31 context->from = NULL;
32 getcontext(&context->state);
33}
34
35static inline void coroutine_initialize(
36 struct coroutine_context *context,
37 coroutine_start start,
38 void *stack,
39 size_t size
40) {
41 assert(start && stack && size >= 1024);
42
43 coroutine_initialize_main(context);
44
45 context->state.uc_stack.ss_size = size;
46 // Despite what it's called, this is not actually a stack pointer. It points to the address of the stack allocation (the lowest address).
47 context->state.uc_stack.ss_sp = (char*)stack;
48 context->state.uc_stack.ss_flags = 0;
49 context->state.uc_link = NULL;
50
51 makecontext(&context->state, (void(*)(void))coroutine_trampoline, 2, (void*)start, (void*)context);
52}
53
54static inline struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target)
55{
56 struct coroutine_context * previous = target->from;
57
58 target->from = current;
59 swapcontext(&current->state, &target->state);
60 target->from = previous;
61
62 return target;
63}
64
65static inline void coroutine_destroy(struct coroutine_context * context)
66{
67 context->state.uc_stack.ss_sp = NULL;
68 context->state.uc_stack.ss_size = 0;
69 context->from = NULL;
70}
coroutine_start
COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self)
Definition: Context.h:24
COROUTINE
#define COROUTINE
Definition: Context.h:15
coroutine_transfer
struct coroutine_context * coroutine_transfer(struct coroutine_context *current, struct coroutine_context *target)
Definition: Context.c:136
assert.h
assert
#define assert(x)
Definition: dlmalloc.c:1176
size
voidpf void uLong size
Definition: ioapi.h:138
NULL
#define NULL
Definition: regenc.h:69
coroutine_context
Definition: Context.h:20
coroutine_context::from
struct coroutine_context * from
Definition: Context.h:41
coroutine_context::stack
void * stack
Definition: Context.h:33
coroutine_context::state
jmp_buf state
Definition: Context.h:39
coroutine_context::state
ucontext_t state
Definition: Context.h:22
coroutine_trampoline
void coroutine_trampoline()