Skip to content

Commit 6d5e58f

Browse files
authored
Assign names to threads in CLI tool (#497)
1 parent e9d8c46 commit 6d5e58f

File tree

3 files changed

+62
-7
lines changed

3 files changed

+62
-7
lines changed

Source/astcenccli_internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,16 @@ void launch_threads(
397397
void (*func)(int, int, void*),
398398
void *payload);
399399

400+
/**
401+
* @brief Set the current thread name to a string value.
402+
*
403+
* For portability strings should be no longer than 16 characters.
404+
*
405+
* @param name The thread name.
406+
*/
407+
void set_thread_name(
408+
const char* name);
409+
400410
/**
401411
* @brief The main entry point.
402412
*

Source/astcenccli_platform_dependents.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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
@@ -38,7 +38,11 @@
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. */
4448
typedef 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",

Source/astcenccli_toplevel.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ static void compression_workload_runner(
232232
) {
233233
(void)thread_count;
234234

235+
char name[16] { 0 };
236+
std::snprintf(name, 16, "astc workc %d", thread_id);
237+
set_thread_name(name);
238+
235239
compression_workload* work = static_cast<compression_workload*>(payload);
236240
astcenc_error error = astcenc_compress_image(
237241
work->context, work->image, &work->swizzle,
@@ -259,6 +263,10 @@ static void decompression_workload_runner(
259263
) {
260264
(void)thread_count;
261265

266+
char name[16] { 0 };
267+
std::snprintf(name, 16, "astc workd %d", thread_id);
268+
set_thread_name(name);
269+
262270
decompression_workload* work = static_cast<decompression_workload*>(payload);
263271
astcenc_error error = astcenc_decompress_image(
264272
work->context, work->data, work->data_len,
@@ -1881,10 +1889,13 @@ static void print_diagnostic_images(
18811889
*
18821890
* @return 0 on success, non-zero otherwise.
18831891
*/
1884-
int astcenc_main(
1892+
int
1893+
astcenc_main(
18851894
int argc,
18861895
char **argv
18871896
) {
1897+
set_thread_name("astc main");
1898+
18881899
#if ASTCENC_SVE != 0
18891900
// Do this check here because is needs SVE instructions so cannot be in
18901901
// the veneer check which is compiled as stock Armv8. We know we have SVE

0 commit comments

Comments
 (0)