ruby/coroutine/copy/Context.h
nagachika f469298339 merge revision(s) f96216df8dfd2d1e206150572912289f4dda7386,0091fac1d8de07e86fef8315ba77609bed9dd7f5,04c704c5c967ea9bded6bf645439fe59c7d9f7d6,23655e6de5ee989feb8c65c7061fe9a71579dc54,7cb8904a12c850ee30dcd67817fa2f9dc3fee813,41168f69fbeb32cfc88210911d62e419b8116589,87f6154bb4c67ca77ee353bb1fe25a922036c0e5: [Backport #17202]
Remove "All Rights Reserved." from Copyright statement.

	Patch assembly so that it aligns properly

	Removed trailing spaces [ci skip]

	Fix build error on Apple silicon macOS

	This patch will fix following build error on macOS 11.0 + Xcode 12 beta.

	```
	$ ./configure
	$ make V=1
		BASERUBY = /Users/watson/.rbenv/shims/ruby --disable=gems
		CC = clang -fdeclspec
		LD = ld
		LDSHARED = clang -fdeclspec -dynamiclib
		CFLAGS = -O3 -ggdb3 -Wall -Wextra -Werror=deprecated-declarations -Werror=division-by-zero -Werror=implicit-function-declaration -Werror=implicit-int -Werror=misleading-indentation -Werror=pointer-arith -Werror=shorten-64-to-32 -Werror=write-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Werror=extra-tokens -std=gnu99  -pipe
		XCFLAGS = -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fno-strict-overflow -DRUBY_DEVEL=1 -fvisibility=hidden -DRUBY_EXPORT -fPIE -DCANONICALIZATION_FOR_MATHN -I. -I.ext/include/arm64-darwin20 -I./include -I. -I./enc/unicode/12.1.0
		CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT
		DLDFLAGS = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -fstack-protector-strong -Wl,-pie -framework Security -framework Foundation
		SOLIBS = -lpthread -ldl -lobjc
		LANG = ja_JP.UTF-8
		LC_ALL =
		LC_CTYPE =
		MFLAGS =
	Apple clang version 12.0.0 (clang-1200.0.22.19)
	Target: arm64-apple-darwin20.0.0
	Thread model: posix
	InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
	clang -fdeclspec -O3 -ggdb3 -Wall -Wextra -Werror=deprecated-declarations -Werror=division-by-zero -Werror=implicit-function-declaration -Werror=implicit-int -Werror=misleading-indentation -Werror=pointer-arith -Werror=shorten-64-to-32 -Werror=write-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Werror=extra-tokens -std=gnu99  -pipe  -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fno-strict-overflow -DRUBY_DEVEL=1 -fvisibility=hidden -DRUBY_EXPORT -fPIE -DCANONICALIZATION_FOR_MATHN -I. -I.ext/include/arm64-darwin20 -I./include -I. -I./enc/unicode/12.1.0 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT    -o cont.o -c cont.c
	In file included from cont.c:19:
	./coroutine/ucontext/Context.h:32:5: error: 'getcontext' is deprecated: first deprecated in macOS 10.6 [-Werror,-Wdeprecated-declarations]
	    getcontext(&context->state);
	    ^
	/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ucontext.h:37:6: note: 'getcontext' has been
	      explicitly marked deprecated here
	int  getcontext(ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
	     ^
	In file included from cont.c:19:
	./coroutine/ucontext/Context.h:51:5: error: 'makecontext' is deprecated: first deprecated in macOS 10.6 [-Werror,-Wdeprecated-declarations]
	    makecontext(&context->state, (void(*)(void))coroutine_trampoline, 2, (void*)start, (void*)context);
	    ^
	/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ucontext.h:38:6: note: 'makecontext' has been
	      explicitly marked deprecated here
	void makecontext(ucontext_t *, void (*)(), int, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0) __WATCHOS_PROHI...
	     ^
	In file included from cont.c:19:
	./coroutine/ucontext/Context.h:59:5: error: 'swapcontext' is deprecated: first deprecated in macOS 10.6 [-Werror,-Wdeprecated-declarations]
	    swapcontext(&current->state, &target->state);
	    ^
	/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ucontext.h:40:6: note: 'swapcontext' has been
	      explicitly marked deprecated here
	int  swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_...
	     ^
	3 errors generated.
	make: *** [cont.o] Error 1
	```

	Extract correct processor name for ARM64 Macs

	Prefix export symbol prefix to coroutine_transfer

	Revert "Revert "[ruby/fiddle] Use ffi_closure_free by default.
	 (#20)""

	This reverts commit efd641ffab.

	This changeset seems to be needed to suppress a warning on Ubuntu 20.04
	20200304T033004Z.log.html.gz
	```
	closure.c:264:5: warning: 'ffi_prep_closure' is deprecated: use ffi_prep_closure_loc instead [-Wdeprecated-declarations]
	  264 |     result = ffi_prep_closure(pcl, cif, callback, (void *)self);
	      |     ^~~~~~
	```

	I guess there was a reason why the commit was reverted (maybe some CIs
	failed?), so try it again.
2020-09-30 19:24:17 +09:00

86 lines
2.3 KiB
C

/*
* This file is part of the "Coroutine" project and released under the MIT License.
*
* Created by Samuel Williams on 27/6/2019.
* Copyright, 2019, by Samuel Williams.
*/
#pragma once
#include <assert.h>
#include <stddef.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
#include <alloca.h>
#define COROUTINE __attribute__((noreturn)) void
#if INTPTR_MAX <= INT32_MAX
#define COROUTINE_LIMITED_ADDRESS_SPACE
#endif
// This stack copying implementation which uses a private stack for each coroutine, including the main one.
#define COROUTINE_PRIVATE_STACK
struct coroutine_context
{
// Private stack:
void *stack;
size_t size, used;
// The top (or bottom) of the currently executing stack:
void *base;
jmp_buf state;
struct coroutine_context *from;
};
typedef COROUTINE(*coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
int coroutine_save_stack(struct coroutine_context * context);
COROUTINE coroutine_restore_stack(struct coroutine_context *context);
// @param stack The private stack area memory allocation (pointer to lowest address).
// @param size The size of the private stack area.
// @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.
static inline void coroutine_initialize_main(struct coroutine_context *context, void *stack, size_t size, void *base) {
assert(stack);
assert(size >= 1024);
context->stack = stack;
context->size = size;
context->used = 0;
assert(base);
context->base = base;
context->from = NULL;
}
// @param start The start function to invoke.
static inline void coroutine_initialize(
struct coroutine_context *context,
coroutine_start start,
void *stack,
size_t size,
void *base
) {
assert(start);
coroutine_initialize_main(context, stack, size, base);
if (coroutine_save_stack(context)) {
start(context->from, context);
}
}
struct coroutine_context *coroutine_transfer(struct coroutine_context *current, register struct coroutine_context *target);
static inline void coroutine_destroy(struct coroutine_context *context)
{
context->stack = NULL;
context->size = 0;
context->from = NULL;
}