Ruby: coroutine/copy/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 27/6/2019.
5 * Copyright, 2019, by Samuel Williams.
6*/
7
8#pragma once
9
10#include <assert.h>
11#include <stddef.h>
12#include <setjmp.h>
13#include <string.h>
14#include <stdlib.h>
15
16/* OpenBSD supports alloca, but does not include alloca.h */
17#ifndef __OpenBSD__
18#include <alloca.h>
19#endif
20
21#define COROUTINE __attribute__((noreturn)) void
22
23#if INTPTR_MAX <= INT32_MAX
24#define COROUTINE_LIMITED_ADDRESS_SPACE
25#endif
26
27// This stack copying implementation which uses a private stack for each coroutine, including the main one.
28#define COROUTINE_PRIVATE_STACK
29
30struct coroutine_context
31{
32 // Private stack:
33 void *stack;
34 size_t size, used;
35
36 // The top (or bottom) of the currently executing stack:
37 void *base;
38
39 jmp_buf state;
40
41 struct coroutine_context *from;
42};
43
44 typedef COROUTINE(*coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
45
46int coroutine_save_stack(struct coroutine_context * context);
47 COROUTINE coroutine_restore_stack(struct coroutine_context *context);
48
49// @param stack The private stack area memory allocation (pointer to lowest address).
50// @param size The size of the private stack area.
51// @param base A stack pointer to the base of the main stack. On x86 hardware, this is the upper extent of the region that will be copied to the private stack.
52static inline void coroutine_initialize_main(struct coroutine_context *context, void *stack, size_t size, void *base) {
53 assert(stack);
54 assert(size >= 1024);
55
56 context->stack = stack;
57 context->size = size;
58 context->used = 0;
59
60 assert(base);
61 context->base = base;
62
63 context->from = NULL;
64}
65
66// @param start The start function to invoke.
67static inline void coroutine_initialize(
68 struct coroutine_context *context,
69 coroutine_start start,
70 void *stack,
71 size_t size,
72 void *base
73) {
74 assert(start);
75
76 coroutine_initialize_main(context, stack, size, base);
77
78 if (coroutine_save_stack(context)) {
79 start(context->from, context);
80 }
81}
82
83 struct coroutine_context *coroutine_transfer(struct coroutine_context *current, register struct coroutine_context *target);
84
85static inline void coroutine_destroy(struct coroutine_context *context)
86{
87 context->stack = NULL;
88 context->size = 0;
89 context->from = NULL;
90}
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
coroutine_save_stack
int coroutine_save_stack(struct coroutine_context *context)
Definition: Context.c:78
coroutine_restore_stack
COROUTINE coroutine_restore_stack(struct coroutine_context *context)
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::used
size_t used
Definition: Context.h:34
coroutine_context::stack
void * stack
Definition: Context.h:33
coroutine_context::state
jmp_buf state
Definition: Context.h:39
coroutine_context::base
void * base
Definition: Context.h:37
coroutine_context::size
size_t size
Definition: Context.h:34