aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/runtime.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-05-31 17:56:36 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-05-31 17:56:36 +0000
commit4d12cf3cc3143843225ecdb0e5048fc7c37b1574 (patch)
tree30d27f1ac980671a5b890c86e562a746f4f4b54e /libgo/runtime/runtime.h
parent34a13a521e3fc6f46fcaf2f158d20e66874e99fd (diff)
downloadgcc-4d12cf3cc3143843225ecdb0e5048fc7c37b1574.zip
gcc-4d12cf3cc3143843225ecdb0e5048fc7c37b1574.tar.gz
gcc-4d12cf3cc3143843225ecdb0e5048fc7c37b1574.tar.bz2
runtime: implement cheaper context switch on Linux/AMD64
Currently, goroutine switches are implemented with libc getcontext/setcontext functions, which saves/restores the machine register states and also the signal context. This does more than what we need, and performs an expensive syscall. This CL implements a simplified version of getcontext/setcontext, in assembly, that only saves/restores the necessary part, i.e. the callee-save registers, and the PC, SP. A simplified version of makecontext, written in C, is also added. Currently this is only implemented on Linux/AMD64. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/178298 From-SVN: r271818
Diffstat (limited to 'libgo/runtime/runtime.h')
-rw-r--r--libgo/runtime/runtime.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index 71c1a3e..a421dea 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -510,3 +510,20 @@ bool probestackmaps(void)
// older versions of glibc when a SIGPROF signal arrives while
// collecting a backtrace.
extern uint32 __go_runtime_in_callers;
+
+// Cheaper context switch functions. Currently only defined on
+// Linux/AMD64.
+#if defined(__x86_64__) && defined(__linux__) && !defined(__CET__)
+typedef struct {
+ uint64 regs[8];
+} __go_context_t;
+int __go_getcontext(__go_context_t*);
+int __go_setcontext(__go_context_t*);
+void __go_makecontext(__go_context_t*, void (*)(), void*, size_t);
+#else
+#define __go_context_t ucontext_t
+#define __go_getcontext(c) getcontext(c)
+#define __go_setcontext(c) setcontext(c)
+#define __go_makecontext(c, fn, sp, size) \
+ ((c)->uc_stack.ss_sp = sp, (c)->uc_stack.ss_size = size, makecontext(c, fn, 0))
+#endif