Skip to content

Commit

Permalink
Assign names to threads in CLI tool (#497)
Browse files Browse the repository at this point in the history
  • Loading branch information
solidpixel authored Aug 16, 2024
1 parent e9d8c46 commit 6d5e58f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
10 changes: 10 additions & 0 deletions Source/astcenccli_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,16 @@ void launch_threads(
void (*func)(int, int, void*),
void *payload);

/**
* @brief Set the current thread name to a string value.
*
* For portability strings should be no longer than 16 characters.
*
* @param name The thread name.
*/
void set_thread_name(
const char* name);

/**
* @brief The main entry point.
*
Expand Down
46 changes: 40 additions & 6 deletions Source/astcenccli_platform_dependents.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2023 Arm Limited
// Copyright 2011-2024 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
Expand Down Expand Up @@ -38,7 +38,11 @@
#if defined(_WIN32) && !defined(__CYGWIN__)

#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <Processthreadsapi.h>
#include <algorithm>
#include <cstring>

/** @brief Alias pthread_t to one of the internal Windows types. */
typedef HANDLE pthread_t;
Expand All @@ -58,7 +62,7 @@ static int pthread_create(
static_cast<void>(attribs);
LPTHREAD_START_ROUTINE func = reinterpret_cast<LPTHREAD_START_ROUTINE>(threadfunc);
*thread = CreateThread(nullptr, 0, func, thread_arg, 0, nullptr);

// Ensure we return 0 on success, non-zero on error
if (*thread == NULL)
{
Expand Down Expand Up @@ -142,6 +146,24 @@ double get_time()
return static_cast<double>(ticks) / 1.0e7;
}

/* See header for documentation */
void set_thread_name(
const char* name
) {
// Names are limited to 16 characters
wchar_t wname [16] { 0 };
size_t name_len = std::strlen(name);
size_t clamp_len = std::min<size_t>(name_len, 15);

// We know we only have basic 7-bit ASCII so just widen
for (size_t i = 0; i < clamp_len; i++)
{
wname[i] = static_cast<wchar_t>(name[i]);
}

SetThreadDescription(GetCurrentThread(), wname);
}

/* ============================================================================
Platform code for an platform using POSIX APIs.
============================================================================ */
Expand All @@ -165,6 +187,18 @@ double get_time()
return static_cast<double>(tv.tv_sec) + static_cast<double>(tv.tv_usec) * 1.0e-6;
}

/* See header for documentation */
void set_thread_name(
const char* name
) {
// No standard mechanism, so be defensive here
#if defined(__linux__)
pthread_setname_np(pthread_self(), name);
#elif defined(__APPLE__)
pthread_setname_np(name);
#endif
}

#endif

/**
Expand Down Expand Up @@ -215,9 +249,9 @@ void launch_threads(
}

// Otherwise spawn worker threads
launch_desc *thread_descs = new launch_desc[thread_count];
launch_desc *thread_descs = new launch_desc[thread_count];
int actual_thread_count { 0 };

for (int i = 0; i < thread_count; i++)
{
thread_descs[actual_thread_count].thread_count = thread_count;
Expand All @@ -230,7 +264,7 @@ void launch_threads(
&(thread_descs[actual_thread_count].thread_handle),
nullptr,
launch_threads_helper,
reinterpret_cast<void*>(thread_descs + actual_thread_count));
reinterpret_cast<void*>(thread_descs + actual_thread_count));

// Track how many threads we actually created
if (!error)
Expand All @@ -248,7 +282,7 @@ void launch_threads(

// If we did not create thread_count threads then emit a warning
if (actual_thread_count != thread_count)
{
{
int log_count = actual_thread_count == 0 ? 1 : actual_thread_count;
const char* log_s = log_count == 1 ? "" : "s";
printf("WARNING: %s using %d thread%s due to thread creation error\n\n",
Expand Down
13 changes: 12 additions & 1 deletion Source/astcenccli_toplevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ static void compression_workload_runner(
) {
(void)thread_count;

char name[16] { 0 };
std::snprintf(name, 16, "astc workc %d", thread_id);
set_thread_name(name);

compression_workload* work = static_cast<compression_workload*>(payload);
astcenc_error error = astcenc_compress_image(
work->context, work->image, &work->swizzle,
Expand Down Expand Up @@ -259,6 +263,10 @@ static void decompression_workload_runner(
) {
(void)thread_count;

char name[16] { 0 };
std::snprintf(name, 16, "astc workd %d", thread_id);
set_thread_name(name);

decompression_workload* work = static_cast<decompression_workload*>(payload);
astcenc_error error = astcenc_decompress_image(
work->context, work->data, work->data_len,
Expand Down Expand Up @@ -1881,10 +1889,13 @@ static void print_diagnostic_images(
*
* @return 0 on success, non-zero otherwise.
*/
int astcenc_main(
int
astcenc_main(
int argc,
char **argv
) {
set_thread_name("astc main");

#if ASTCENC_SVE != 0
// Do this check here because is needs SVE instructions so cannot be in
// the veneer check which is compiled as stock Armv8. We know we have SVE
Expand Down

0 comments on commit 6d5e58f

Please sign in to comment.