runtime/cgo: merge bodies of cgo_sys_thread_start on windows
The bodies of cgo_sys_thread_start (and x_cgo_sys_thread_create) are
nearly identical on all of the windows ports.
Create a single _cgo_beginthread implementation that contains the body
and is used on all ports. This will reduce churn in an upcoming CL to
add retry logic.
We could theoretically have a single implementation of
_cgo_sys_thread_start shared by all ports, but I keep them separate for
ease of searching. Right now every single port implements this function
in their gcc_GOOS_GOARCH.c file, so it is nice to keep this symmetry.
_cgo_dummy_export must move out of libcgo_windows.h because it is a
definition and the inclusion of libcgo_windows.h in multiple files
creates duplicate definitions.
For #52572.
Change-Id: I9fa22009389349c754210274c7db2631b061f9c7
Reviewed-on: https://go-review.googlesource.com/c/go/+/410354
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/src/runtime/cgo/gcc_libinit_windows.c b/src/runtime/cgo/gcc_libinit_windows.c
index ad50386..a9b94c3 100644
--- a/src/runtime/cgo/gcc_libinit_windows.c
+++ b/src/runtime/cgo/gcc_libinit_windows.c
@@ -13,6 +13,16 @@
#include <errno.h>
#include "libcgo.h"
+#include "libcgo_windows.h"
+
+// Ensure there's one symbol marked __declspec(dllexport).
+// If there are no exported symbols, the unfortunate behavior of
+// the binutils linker is to also strip the relocations table,
+// resulting in non-PIE binary. The other option is the
+// --export-all-symbols flag, but we don't need to export all symbols
+// and this may overflow the export table (#40795).
+// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
+__declspec(dllexport) int _cgo_dummy_export;
static volatile LONG runtime_init_once_gate = 0;
static volatile LONG runtime_init_once_done = 0;
@@ -53,13 +63,7 @@
void
x_cgo_sys_thread_create(void (*func)(void*), void* arg) {
- uintptr_t thandle;
-
- thandle = _beginthread(func, 0, arg);
- if(thandle == -1) {
- fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
- abort();
- }
+ _cgo_beginthread(func, arg);
}
int
@@ -123,3 +127,13 @@
LeaveCriticalSection(&runtime_init_cs);
return ret;
}
+
+void _cgo_beginthread(void (*func)(void*), void* arg) {
+ uintptr_t thandle;
+
+ thandle = _beginthread(func, 0, arg);
+ if (thandle == -1) {
+ fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
+ abort();
+ }
+}
diff --git a/src/runtime/cgo/gcc_windows_386.c b/src/runtime/cgo/gcc_windows_386.c
index 60cb011..56fbaac 100644
--- a/src/runtime/cgo/gcc_windows_386.c
+++ b/src/runtime/cgo/gcc_windows_386.c
@@ -22,13 +22,7 @@
void
_cgo_sys_thread_start(ThreadStart *ts)
{
- uintptr_t thandle;
-
- thandle = _beginthread(threadentry, 0, ts);
- if(thandle == -1) {
- fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
- abort();
- }
+ _cgo_beginthread(threadentry, ts);
}
static void
@@ -50,6 +44,6 @@
"movl %1, 0(%%eax)\n" // MOVL g, 0(FS)
:: "r"(ts.tls), "r"(ts.g) : "%eax"
);
-
+
crosscall_386(ts.fn);
}
diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c
index 9df9b9b..996947e 100644
--- a/src/runtime/cgo/gcc_windows_amd64.c
+++ b/src/runtime/cgo/gcc_windows_amd64.c
@@ -24,13 +24,7 @@
void
_cgo_sys_thread_start(ThreadStart *ts)
{
- uintptr_t thandle;
-
- thandle = _beginthread(threadentry, 0, ts);
- if(thandle == -1) {
- fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
- abort();
- }
+ _cgo_beginthread(threadentry, ts);
}
static void
diff --git a/src/runtime/cgo/gcc_windows_arm64.c b/src/runtime/cgo/gcc_windows_arm64.c
index 61ef094..8f113cc 100644
--- a/src/runtime/cgo/gcc_windows_arm64.c
+++ b/src/runtime/cgo/gcc_windows_arm64.c
@@ -23,13 +23,7 @@
void
_cgo_sys_thread_start(ThreadStart *ts)
{
- uintptr_t thandle;
-
- thandle = _beginthread(threadentry, 0, ts);
- if(thandle == -1) {
- fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
- abort();
- }
+ _cgo_beginthread(threadentry, ts);
}
extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
diff --git a/src/runtime/cgo/libcgo_windows.h b/src/runtime/cgo/libcgo_windows.h
index 0013f06..33d7637 100644
--- a/src/runtime/cgo/libcgo_windows.h
+++ b/src/runtime/cgo/libcgo_windows.h
@@ -2,11 +2,5 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Ensure there's one symbol marked __declspec(dllexport).
-// If there are no exported symbols, the unfortunate behavior of
-// the binutils linker is to also strip the relocations table,
-// resulting in non-PIE binary. The other option is the
-// --export-all-symbols flag, but we don't need to export all symbols
-// and this may overflow the export table (#40795).
-// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
-__declspec(dllexport) int _cgo_dummy_export;
+// Call _beginthread, aborting on failure.
+void _cgo_beginthread(void (*func)(void*), void* arg);