mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
libthr: pthread_query_np(3) and pthread_query_all_np(3)
Reviewed by: aokblast, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D60838
This commit is contained in:
1 parent
49e0c6270c
commit
588bd8bb6c
4 files changed
+149
No files matched your search
@@ -34,6 +34,34 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/cpuset.h>
|
||||
|
||||
enum pthread_state_np {
|
||||
PTHREAD_STATE_RUNNING_NP = 100,
|
||||
PTHREAD_STATE_SUSPENDED_NP,
|
||||
PTHREAD_STATE_DEAD_NP,
|
||||
};
|
||||
|
||||
#define PTHREAD_INFO_DETACHED_NP 0x0001
|
||||
#define PTHREAD_INFO_INITIAL_NP 0x0002
|
||||
|
||||
#define PTHREAD_INFO_CANCEL_ENABLED_NP 0x0001
|
||||
#define PTHREAD_INFO_CANCEL_ASYNC_NP 0x0002
|
||||
#define PTHREAD_INFO_CANCEL_PENDING_NP 0x0004
|
||||
#define PTHREAD_INFO_CANCEL_AT_POINT_NP 0x0008
|
||||
#define PTHREAD_INFO_CANCEL_IN_PROG_NP 0x0010
|
||||
|
||||
struct pthread_info_np {
|
||||
size_t pthread_info_size;
|
||||
pthread_t thread;
|
||||
long lwpid;
|
||||
enum pthread_state_np state;
|
||||
int flags;
|
||||
int cancel_state;
|
||||
int *errno_location;
|
||||
struct tcb *tcb;
|
||||
struct uexterror *exterr;
|
||||
char name[128];
|
||||
};
|
||||
|
||||
/*
|
||||
* Non-POSIX thread function prototype definitions:
|
||||
*/
|
||||
@@ -57,6 +85,8 @@ int pthread_mutex_isowned_np(pthread_mutex_t *mutex);
|
||||
void pthread_resume_all_np(void);
|
||||
int pthread_resume_np(pthread_t);
|
||||
int pthread_peekjoin_np(pthread_t, void **);
|
||||
int pthread_query_np(pthread_t, struct pthread_info_np *, size_t);
|
||||
int pthread_query_all_np(struct pthread_info_np *, size_t *);
|
||||
void pthread_set_name_np(pthread_t, const char *);
|
||||
int pthread_setaffinity_np(pthread_t, size_t, const cpuset_t *);
|
||||
void pthread_signals_block_np(void);
|
||||
|
||||
@@ -345,5 +345,7 @@ FBSD_1.8 {
|
||||
|
||||
FBSD_1.9 {
|
||||
pthread_cond_clockwait;
|
||||
pthread_query_np;
|
||||
pthread_query_all_np;
|
||||
pthread_tryjoin_np;
|
||||
};
|
||||
@@ -37,6 +37,7 @@ SRCS+= \
|
||||
thr_printf.c \
|
||||
thr_pshared.c \
|
||||
thr_pspinlock.c \
|
||||
thr_query.c \
|
||||
thr_resume_np.c \
|
||||
thr_rtld.c \
|
||||
thr_rwlock.c \
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright 2026 The FreeBSD Foundation
|
||||
*
|
||||
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
|
||||
#include "libc_private.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
static void
|
||||
pthread_getinfo(struct pthread *curthread, struct pthread *thread, bool locked,
|
||||
struct pthread_info_np *info)
|
||||
{
|
||||
if (!locked)
|
||||
THR_THREAD_LOCK(curthread, thread);
|
||||
info->pthread_info_size = sizeof(*info);
|
||||
info->thread = thread;
|
||||
info->lwpid = thread->tid;
|
||||
if (thread->state == PS_DEAD)
|
||||
info->state = PTHREAD_STATE_DEAD_NP;
|
||||
else if ((thread->flags & THR_FLAGS_SUSPENDED) != 0)
|
||||
info->state = PTHREAD_STATE_SUSPENDED_NP;
|
||||
else
|
||||
info->state = PTHREAD_STATE_RUNNING_NP;
|
||||
info->flags = 0;
|
||||
if ((thread->flags & THR_FLAGS_DETACHED) != 0)
|
||||
info->flags |= PTHREAD_INFO_DETACHED_NP;
|
||||
if (thread == _thr_initial)
|
||||
info->flags |= PTHREAD_INFO_INITIAL_NP;
|
||||
info->cancel_state = 0;
|
||||
if (thread->cancel_enable)
|
||||
info->cancel_state |= PTHREAD_INFO_CANCEL_ENABLED_NP;
|
||||
if (thread->cancel_async)
|
||||
info->cancel_state |= PTHREAD_INFO_CANCEL_ASYNC_NP;
|
||||
if (thread->cancel_point)
|
||||
info->cancel_state |= PTHREAD_INFO_CANCEL_AT_POINT_NP;
|
||||
if (thread->cancel_pending)
|
||||
info->cancel_state |= PTHREAD_INFO_CANCEL_PENDING_NP;
|
||||
if (thread->cancelling)
|
||||
info->cancel_state |= PTHREAD_INFO_CANCEL_IN_PROG_NP;
|
||||
info->errno_location = thread == _thr_initial ? &__libsys_errno :
|
||||
&thread->error;
|
||||
info->tcb = thread->tcb;
|
||||
if (thread->name != NULL)
|
||||
strlcpy(info->name, thread->name, sizeof(info->name));
|
||||
else
|
||||
info->name[0] = '\0';
|
||||
info->exterr = &thread->uexterr;
|
||||
THR_THREAD_UNLOCK(curthread, thread);
|
||||
}
|
||||
|
||||
int
|
||||
pthread_query_np(pthread_t thread, struct pthread_info_np *info, size_t bufsz)
|
||||
{
|
||||
struct pthread *curthread;
|
||||
struct pthread_info_np pi;
|
||||
int ret;
|
||||
|
||||
if (_thr_initial == NULL)
|
||||
return (EAGAIN);
|
||||
|
||||
curthread = _get_curthread();
|
||||
if (thread != curthread) {
|
||||
ret = _thr_find_thread(curthread, thread, 1);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
}
|
||||
pthread_getinfo(curthread, thread, thread != curthread, &pi);
|
||||
memcpy(info, &pi, MIN(sizeof(pi), bufsz));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pthread_query_all_np(struct pthread_info_np *info, size_t *bufsz)
|
||||
{
|
||||
struct pthread *curthread, *thr;
|
||||
size_t cnt, i;
|
||||
int res;
|
||||
|
||||
if (_thr_initial == NULL) {
|
||||
/* Exactly one thread exists. */
|
||||
*bufsz = sizeof(*info);
|
||||
return (EAGAIN);
|
||||
}
|
||||
|
||||
curthread = _get_curthread();
|
||||
res = 0;
|
||||
i = 0;
|
||||
cnt = *bufsz / sizeof(*info);
|
||||
THREAD_LIST_RDLOCK(curthread);
|
||||
TAILQ_FOREACH(thr, &_thread_list, tle) {
|
||||
if (i + 1 > cnt)
|
||||
res = ENOMEM;
|
||||
/*
|
||||
* Continue the loop even after the buffer is filled,
|
||||
* to report required buffer size.
|
||||
*/
|
||||
if (res == 0)
|
||||
pthread_getinfo(curthread, thr, false, &info[i]);
|
||||
i++;
|
||||
}
|
||||
THREAD_LIST_UNLOCK(curthread);
|
||||
|
||||
*bufsz = i * sizeof(*info);
|
||||
return (res);
|
||||
}
|
||||
Reference in new issue
Block a user