Ruby  3.1.4p223 (2023-03-30 revision HEAD)
Context.h
1 #ifndef COROUTINE_AMD64_CONTEXT_H
2 #define COROUTINE_AMD64_CONTEXT_H 1
3 
4 /*
5  * This file is part of the "Coroutine" project and released under the MIT License.
6  *
7  * Created by Samuel Williams on 10/5/2018.
8  * Copyright, 2018, by Samuel Williams.
9 */
10 
11 #pragma once
12 
13 #include <assert.h>
14 #include <stddef.h>
15 #include <stdint.h>
16 #include <string.h>
17 
18 #define COROUTINE __attribute__((noreturn)) void
19 
20 enum {COROUTINE_REGISTERS = 6};
21 
23 {
24  void **stack_pointer;
25  void *argument;
26 };
27 
28 typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
29 
30 static inline void coroutine_initialize_main(struct coroutine_context * context) {
31  context->stack_pointer = NULL;
32 }
33 
34 static inline void coroutine_initialize(
35  struct coroutine_context *context,
36  coroutine_start start,
37  void *stack,
38  size_t size
39 ) {
40  assert(start && stack && size >= 1024);
41 
42  // Stack grows down. Force 16-byte alignment.
43  char * top = (char*)stack + size;
44  context->stack_pointer = (void**)((uintptr_t)top & ~0xF);
45 
46  *--context->stack_pointer = NULL;
47  *--context->stack_pointer = (void*)start;
48 
49  context->stack_pointer -= COROUTINE_REGISTERS;
50  memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
51 }
52 
53 struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
54 
55 static inline void coroutine_destroy(struct coroutine_context * context)
56 {
57  context->stack_pointer = NULL;
58 }
59 
60 #endif /* COROUTINE_AMD64_CONTEXT_H */