Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assign names to threads in CLI tool #497

Merged
merged 8 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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