Using SetThreadDescription has the advantage that on recent Visual
Studio / Windows, the thread name is always available regardless of
whether a debugger was attached, is also available in crash dumps, and
to other tools.
Quoting MSDN at Set a thread name in C/C++:
https://learn.microsoft.com/en-us/visualstudio/debugger/tips-for-debugging-threads?view=vs-2022&tabs=csharp#set-a-thread-name-in-cc
> There are two ways to set a thread name. The first is via the
> SetThreadDescription function. The second is by throwing a
> particular exception while the Visual Studio debugger is attached to
> the process. Each approach has benefits and caveats. The use of
> SetThreadDescription is supported starting in Windows 10 version
> 1607 or Windows Server 2016.
>
> It's worth noting that both approaches can be used together, if
> desired, since the mechanisms by which they work are independent of
> each other.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: LIU Hao <lh_mouse@126.com>
Here is a patch which fixes bugs #988 and #992 following the commit
7b3379.
This commit introduced a new function winpthreads_init in charge of
setting up the _pthread_get_system_time_best_as_file_time and _pthread_get_tick_count_64
pointers using a runtime detection.
This function is defined with the constructor attribute. The problem is
that every static object making use of a constructor is also tagged with
this constructor attribute and the call ordering is unspecified.
For example, when linking code making use of C++11 chrono objects the
libstdc++ code is called before winpthreads_init but makes of the
clock_gettime function which causes a crash.
A minimal reproduction code can be found here in bug #992.
This bug can be fixed by setting a priority of 0 to the
winpthreads_constructor. It is then called before the static
constructors.
Signed-off-by: LIU Hao <lh_mouse@126.com>
Commit f281f4969d changed
pthread_cleanup_push() to use MemoryBarrier() instead of
__sync_synchronize(), for various reasons - one of them being
able to build winpthreads with MSVC.
Unfortunately, this change had the effect of breaking user code,
including winpthreads headers and using pthread_cleanup_push()
without including Windows headers first, as the MemoryBarrier()
intrinsic requires including headers to get it properly declared
(both with GCC, Clang and MSVC).
To avoid this issue, revert to __sync_synchronize() in the
installed header, as long as it is included with a GCC compatible
compiler. For MSVC, keep using MemoryBarrier().
Signed-off-by: Martin Storsjö <martin@martin.st>
Microsoft documentation states that MSVC doesn't support __declspec
after the pointer star for a return type. Move all the specifiers
before return types for consistency.
// Recommended, selectany & int both part of decl-specifier
__declspec(selectany) int * pi1 = 0;
// OK, selectany & int both part of decl-specifier
int __declspec(selectany) * pi2 = 0;
// ERROR, selectany is not part of a declarator
int * __declspec(selectany) pi3 = 0;
https://learn.microsoft.com/en-us/cpp/cpp/declspec?view=msvc-170
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
The non-suffixed macro GetModuleHandle depends on whether the file is
being compiled in Unicode mode or not. Prefer using the char string
literal here, for compatibility with old Windows not supporting
Unicode.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
It is sufficient to specify the section on the symbol declaration.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
Some WinAPI functions were introduced in recent versions of
Windows. We could detect whether to use the newer functions based on
the _WIN32_WINNT define. However, the issue is that _WIN32_WINNT
defaults to Win10 these days, so a default build of a toolchain won't
work for older targets, which is why it was agreed to do the change to
try to load this function at runtime.
https://sourceforge.net/p/mingw-w64/mailman/message/47371359/,
https://sourceforge.net/p/mingw-w64/mailman/message/49958237/ and
https://sourceforge.net/p/mingw-w64/mailman/message/48131379/.
Multiple workarounds are needed for MSVC to make this detection
portable.
1. Missing constructor attribute in MSVC
> The `constructor` attribute causes the function to be called before
> entering `main()`.
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-constructor-function-attributehttps://clang.llvm.org/docs/AttributeReference.html#constructor
This feature is not supported by the MSVC compiler, and can be worked
around by putting a function pointer to the constructor in the
.CRT$XC? section of the executable.
https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170#linker-features-for-initialization
We chose the .CRT$XCT section, however the documentation warns:
> The names .CRT$XCT and .CRT$XCV aren't used by either the compiler
> or the CRT library right now, but there's no guarantee that they'll
> remain unused in the future. And, your variables could still be
> optimized away by the compiler. Consider the potential engineering,
> maintenance, and portability issues before adopting this technique.
2. Missing typeof extension in MSVC
As MSVC doesn't support the GCC __typeof__ extension, we explicit the
type of the function pointer.
Casting the result of GetProcAddress (a function pointer) to
a (void *) (a data pointer) is allowed as an extension, mimics the
POSIX dlsym function, and prevents compiler warnings.
3. Missing __atomic functions in MSVC
MSVC doesn't support GCC __atomic functions. Finding whether
GetSystemTimePreciseAsFileTime is present on the system can be done
using a function tagged with the constructor attribute, avoiding the
need of atomics to prevent races.
4. Gather the initialization bits into a single function
Considering the amount of boilerplate code needed to instruct the
linker on MSVC, gather the discovery of the WinAPI functions in a
single winpthreads_init function. The WinAPI functions can be accessed
through internal global function pointers.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
Use YieldProcessor which already has the best definition for all MSVC
and MinGW supported architectures of the memory pause / yield
instruction.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
- Make pthread_create_wrapper return an unsigned;
_beginthreadindex takes a function returning an unsigned. The
variable holding the return value of pthread_create_wrapper is
already an unsigned.
- Make pthread_create_wrapper __stdcall.
Co-authored-by: Samuel Hym <samuel.hym@rustyne.lautre.net>
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
The requested stack size is a `size_t`, whereas _beginthreadex takes
an `unsigned int`. This provides a bit of input sanitation, and
prevents a compiler warning.
Co-authored-by: Samuel Hym <samuel.hym@rustyne.lautre.net>
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
Binutils' windres uses the C preprocessor and gets MinGW pre-defined
macros, whereas the Microsoft tool RC [1] implements its own C
preprocessor and doesn't call MSVC, so it defines a subset of the
macros.
Also update the copyright year, license field, and url of the project.
License field is updated to "MIT AND BSD-3-Clause" using SPDX [2]
identifiers and expressions, removing ZPL, considering the COPYING
file in winpthreads.
[1]: https://learn.microsoft.com/en-us/windows/win32/menurc/resource-compiler
[2]: https://spdx.dev/use/specifications/
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
This is done by running `WANT_AUTOMAKE=1.16 autoreconf -ifv` in the
winpthreads directory.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
Fixes a warning from libtoolize: 'AC_PROG_RANLIB' is rendered obsolete
by 'LT_INIT'.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
MSVC warns [1] against relative path in include directives, and
semaphore.h is already in the include path.
warning C4464: relative include path contains '..'
[1]: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4464?view=msvc-170
windows.h is a system header and better placed at first, enclosed in
angle brackets.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
Interestingly, pthread_cleanup_push/pop are allowed by POSIX to be
implemented as macros opening and closing an lexical scope. By using
the well-known trick of do { ... } while (0) [1], we prevent potential
scoping issues in surrounding code when the macro is expanded.
Removing the comma operator in pthread_cleanup_pop prevents compiler
warnings against not using the return value of the expression, and a
against an empty statement.
[1]: https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
A classic idiom preventing all kinds of bad interactions with
surrounding code when the macro is expanded. Newer compilers may also
warn against empty statements of the form
{ expressions... };
where the ending ; is actually an empty statement.
https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
As DWORD is a typedef for unsigned long, we can use the %lu format
specifier. The %p format specifier requires (void *) pointers.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
- Force a reference to _tls_used to make the linker create the TLS
directory if it's not already there. (e.g. if __declspec(thread) is
not used).
- Force a reference to __xl_f to prevent whole program optimization
from discarding the variable.
- On x86, symbols are prefixed with an underscore.
- Mark the TLS callback as const.
- Prefer using #pragma section (over const_seg or data_seg) as it
makes the code shorter and allows sharing code with GCC, and is
portable to all architectures.
- Declare the variable as extern const to silence clang-cl warnings.
[1]: https://learn.microsoft.com/en-us/cpp/preprocessor/pragma-seg?view=msvc-170
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
Previous code was too complex and hard to understand, and snprintf
fits the job nicely.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
Prevents a warning of `r` being shadowed, and makes the code clearer.
Signed-off-by: Antonin Décimo <antonin@tarides.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
In Windows Store builds with the winstorecompat library,
GetModuleHandle returns null, and GetProcAddress is not documented
to allow passing null.
Signed-off-by: Martin Storsjö <martin@martin.st>
The hidden API are found in windowsapp since the RS4/19H1 SDK. They are
also allowed by the WACK in api-ms-win-security-cryptoapi-l1-1-0.
That DLL has been on all Windows 10 versions [1].
It's better to use the real API than using CCryptography winrt API just for
these calls.
Crypto.c is kept in the old winstorecompat when targetting Windows 8.
Apps targetting UWP before 19H1 and using CryptGenRandom may not work
if api-ms-win-security-cryptoapi-l1-1-0.dll on older Windows doesn't
contain the entry.
[1] https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-security-cryptoapi-l1-1-0dll
Signed-off-by: LIU Hao <lh_mouse@126.com>