2021-06-18 18:57 (UTC-0700), Narcisa Ana Maria Vasile: > From: Narcisa Vasile <navas...@microsoft.com> > > Implement function that sets the name of a thread. > On Windows, SetThreadDescription() is used. Use GetProcAddress() > to obtain the address of the function for MinGW compatibility. > > Depends-on: series-17402 ("eal: Add EAL API for threading") > > Signed-off-by: Narcisa Vasile <navas...@microsoft.com> > --- > lib/eal/common/rte_thread.c | 17 ++++++++++ > lib/eal/include/rte_thread.h | 18 +++++++++++ > lib/eal/version.map | 1 + > lib/eal/windows/rte_thread.c | 60 ++++++++++++++++++++++++++++++++++++ > 4 files changed, 96 insertions(+) [...] > diff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h > index 40da83467b..c65cfd8c9e 100644 > --- a/lib/eal/include/rte_thread.h > +++ b/lib/eal/include/rte_thread.h > @@ -24,6 +24,8 @@ extern "C" { > > #include <sched.h> > > +#define RTE_THREAD_MAX_DESCRIPTION_LENGTH 16 > +
Why export this constant? > /** > * Thread id descriptor. > */ > @@ -439,6 +441,22 @@ int rte_thread_barrier_wait(rte_thread_barrier *barrier); > __rte_experimental > int rte_thread_barrier_destroy(rte_thread_barrier *barrier); > > +/** > + * Set the name of the thread represented by 'thread_id'. > + * > + * @param thread_id > + * The id of the thread. > + * > + * @param name > + * Thread name to set. > + * > + * @return > + * On success, return 0. > + * On failure, return a positive errno-style error number. Typo: extra space. > + */ > +__rte_experimental > +int rte_thread_name_set(rte_thread_t thread_id, const char *name); > + There is `rte_thread_setname(pthread_t id, const char * name, size_t len)`. I assume it should be deprecated in favor of this new API via a notice in `deprecation.rst`. > /** > * Create a TLS data key visible to all threads in the process. > * the created key is later used to get/set a value. > diff --git a/lib/eal/version.map b/lib/eal/version.map > index 6645f60a78..2a566c04af 100644 > --- a/lib/eal/version.map > +++ b/lib/eal/version.map > @@ -443,6 +443,7 @@ EXPERIMENTAL { > rte_thread_barrier_init; > rte_thread_barrier_wait; > rte_thread_barrier_destroy; > + rte_thread_name_set; > }; > > INTERNAL { > diff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c > index b2ff16f51f..995ae2491d 100644 > --- a/lib/eal/windows/rte_thread.c > +++ b/lib/eal/windows/rte_thread.c > @@ -556,6 +556,66 @@ rte_thread_barrier_destroy(rte_thread_barrier *barrier) > return 0; > } > > +typedef HRESULT > +(*SetThreadDescription_type)(HANDLE thread_handle, PCWSTR > thread_description); > + > +int > +rte_thread_name_set(rte_thread_t thread_id, const char *name) > +{ > + int ret = 0; > + size_t count; > + HRESULT hr; > + HANDLE thread_handle = NULL; > + WCHAR w_name[RTE_THREAD_MAX_DESCRIPTION_LENGTH]; > + HMODULE kernel_lib = NULL; > + SetThreadDescription_type SetThreadDescription_ptr; > + > + static const char library_name[] = "kernel32.dll"; > + static const char function[] = "SetThreadDescription"; > + > + kernel_lib = LoadLibraryA(library_name); > + if (kernel_lib == NULL) { > + ret = thread_log_last_error("LoadLibraryA(\"kernel32.dll\")"); > + goto cleanup; > + } Rather then locate the function every time (kernel32.dll is always loaded), what do you think of using `RTE_INIT`/`RTE_FINI` for that? > + > + SetThreadDescription_ptr = (SetThreadDescription_type)( > + (void *)GetProcAddress(kernel_lib, function)); > + if (SetThreadDescription_ptr == NULL) { > + ret = thread_log_last_error("GetProcAddress(\"kernel32.dll\", > \"SetThreadDescription\")"); > + goto cleanup; > + } > + > + thread_handle = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, > + thread_id.opaque_id); > + if (thread_handle == NULL) { > + ret = thread_log_last_error("OpenThread()"); > + goto cleanup; > + } > + > + count = mbstowcs(w_name, name, RTE_THREAD_MAX_DESCRIPTION_LENGTH); It's better to use `RTE_DIM(w_name)`, this way named constant is not needed. > + if (count < 0) { > + RTE_LOG(DEBUG, EAL, "Invalid thread name!\n"); > + ret = EINVAL; > + goto cleanup; > + } > + > + hr = SetThreadDescription_ptr(thread_handle, w_name); > + if (FAILED(hr)) { > + ret = thread_log_last_error("SetThreadDescription()"); > + goto cleanup; > + } > + > +cleanup: > + if (kernel_lib != NULL) > + FreeLibrary(kernel_lib); > + if (thread_handle != NULL) { > + CloseHandle(thread_handle); > + thread_handle = NULL; Such local variable assignments on cleanup are useless. > + } > + return ret; > +} > + > int > rte_thread_key_create(rte_thread_key *key, > __rte_unused void (*destructor)(void *))