Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

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. All rights reserved.
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 #include <alloca.h>
16
17 #define COROUTINE __attribute__((noreturn)) void
18
19 #if INTPTR_MAX <= INT32_MAX
20 #define COROUTINE_LIMITED_ADDRESS_SPACE
21 #endif
22
23 // This stack copying implementation which uses a private stack for each coroutine, including the main one.
24 #define COROUTINE_PRIVATE_STACK
25
26 struct coroutine_context
27 {
28 // Private stack:
29 void *stack;
30 size_t size, used;
31
32 // The top (or bottom) of the currently executing stack:
33 void *base;
34
35 jmp_buf state;
36
37 struct coroutine_context *from;
38 };
39
40 typedef COROUTINE(*coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
41
42 int coroutine_save_stack(struct coroutine_context * context);
43 COROUTINE coroutine_restore_stack(struct coroutine_context *context);
44
45 // @param stack The private stack area memory allocation (pointer to lowest address).
46 // @param size The size of the private stack area.
47 // @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.
48 static inline void coroutine_initialize_main(struct coroutine_context *context, void *stack, size_t size, void *base) {
49 assert(stack);
50 assert(size >= 1024);
51
52 context->stack = stack;
53 context->size = size;
54 context->used = 0;
55
56 assert(base);
57 context->base = base;
58
59 context->from = NULL;
60 }
61
62 // @param start The start function to invoke.
63 static inline void coroutine_initialize(
64 struct coroutine_context *context,
65 coroutine_start start,
66 void *stack,
67 size_t size,
68 void *base
69 ) {
70 assert(start);
71
72 coroutine_initialize_main(context, stack, size, base);
73
74 if (coroutine_save_stack(context)) {
75 start(context->from, context);
76 }
77 }
78
79 struct coroutine_context *coroutine_transfer(struct coroutine_context *current, register struct coroutine_context *target);
80
81 static inline void coroutine_destroy(struct coroutine_context *context)
82 {
83 context->stack = NULL;
84 context->size = 0;
85 context->from = NULL;
86 }
coroutine_context::stack
void * stack
Definition: Context.h:29
assert
#define assert(x)
Definition: dlmalloc.c:1176
coroutine_context::used
size_t used
Definition: Context.h:30
COROUTINE
#define COROUTINE
Definition: Context.h:17
coroutine_context::state
jmp_buf state
Definition: Context.h:35
assert.h
coroutine_context::size
size_t size
Definition: Context.h:30
NULL
#define NULL
Definition: _sdbm.c:101
coroutine_start
COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self)
Definition: Context.h:22
coroutine_context::from
struct coroutine_context * from
Definition: Context.h:37
size
int size
Definition: encoding.c:58
coroutine_context
Definition: Context.h:17
coroutine_transfer
struct coroutine_context * coroutine_transfer(struct coroutine_context *current, struct coroutine_context *target)
Definition: Context.c:115
jmp_buf
long jmp_buf[32]
Definition: rb_mjit_min_header-2.7.0.h:9390
coroutine_restore_stack
COROUTINE coroutine_restore_stack(struct coroutine_context *context)
coroutine_save_stack
int coroutine_save_stack(struct coroutine_context *context)
Definition: Context.c:38
coroutine_context::base
void * base
Definition: Context.h:33