[v2,1/4] eal: add thread set name API operating on rte thread
Checks
Commit Message
Add a rte_thread_set_name that sets the name of an rte_thread_t thread.
This is a replacement for the rte_thread_setname(pthread_t, ...) which
exposes platform-specific details.
Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
---
lib/eal/common/eal_common_thread.c | 9 +++-----
lib/eal/common/eal_common_trace.c | 2 --
lib/eal/freebsd/eal.c | 4 +++-
lib/eal/freebsd/eal_thread.c | 11 +++++++++
lib/eal/include/rte_thread.h | 17 ++++++++++++++
lib/eal/linux/eal.c | 8 +++----
lib/eal/linux/eal_thread.c | 22 ++++++++++++++++++
lib/eal/version.map | 3 +++
lib/eal/windows/rte_thread.c | 46 ++++++++++++++++++++++++++++++++++++++
9 files changed, 108 insertions(+), 14 deletions(-)
Comments
On Wed, Dec 14, 2022 at 5:47 PM Tyler Retzlaff
<roretzla@linux.microsoft.com> wrote:
> diff --git a/lib/eal/common/eal_common_trace.c b/lib/eal/common/eal_common_trace.c
> index 5caaac8..89522dc 100644
> --- a/lib/eal/common/eal_common_trace.c
> +++ b/lib/eal/common/eal_common_trace.c
> @@ -356,8 +356,6 @@ rte_trace_mode rte_trace_mode_get(void)
> /* Store the thread name */
> char *name = header->stream_header.thread_name;
> memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
> - rte_thread_getname(pthread_self(), name,
> - __RTE_TRACE_EMIT_STRING_LEN_MAX);
>
> trace->lcore_meta[count].mem = header;
> trace->nb_trace_mem_list++;
Note, this belongs to patch 2.
I understand we can drop the thread name retrieval helper from public
API, but at least for the trace framework it added some info in the
traces.
Jerin, Sunil, what do you think? Should we keep this helper internally?
On Wed, Jan 11, 2023 at 05:09:25PM +0100, David Marchand wrote:
> On Wed, Dec 14, 2022 at 5:47 PM Tyler Retzlaff
> <roretzla@linux.microsoft.com> wrote:
> > diff --git a/lib/eal/common/eal_common_trace.c b/lib/eal/common/eal_common_trace.c
> > index 5caaac8..89522dc 100644
> > --- a/lib/eal/common/eal_common_trace.c
> > +++ b/lib/eal/common/eal_common_trace.c
> > @@ -356,8 +356,6 @@ rte_trace_mode rte_trace_mode_get(void)
> > /* Store the thread name */
> > char *name = header->stream_header.thread_name;
> > memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
> > - rte_thread_getname(pthread_self(), name,
> > - __RTE_TRACE_EMIT_STRING_LEN_MAX);
> >
> > trace->lcore_meta[count].mem = header;
> > trace->nb_trace_mem_list++;
>
> Note, this belongs to patch 2.
agreed, not sure how i fumbled that. since there has been no reply about
retaining rte_thread_getname as an internal api i'll just move this
change to patch 2.
> I understand we can drop the thread name retrieval helper from public
> API, but at least for the trace framework it added some info in the
> traces.
> Jerin, Sunil, what do you think? Should we keep this helper internally?
>
>
> --
> David Marchand
On Wed, Jan 11, 2023 at 9:39 PM David Marchand
<david.marchand@redhat.com> wrote:
>
> On Wed, Dec 14, 2022 at 5:47 PM Tyler Retzlaff
> <roretzla@linux.microsoft.com> wrote:
> > diff --git a/lib/eal/common/eal_common_trace.c b/lib/eal/common/eal_common_trace.c
> > index 5caaac8..89522dc 100644
> > --- a/lib/eal/common/eal_common_trace.c
> > +++ b/lib/eal/common/eal_common_trace.c
> > @@ -356,8 +356,6 @@ rte_trace_mode rte_trace_mode_get(void)
> > /* Store the thread name */
> > char *name = header->stream_header.thread_name;
> > memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
> > - rte_thread_getname(pthread_self(), name,
> > - __RTE_TRACE_EMIT_STRING_LEN_MAX);
> >
> > trace->lcore_meta[count].mem = header;
> > trace->nb_trace_mem_list++;
>
> Note, this belongs to patch 2.
>
> I understand we can drop the thread name retrieval helper from public
> API, but at least for the trace framework it added some info in the
> traces.
> Jerin, Sunil, what do you think? Should we keep this helper internally?
Good catch @David Marchand. Yes, we should be it as internal helper
API use it here.
For trace, It will be difficult to make sense without thread name.
>
>
> --
> David Marchand
>
On Fri, Jan 13, 2023 at 10:06:44AM +0530, Jerin Jacob wrote:
> On Wed, Jan 11, 2023 at 9:39 PM David Marchand
> <david.marchand@redhat.com> wrote:
> >
> > On Wed, Dec 14, 2022 at 5:47 PM Tyler Retzlaff
> > <roretzla@linux.microsoft.com> wrote:
> > > diff --git a/lib/eal/common/eal_common_trace.c b/lib/eal/common/eal_common_trace.c
> > > index 5caaac8..89522dc 100644
> > > --- a/lib/eal/common/eal_common_trace.c
> > > +++ b/lib/eal/common/eal_common_trace.c
> > > @@ -356,8 +356,6 @@ rte_trace_mode rte_trace_mode_get(void)
> > > /* Store the thread name */
> > > char *name = header->stream_header.thread_name;
> > > memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
> > > - rte_thread_getname(pthread_self(), name,
> > > - __RTE_TRACE_EMIT_STRING_LEN_MAX);
> > >
> > > trace->lcore_meta[count].mem = header;
> > > trace->nb_trace_mem_list++;
> >
> > Note, this belongs to patch 2.
> >
> > I understand we can drop the thread name retrieval helper from public
> > API, but at least for the trace framework it added some info in the
> > traces.
> > Jerin, Sunil, what do you think? Should we keep this helper internally?
>
>
> Good catch @David Marchand. Yes, we should be it as internal helper
> API use it here.
> For trace, It will be difficult to make sense without thread name.
is the name what is really valuable here because it will only appear in
traces for linux with a new enough glibc, i.e. freebsd and windows it
will always be empty.
we could just provide the thread id and that is available on all
platforms, i'd like to see consistency for all platforms if possible
here but i'm not pushing too hard since we don't declare our tracing
output to be a compatibility surface.
can we just provide the thread id?
>
> >
> >
> > --
> > David Marchand
> >
On Fri, Jan 13, 2023 at 09:09:21AM -0800, Tyler Retzlaff wrote:
> On Fri, Jan 13, 2023 at 10:06:44AM +0530, Jerin Jacob wrote:
> > On Wed, Jan 11, 2023 at 9:39 PM David Marchand
> > <david.marchand@redhat.com> wrote:
> > >
> > > On Wed, Dec 14, 2022 at 5:47 PM Tyler Retzlaff
> > > <roretzla@linux.microsoft.com> wrote:
> > > > diff --git a/lib/eal/common/eal_common_trace.c b/lib/eal/common/eal_common_trace.c
> > > > index 5caaac8..89522dc 100644
> > > > --- a/lib/eal/common/eal_common_trace.c
> > > > +++ b/lib/eal/common/eal_common_trace.c
> > > > @@ -356,8 +356,6 @@ rte_trace_mode rte_trace_mode_get(void)
> > > > /* Store the thread name */
> > > > char *name = header->stream_header.thread_name;
> > > > memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
> > > > - rte_thread_getname(pthread_self(), name,
> > > > - __RTE_TRACE_EMIT_STRING_LEN_MAX);
> > > >
> > > > trace->lcore_meta[count].mem = header;
> > > > trace->nb_trace_mem_list++;
> > >
> > > Note, this belongs to patch 2.
> > >
> > > I understand we can drop the thread name retrieval helper from public
> > > API, but at least for the trace framework it added some info in the
> > > traces.
> > > Jerin, Sunil, what do you think? Should we keep this helper internally?
> >
> >
> > Good catch @David Marchand. Yes, we should be it as internal helper
> > API use it here.
> > For trace, It will be difficult to make sense without thread name.
>
> is the name what is really valuable here because it will only appear in
> traces for linux with a new enough glibc, i.e. freebsd and windows it
> will always be empty.
>
> we could just provide the thread id and that is available on all
> platforms, i'd like to see consistency for all platforms if possible
> here but i'm not pushing too hard since we don't declare our tracing
> output to be a compatibility surface.
>
> can we just provide the thread id?
as a compromise i have submitted a new version for the series that
curtails the scope of the original rte_thread_getname and allowing it at
this single callsite.
going forward however i would suggest we do not allow further internal
use.
thanks!
@@ -291,12 +291,9 @@ static void *ctrl_thread_init(void *arg)
return -ret;
}
- if (name != NULL) {
- ret = rte_thread_setname(*thread, name);
- if (ret < 0)
- RTE_LOG(DEBUG, EAL,
- "Cannot set name for ctrl thread\n");
- }
+ if (name != NULL)
+ rte_thread_set_name((rte_thread_t){(uintptr_t)*thread},
+ name);
/* Wait for the control thread to initialize successfully */
while ((ctrl_thread_status =
@@ -356,8 +356,6 @@ rte_trace_mode rte_trace_mode_get(void)
/* Store the thread name */
char *name = header->stream_header.thread_name;
memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
- rte_thread_getname(pthread_self(), name,
- __RTE_TRACE_EMIT_STRING_LEN_MAX);
trace->lcore_meta[count].mem = header;
trace->nb_trace_mem_list++;
@@ -817,7 +817,9 @@ static void rte_eal_init_alert(const char *msg)
/* Set thread_name for aid in debugging. */
snprintf(thread_name, sizeof(thread_name),
"rte-worker-%d", i);
- rte_thread_setname(lcore_config[i].thread_id, thread_name);
+ rte_thread_set_name(
+ (rte_thread_t){(uintptr_t)lcore_config[i].thread_id},
+ thread_name);
ret = pthread_setaffinity_np(lcore_config[i].thread_id,
sizeof(rte_cpuset_t), &lcore_config[i].cpuset);
@@ -32,6 +32,17 @@ int rte_sys_gettid(void)
return (int)lwpid;
}
+void rte_thread_set_name(rte_thread_t thread_id, const char *thread_name)
+{
+ char truncated[RTE_MAX_THREAD_NAME_LEN];
+ const size_t truncatedsz = sizeof(truncated);
+
+ if (strlcpy(truncated, thread_name, truncatedsz) >= truncatedsz)
+ RTE_LOG(DEBUG, EAL, "Truncated thread name\n");
+
+ pthread_set_name_np((pthread_t)thread_id.opaque_id, truncated);
+}
+
int rte_thread_setname(pthread_t id, const char *name)
{
/* this BSD function returns no error */
@@ -146,6 +146,23 @@ int rte_thread_create(rte_thread_t *thread_id,
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
+ * Set the name of the thread.
+ *
+ * @param thread_id
+ * The id of the thread to set name.
+ *
+ * @param thread_name
+ * The name to set. Truncated to RTE_MAX_THREAD_NAME_LEN,
+ * including terminating NUL if necessary.
+ */
+__rte_experimental
+void
+rte_thread_set_name(rte_thread_t thread_id, const char *thread_name);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
* Check if 2 thread ids are equal.
*
* @param t1
@@ -1255,11 +1255,9 @@ static void rte_eal_init_alert(const char *msg)
/* Set thread_name for aid in debugging. */
snprintf(thread_name, sizeof(thread_name),
"rte-worker-%d", i);
- ret = rte_thread_setname(lcore_config[i].thread_id,
- thread_name);
- if (ret != 0)
- RTE_LOG(DEBUG, EAL,
- "Cannot set name for lcore thread\n");
+ rte_thread_set_name(
+ (rte_thread_t){(uintptr_t)lcore_config[i].thread_id},
+ thread_name);
ret = pthread_setaffinity_np(lcore_config[i].thread_id,
sizeof(rte_cpuset_t), &lcore_config[i].cpuset);
@@ -10,6 +10,7 @@
#include <rte_eal.h>
#include <rte_lcore.h>
+#include <rte_log.h>
#include <rte_string_fns.h>
/* require calling thread tid by gettid() */
@@ -18,6 +19,27 @@ int rte_sys_gettid(void)
return (int)syscall(SYS_gettid);
}
+void rte_thread_set_name(rte_thread_t thread_id, const char *thread_name)
+{
+ int ret = ENOSYS;
+#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
+#if __GLIBC_PREREQ(2, 12)
+ char truncated[RTE_MAX_THREAD_NAME_LEN];
+ const size_t truncatedsz = sizeof(truncated);
+
+ if (strlcpy(truncated, thread_name, truncatedsz) >= truncatedsz)
+ RTE_LOG(DEBUG, EAL, "Truncated thread name\n");
+
+ ret = pthread_setname_np((pthread_t)thread_id.opaque_id, truncated);
+#endif
+#endif
+ RTE_SET_USED(thread_id);
+ RTE_SET_USED(thread_name);
+
+ if (ret != 0)
+ RTE_LOG(DEBUG, EAL, "Failed to set thread name\n");
+}
+
int rte_thread_setname(pthread_t id, const char *name)
{
int ret = ENOSYS;
@@ -440,6 +440,9 @@ EXPERIMENTAL {
rte_thread_detach;
rte_thread_equal;
rte_thread_join;
+
+ # added in 23.03
+ rte_thread_set_name;
};
INTERNAL {
@@ -4,7 +4,9 @@
*/
#include <errno.h>
+#include <wchar.h>
+#include <rte_eal.h>
#include <rte_common.h>
#include <rte_errno.h>
#include <rte_thread.h>
@@ -305,6 +307,50 @@ struct thread_routine_ctx {
return thread_id;
}
+void
+rte_thread_set_name(rte_thread_t thread_id, const char *thread_name)
+{
+ int ret = 0;
+ wchar_t wname[RTE_MAX_THREAD_NAME_LEN];
+ mbstate_t state = {0};
+ size_t rv;
+ HANDLE thread_handle;
+
+ thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE,
+ thread_id.opaque_id);
+ if (thread_handle == NULL) {
+ ret = thread_log_last_error("OpenThread()");
+ goto cleanup;
+ }
+
+ memset(wname, 0, sizeof(wname));
+ rv = mbsrtowcs(wname, &thread_name, RTE_DIM(wname) - 1, &state);
+ if (rv == (size_t)-1) {
+ ret = EILSEQ;
+ goto cleanup;
+ }
+
+ if (wcslen(wname) < strlen(thread_name))
+ RTE_LOG(DEBUG, EAL, "Truncated thread name\n");
+
+#ifndef RTE_TOOLCHAIN_GCC
+ if (FAILED(SetThreadDescription(thread_handle, wname))) {
+ ret = EINVAL;
+ goto cleanup;
+ }
+#else
+ ret = ENOTSUP;
+ goto cleanup;
+#endif
+
+cleanup:
+ if (thread_handle != NULL)
+ CloseHandle(thread_handle);
+
+ if (ret != 0)
+ RTE_LOG(DEBUG, EAL, "Failed to set thread name\n");
+}
+
int
rte_thread_get_priority(rte_thread_t thread_id,
enum rte_thread_priority *priority)