Ruby  2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
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. All rights reserved.
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 
20 struct coroutine_context
21 {
23  struct coroutine_context * from;
24 };
25 
27 
28 COROUTINE coroutine_trampoline(void * _start, void * _context);
29 
30 static inline void coroutine_initialize_main(struct coroutine_context * context) {
31  context->from = NULL;
32  getcontext(&context->state);
33 }
34 
35 static 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 
54 static 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 
65 static 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
#define COROUTINE
Definition: Context.h:14
coroutine_context::stack
void * stack
Definition: Context.h:29
assert
#define assert(x)
Definition: dlmalloc.c:1176
coroutine_context::state
jmp_buf state
Definition: Context.h:35
assert.h
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::state
ucontext_t state
Definition: Context.h:22
ucontext_t
ucontext_t
Definition: rb_mjit_min_header-2.7.2.h:2341
coroutine_context::from
struct coroutine_context * from
Definition: Context.h:37
size
int size
Definition: encoding.c:58
coroutine_context
Definition: Context.h:18
coroutine_transfer
struct coroutine_context * coroutine_transfer(struct coroutine_context *current, struct coroutine_context *target)
Definition: Context.c:115
coroutine_trampoline
COROUTINE coroutine_trampoline(void *_start, void *_context)
Definition: Context.c:16