1#ifndef COROUTINE_AMD64_CONTEXT_H
2#define COROUTINE_AMD64_CONTEXT_H 1
18#define COROUTINE __attribute__((noreturn)) void
20enum {COROUTINE_REGISTERS = 6};
22#if defined(__SANITIZE_ADDRESS__)
23 #define COROUTINE_SANITIZE_ADDRESS
24#elif defined(__has_feature)
25 #if __has_feature(address_sanitizer)
26 #define COROUTINE_SANITIZE_ADDRESS
30#if defined(COROUTINE_SANITIZE_ADDRESS)
31#include <sanitizer/common_interface_defs.h>
32#include <sanitizer/asan_interface.h>
35#if defined(__SANITIZE_THREAD__)
36 #define COROUTINE_SANITIZE_THREAD
37#elif defined(__has_feature)
38 #if __has_feature(thread_sanitizer)
39 #define COROUTINE_SANITIZE_THREAD
43#if defined(COROUTINE_SANITIZE_THREAD)
48#include <sanitizer/tsan_interface.h>
56#if defined(COROUTINE_SANITIZE_ADDRESS)
62#if defined(COROUTINE_SANITIZE_THREAD)
74 context->stack_pointer = NULL;
76#if defined(COROUTINE_SANITIZE_THREAD)
78 context->tsan_fiber = __tsan_get_current_fiber();
79 context->tsan_fiber_owned = 0;
83static inline void coroutine_initialize(
85 coroutine_start start,
89 assert(start && stack && size >= 1024);
91#if defined(COROUTINE_SANITIZE_ADDRESS)
92 context->fake_stack = NULL;
93 context->stack_base = stack;
94 context->stack_size = size;
97#if defined(COROUTINE_SANITIZE_THREAD)
98 context->tsan_fiber = __tsan_create_fiber(0);
99 context->tsan_fiber_owned = 1;
103 char * top = (
char*)stack + size;
104 context->stack_pointer = (
void**)((uintptr_t)top & ~0xF);
106 *--context->stack_pointer = NULL;
107 *--context->stack_pointer = (
void*)(uintptr_t)start;
109 context->stack_pointer -= COROUTINE_REGISTERS;
110 memset(context->stack_pointer, 0,
sizeof(
void*) * COROUTINE_REGISTERS);
117 context->stack_pointer = NULL;
119#if defined(COROUTINE_SANITIZE_THREAD)
123 if (context->tsan_fiber && context->tsan_fiber_owned) {
124 __tsan_destroy_fiber(context->tsan_fiber);
125 context->tsan_fiber = NULL;
126 context->tsan_fiber_owned = 0;