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
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
42};
43
45
46int coroutine_save_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) {
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
83struct 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(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self)
Definition: Context.h:24
#define COROUTINE
Definition: Context.h:15
struct coroutine_context * coroutine_transfer(struct coroutine_context *current, struct coroutine_context *target)
Definition: Context.c:136
int coroutine_save_stack(struct coroutine_context *context)
Definition: Context.c:78
COROUTINE coroutine_restore_stack(struct coroutine_context *context)
#define assert(x)
Definition: dlmalloc.c:1176
voidpf void uLong size
Definition: ioapi.h:138
#define NULL
Definition: regenc.h:69
struct coroutine_context * from
Definition: Context.h:41
void * stack
Definition: Context.h:33
jmp_buf state
Definition: Context.h:39