diff --git a/include/posix/pthread.h b/include/posix/pthread.h index b93b82861d3..12707894db0 100644 --- a/include/posix/pthread.h +++ b/include/posix/pthread.h @@ -522,6 +522,41 @@ int pthread_key_delete(pthread_key_t key); int pthread_setspecific(pthread_key_t key, const void *value); void *pthread_getspecific(pthread_key_t key); +/* Glibc / Oracle Extension Functions */ + +/** + * @brief Set name of POSIX thread. + * + * Non-portable, extension function that conforms with most + * other definitions of this function. + * + * @param thread POSIX thread to set name + * @param name Name string + * @retval 0 Success + * @retval ESRCH Thread does not exist + * @retval EINVAL Name buffer is NULL + * @retval Negative value if kernel function error + * + */ +int pthread_setname_np(pthread_t thread, const char *name); + +/** + * @brief Get name of POSIX thread and store in name buffer + * that is of size len. + * + * Non-portable, extension function that conforms with most + * other definitions of this function. + * + * @param thread POSIX thread to obtain name information + * @param name Destination buffer + * @param len Destination buffer size + * @retval 0 Success + * @retval ESRCH Thread does not exist + * @retval EINVAL Name buffer is NULL + * @retval Negative value if kernel function error + */ +int pthread_getname_np(pthread_t thread, char *name, size_t len); + #ifdef __cplusplus } #endif diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 2178b0518fd..ca4ed4ae732 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -597,3 +597,47 @@ int pthread_attr_destroy(pthread_attr_t *attr) return EINVAL; } + +int pthread_setname_np(pthread_t thread, const char *name) +{ +#ifdef CONFIG_THREAD_NAME + k_tid_t kthread = (k_tid_t)thread; + + if (kthread == NULL) { + return ESRCH; + } + + if (name == NULL) { + return EINVAL; + } + + return k_thread_name_set(kthread, name); +#else + ARG_UNUSED(thread); + ARG_UNUSED(name); + return 0; +#endif +} + +int pthread_getname_np(pthread_t thread, char *name, size_t len) +{ +#ifdef CONFIG_THREAD_NAME + k_tid_t kthread = (k_tid_t)thread; + + if (kthread == NULL) { + return ESRCH; + } + + if (name == NULL) { + return EINVAL; + } + + memset(name, '\0', len); + return k_thread_name_copy(kthread, name, len-1); +#else + ARG_UNUSED(thread); + ARG_UNUSED(name); + ARG_UNUSED(len); + return 0; +#endif +} diff --git a/tests/posix/common/prj.conf b/tests/posix/common/prj.conf index 4f6a845b21c..f01ae5140a9 100644 --- a/tests/posix/common/prj.conf +++ b/tests/posix/common/prj.conf @@ -6,5 +6,6 @@ CONFIG_SEM_VALUE_MAX=32767 CONFIG_POSIX_MQUEUE=y CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_MAX_THREAD_BYTES=4 +CONFIG_THREAD_NAME=y CONFIG_SMP=n diff --git a/tests/posix/common/src/pthread.c b/tests/posix/common/src/pthread.c index 2b73b4ec77d..d055ee7eeb2 100644 --- a/tests/posix/common/src/pthread.c +++ b/tests/posix/common/src/pthread.c @@ -10,6 +10,10 @@ #include #include +#ifndef min +#define min(a, b) ((a) < (b)) ? (a) : (b) +#endif + #define N_THR_E 3 #define N_THR_T 4 #define BOUNCES 64 @@ -235,6 +239,8 @@ void test_posix_pthread_execution(void) void *retval, *stackaddr; size_t stacksize; int serial_threads = 0; + char name[] = "thread name"; + char getName[CONFIG_THREAD_MAX_NAME_LEN]; sem_init(&main_sem, 0, 1); schedparam.sched_priority = CONFIG_NUM_COOP_PRIORITIES - 1; @@ -283,6 +289,14 @@ void test_posix_pthread_execution(void) ret = pthread_attr_destroy(&attr[0]); zassert_equal(ret, EINVAL, "uninitialized attr destroyed!"); + /* TESTPOINT: Try getting thread name before init */ + ret = pthread_getname_np(newthread[0], getName, sizeof(getName)); + zassert_equal(ret, ESRCH, "uninitialized getname!"); + + /* TESTPOINT: Try setting thread name before init */ + ret = pthread_setname_np(newthread[0], name); + zassert_equal(ret, ESRCH, "uninitialized setname!"); + /* TESTPOINT: Try creating thread before attr init */ ret = pthread_create(&newthread[0], &attr[0], thread_top_exec, NULL); @@ -325,6 +339,26 @@ void test_posix_pthread_execution(void) zassert_false(ret, "Number of threads exceed max limit"); } + /* TESTPOINT: Try getting thread name with no buffer */ + ret = pthread_getname_np(newthread[0], NULL, sizeof(getName)); + zassert_equal(ret, EINVAL, "uninitialized getname!"); + + /* TESTPOINT: Try setting thread name with no buffer */ + ret = pthread_setname_np(newthread[0], NULL); + zassert_equal(ret, EINVAL, "uninitialized setname!"); + + /* TESTPOINT: Try setting thread name */ + ret = pthread_setname_np(newthread[0], name); + zassert_false(ret, "Set name failed!"); + + /* TESTPOINT: Try getting thread name */ + ret = pthread_getname_np(newthread[0], getName, sizeof(getName)); + zassert_false(ret, "Get name failed!"); + + /* TESTPOINT: Thread names match */ + ret = strncmp(name, getName, min(strlen(name), strlen(getName))); + zassert_false(ret, "Thread names don't match!"); + while (!bounce_test_done()) { sem_wait(&main_sem); }