11// SPDX-License-Identifier: Apache-2.0
22// ----------------------------------------------------------------------------
3- // Copyright 2011-2023 Arm Limited
3+ // Copyright 2011-2024 Arm Limited
44//
55// Licensed under the Apache License, Version 2.0 (the "License"); you may not
66// use this file except in compliance with the License. You may obtain a copy
3838#if defined(_WIN32) && !defined(__CYGWIN__)
3939
4040#define WIN32_LEAN_AND_MEAN
41+ #define NOMINMAX
4142#include < windows.h>
43+ #include < Processthreadsapi.h>
44+ #include < algorithm>
45+ #include < cstring>
4246
4347/* * @brief Alias pthread_t to one of the internal Windows types. */
4448typedef HANDLE pthread_t ;
@@ -58,7 +62,7 @@ static int pthread_create(
5862 static_cast <void >(attribs);
5963 LPTHREAD_START_ROUTINE func = reinterpret_cast <LPTHREAD_START_ROUTINE>(threadfunc);
6064 *thread = CreateThread (nullptr , 0 , func, thread_arg, 0 , nullptr );
61-
65+
6266 // Ensure we return 0 on success, non-zero on error
6367 if (*thread == NULL )
6468 {
@@ -142,6 +146,24 @@ double get_time()
142146 return static_cast <double >(ticks) / 1.0e7 ;
143147}
144148
149+ /* See header for documentation */
150+ void set_thread_name (
151+ const char * name
152+ ) {
153+ // Names are limited to 16 characters
154+ wchar_t wname [16 ] { 0 };
155+ size_t name_len = std::strlen (name);
156+ size_t clamp_len = std::min<size_t >(name_len, 15 );
157+
158+ // We know we only have basic 7-bit ASCII so just widen
159+ for (size_t i = 0 ; i < clamp_len; i++)
160+ {
161+ wname[i] = static_cast <wchar_t >(name[i]);
162+ }
163+
164+ SetThreadDescription (GetCurrentThread (), wname);
165+ }
166+
145167/* ============================================================================
146168 Platform code for an platform using POSIX APIs.
147169============================================================================ */
@@ -165,6 +187,18 @@ double get_time()
165187 return static_cast <double >(tv.tv_sec ) + static_cast <double >(tv.tv_usec ) * 1.0e-6 ;
166188}
167189
190+ /* See header for documentation */
191+ void set_thread_name (
192+ const char * name
193+ ) {
194+ // No standard mechanism, so be defensive here
195+ #if defined(__linux__)
196+ pthread_setname_np (pthread_self (), name);
197+ #elif defined(__APPLE__)
198+ pthread_setname_np (name);
199+ #endif
200+ }
201+
168202#endif
169203
170204/* *
@@ -215,9 +249,9 @@ void launch_threads(
215249 }
216250
217251 // Otherwise spawn worker threads
218- launch_desc *thread_descs = new launch_desc[thread_count];
252+ launch_desc *thread_descs = new launch_desc[thread_count];
219253 int actual_thread_count { 0 };
220-
254+
221255 for (int i = 0 ; i < thread_count; i++)
222256 {
223257 thread_descs[actual_thread_count].thread_count = thread_count;
@@ -230,7 +264,7 @@ void launch_threads(
230264 &(thread_descs[actual_thread_count].thread_handle ),
231265 nullptr ,
232266 launch_threads_helper,
233- reinterpret_cast <void *>(thread_descs + actual_thread_count));
267+ reinterpret_cast <void *>(thread_descs + actual_thread_count));
234268
235269 // Track how many threads we actually created
236270 if (!error)
@@ -248,7 +282,7 @@ void launch_threads(
248282
249283 // If we did not create thread_count threads then emit a warning
250284 if (actual_thread_count != thread_count)
251- {
285+ {
252286 int log_count = actual_thread_count == 0 ? 1 : actual_thread_count;
253287 const char * log_s = log_count == 1 ? " " : " s" ;
254288 printf (" WARNING: %s using %d thread%s due to thread creation error\n\n " ,
0 commit comments