From 00e793cfe36de845501ea302645094149ed63e91 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Mon, 24 Feb 2025 15:37:41 +0100 Subject: [PATCH] runtime/cgo: use CreateThread instead of _beginthread _beginthread is intended to be used together with the C runtime. The cgo runtime doesn't use it, so better use CreateThread directly, which is the Windows API for creating threads. Cq-Include-Trybots: luci.golang.try:gotip-windows-amd64-longtest,gotip-windows-arm64 Change-Id: Ic6cf75f69f62a3babf5e74155da1aac70961886c Reviewed-on: https://go-review.googlesource.com/c/go/+/651995 Reviewed-by: Michael Pratt Reviewed-by: Ian Lance Taylor LUCI-TryBot-Result: Go LUCI --- src/runtime/cgo/gcc_libinit_windows.c | 25 ++++++++++--------------- src/runtime/cgo/gcc_windows_386.c | 6 ++++-- src/runtime/cgo/gcc_windows_amd64.c | 6 ++++-- src/runtime/cgo/gcc_windows_arm64.c | 6 ++++-- src/runtime/cgo/libcgo_windows.h | 2 +- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/runtime/cgo/gcc_libinit_windows.c b/src/runtime/cgo/gcc_libinit_windows.c index ddc0ad7010..5bd64acf23 100644 --- a/src/runtime/cgo/gcc_libinit_windows.c +++ b/src/runtime/cgo/gcc_libinit_windows.c @@ -2,19 +2,15 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -# ifdef __CYGWIN__ +#ifdef __CYGWIN__ #error "don't use the cygwin compiler to build native Windows programs; use MinGW instead" -#else -// Exclude the following code from Cygwin builds. -// Cygwin doesn't implement process.h nor does it support _beginthread. +#endif #define WIN32_LEAN_AND_MEAN #include -#include #include #include -#include #include "libcgo.h" #include "libcgo_windows.h" @@ -69,7 +65,7 @@ _cgo_maybe_run_preinit() { } void -x_cgo_sys_thread_create(void (*func)(void*), void* arg) { +x_cgo_sys_thread_create(unsigned long (__stdcall *func)(void*), void* arg) { _cgo_beginthread(func, arg); } @@ -141,26 +137,25 @@ void (*(_cgo_get_context_function(void)))(struct context_arg*) { return ret; } -void _cgo_beginthread(void (*func)(void*), void* arg) { +void _cgo_beginthread(unsigned long (__stdcall *func)(void*), void* arg) { int tries; - uintptr_t thandle; + HANDLE thandle; for (tries = 0; tries < 20; tries++) { - thandle = _beginthread(func, 0, arg); - if (thandle == -1 && errno == EACCES) { + thandle = CreateThread(NULL, 0, func, arg, 0, NULL); + if (thandle == 0 && GetLastError() == ERROR_NOT_ENOUGH_MEMORY) { // "Insufficient resources", try again in a bit. // // Note that the first Sleep(0) is a yield. Sleep(tries); // milliseconds continue; - } else if (thandle == -1) { + } else if (thandle == 0) { break; } + CloseHandle(thandle); return; // Success! } - fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno); + fprintf(stderr, "runtime: failed to create new OS thread (%lu)\n", GetLastError()); abort(); } - -#endif // __CYGWIN__ \ No newline at end of file diff --git a/src/runtime/cgo/gcc_windows_386.c b/src/runtime/cgo/gcc_windows_386.c index 983e14b7c8..d394dc6acb 100644 --- a/src/runtime/cgo/gcc_windows_386.c +++ b/src/runtime/cgo/gcc_windows_386.c @@ -11,7 +11,7 @@ #include "libcgo.h" #include "libcgo_windows.h" -static void threadentry(void*); +static unsigned long __stdcall threadentry(void*); static void (*setg_gcc)(void*); static DWORD *tls_g; @@ -29,7 +29,8 @@ _cgo_sys_thread_start(ThreadStart *ts) } extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g); -static void +static unsigned long +__stdcall threadentry(void *v) { ThreadStart ts; @@ -50,4 +51,5 @@ threadentry(void *v) ); crosscall1(ts.fn, setg_gcc, ts.g); + return 0; } diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c index e26887a172..455b6b7cb2 100644 --- a/src/runtime/cgo/gcc_windows_amd64.c +++ b/src/runtime/cgo/gcc_windows_amd64.c @@ -11,7 +11,7 @@ #include "libcgo.h" #include "libcgo_windows.h" -static void threadentry(void*); +static unsigned long __stdcall threadentry(void*); static void (*setg_gcc)(void*); static DWORD *tls_g; @@ -30,7 +30,8 @@ _cgo_sys_thread_start(ThreadStart *ts) } extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g); -static void +static unsigned long +__stdcall threadentry(void *v) { ThreadStart ts; @@ -49,4 +50,5 @@ threadentry(void *v) ); crosscall1(ts.fn, setg_gcc, (void*)ts.g); + return 0; } diff --git a/src/runtime/cgo/gcc_windows_arm64.c b/src/runtime/cgo/gcc_windows_arm64.c index 8f113cc3b1..7f02d4bd5c 100644 --- a/src/runtime/cgo/gcc_windows_arm64.c +++ b/src/runtime/cgo/gcc_windows_arm64.c @@ -11,7 +11,7 @@ #include "libcgo.h" #include "libcgo_windows.h" -static void threadentry(void*); +static unsigned long __stdcall threadentry(void*); static void (*setg_gcc)(void*); void @@ -28,7 +28,8 @@ _cgo_sys_thread_start(ThreadStart *ts) extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g); -static void +static unsigned long +__stdcall threadentry(void *v) { ThreadStart ts; @@ -37,4 +38,5 @@ threadentry(void *v) free(v); crosscall1(ts.fn, setg_gcc, (void *)ts.g); + return 0; } diff --git a/src/runtime/cgo/libcgo_windows.h b/src/runtime/cgo/libcgo_windows.h index 33d7637fec..682b7bdbbf 100644 --- a/src/runtime/cgo/libcgo_windows.h +++ b/src/runtime/cgo/libcgo_windows.h @@ -3,4 +3,4 @@ // license that can be found in the LICENSE file. // Call _beginthread, aborting on failure. -void _cgo_beginthread(void (*func)(void*), void* arg); +void _cgo_beginthread(unsigned long (__stdcall *func)(void*), void* arg); -- 2.51.0