Discussion:
Write a version for pthread_get_name_np
Willem Jan Withagen
2018-08-12 20:33:06 UTC
Permalink
Hi,

For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
Tried some the the procstat code I would come up with:

int pthread_get_name_np(pthread_t *thread,
                        char *name, size_t len){
    struct procstat *procstat;
    int pid = getpid();
    unsigned int count, i;
    struct kinfo_proc *kip, *kipp;

    procstat = procstat_open_sysctl();
    kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
            pid, &count);
    for (i = 0; i < count; i++) {
        kipp = &kip[i];
        printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread, thread,
kipp->ki_tid, kipp->ki_tid);
        if (thread == kipp->ki_tid) {
            kinfo_proc_thread_name(kipp, name, len);
        }
    }
    return 0;
}

Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
    lwpid_t ki_tid;                 /* XXXKSE thread id */

What do I need to translate one tid into the other so I can really
compare them?

Thanx,
--WjW
Konstantin Belousov
2018-08-12 20:58:35 UTC
Permalink
Post by Willem Jan Withagen
Hi,
For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
int pthread_get_name_np(pthread_t *thread,
                        char *name, size_t len){
    struct procstat *procstat;
    int pid = getpid();
    unsigned int count, i;
    struct kinfo_proc *kip, *kipp;
    procstat = procstat_open_sysctl();
    kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
            pid, &count);
    for (i = 0; i < count; i++) {
        kipp = &kip[i];
        printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread, thread,
kipp->ki_tid, kipp->ki_tid);
        if (thread == kipp->ki_tid) {
            kinfo_proc_thread_name(kipp, name, len);
        }
    }
    return 0;
}
Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
    lwpid_t ki_tid;                 /* XXXKSE thread id */
What do I need to translate one tid into the other so I can really
compare them?
You need to cast pthread_t * to struct thread *, this is an internal
libthr structure which represents the thread in userspace. The
structure field tid gives you the tid you want to pass to sysctl.
Willem Jan Withagen
2018-08-12 22:01:03 UTC
Permalink
Post by Konstantin Belousov
Post by Willem Jan Withagen
Hi,
For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
int pthread_get_name_np(pthread_t *thread,
                        char *name, size_t len){
    struct procstat *procstat;
    int pid = getpid();
    unsigned int count, i;
    struct kinfo_proc *kip, *kipp;
    procstat = procstat_open_sysctl();
    kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
            pid, &count);
    for (i = 0; i < count; i++) {
        kipp = &kip[i];
        printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread, thread,
kipp->ki_tid, kipp->ki_tid);
        if (thread == kipp->ki_tid) {
            kinfo_proc_thread_name(kipp, name, len);
        }
    }
    return 0;
}
Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
    lwpid_t ki_tid;                 /* XXXKSE thread id */
What do I need to translate one tid into the other so I can really
compare them?
You need to cast pthread_t * to struct thread *, this is an internal
libthr structure which represents the thread in userspace. The
structure field tid gives you the tid you want to pass to sysctl.
mmmm,

I'm afraid I'm not quit able to followup on your answer.

Trying to find what to include to be able to cast this, I can only find
a small bit defined in /usr/src/lib/libthr/thread/thr_private.h.
/*
* lwpid_t is 32bit but kernel thr API exports tid as long type
* to preserve the ABI for M:N model in very early date (r131431).
*/
#define TID(thread) ((uint32_t) ((thread)->tid))

But that I cannot just "include" that file without a lot of mess, and
then still it does not compile.

So could you point me to where this private part of struct thread is
hidding?

Thanx,
--WjW
Konstantin Belousov
2018-08-12 22:57:26 UTC
Permalink
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Hi,
For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
int pthread_get_name_np(pthread_t *thread,
                        char *name, size_t len){
    struct procstat *procstat;
    int pid = getpid();
    unsigned int count, i;
    struct kinfo_proc *kip, *kipp;
    procstat = procstat_open_sysctl();
    kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
            pid, &count);
    for (i = 0; i < count; i++) {
        kipp = &kip[i];
        printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread, thread,
kipp->ki_tid, kipp->ki_tid);
        if (thread == kipp->ki_tid) {
            kinfo_proc_thread_name(kipp, name, len);
        }
    }
    return 0;
}
Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
    lwpid_t ki_tid;                 /* XXXKSE thread id */
What do I need to translate one tid into the other so I can really
compare them?
You need to cast pthread_t * to struct thread *, this is an internal
libthr structure which represents the thread in userspace. The
structure field tid gives you the tid you want to pass to sysctl.
mmmm,
I'm afraid I'm not quit able to followup on your answer.
Trying to find what to include to be able to cast this, I can only find
a small bit defined in /usr/src/lib/libthr/thread/thr_private.h.
/*
* lwpid_t is 32bit but kernel thr API exports tid as long type
* to preserve the ABI for M:N model in very early date (r131431).
*/
#define TID(thread) ((uint32_t) ((thread)->tid))
But that I cannot just "include" that file without a lot of mess, and
then still it does not compile.
So could you point me to where this private part of struct thread is
hidding?
I do not understand your confusion. The thr_private.h header is only
for use by libthr, the FreeBSD threading library implementation. The
function that you are trying to implement, requires understanding of the
libthr internals and can only be implemented as part of libthr.

Any other attempt to translate libthr handle for thread into tid needs
same access to the struct pthread.
Willem Jan Withagen
2018-08-12 23:36:28 UTC
Permalink
Post by Konstantin Belousov
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Hi,
For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
int pthread_get_name_np(pthread_t *thread,
                        char *name, size_t len){
    struct procstat *procstat;
    int pid = getpid();
    unsigned int count, i;
    struct kinfo_proc *kip, *kipp;
    procstat = procstat_open_sysctl();
    kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
            pid, &count);
    for (i = 0; i < count; i++) {
        kipp = &kip[i];
        printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread, thread,
kipp->ki_tid, kipp->ki_tid);
        if (thread == kipp->ki_tid) {
            kinfo_proc_thread_name(kipp, name, len);
        }
    }
    return 0;
}
Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
    lwpid_t ki_tid;                 /* XXXKSE thread id */
What do I need to translate one tid into the other so I can really
compare them?
You need to cast pthread_t * to struct thread *, this is an internal
libthr structure which represents the thread in userspace. The
structure field tid gives you the tid you want to pass to sysctl.
mmmm,
I'm afraid I'm not quit able to followup on your answer.
Trying to find what to include to be able to cast this, I can only find
a small bit defined in /usr/src/lib/libthr/thread/thr_private.h.
/*
* lwpid_t is 32bit but kernel thr API exports tid as long type
* to preserve the ABI for M:N model in very early date (r131431).
*/
#define TID(thread) ((uint32_t) ((thread)->tid))
But that I cannot just "include" that file without a lot of mess, and
then still it does not compile.
So could you point me to where this private part of struct thread is
hidding?
I do not understand your confusion. The thr_private.h header is only
for use by libthr, the FreeBSD threading library implementation. The
function that you are trying to implement, requires understanding of the
libthr internals and can only be implemented as part of libthr.
Any other attempt to translate libthr handle for thread into tid needs
same access to the struct pthread.
Oke,

I don't have more knowledge of (p)threads than just how to use it.
I was trying to do this as a piece of code in the compat.cc of my ceph port.

But trying to reread what you write is boils down to: there is no way to
link a value returned by (struct pthread *)pthread_self() to the kd_tid
value that can be found in the (struct kinfo_proc *) describing that
same thread.

And even though (struct thread *) has a field:
lwpid_t td_tid; /* (b) Thread ID. */
that field seems to be stuck at value td_tid = 32767 every time I look
at it with gdb.

So it is a pity that this is not going to work this way.

--WjW
Konstantin Belousov
2018-08-12 23:48:00 UTC
Permalink
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Hi,
For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
int pthread_get_name_np(pthread_t *thread,
                        char *name, size_t len){
    struct procstat *procstat;
    int pid = getpid();
    unsigned int count, i;
    struct kinfo_proc *kip, *kipp;
    procstat = procstat_open_sysctl();
    kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
            pid, &count);
    for (i = 0; i < count; i++) {
        kipp = &kip[i];
        printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread, thread,
kipp->ki_tid, kipp->ki_tid);
        if (thread == kipp->ki_tid) {
            kinfo_proc_thread_name(kipp, name, len);
        }
    }
    return 0;
}
Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
    lwpid_t ki_tid;                 /* XXXKSE thread id */
What do I need to translate one tid into the other so I can really
compare them?
You need to cast pthread_t * to struct thread *, this is an internal
libthr structure which represents the thread in userspace. The
structure field tid gives you the tid you want to pass to sysctl.
mmmm,
I'm afraid I'm not quit able to followup on your answer.
Trying to find what to include to be able to cast this, I can only find
a small bit defined in /usr/src/lib/libthr/thread/thr_private.h.
/*
* lwpid_t is 32bit but kernel thr API exports tid as long type
* to preserve the ABI for M:N model in very early date (r131431).
*/
#define TID(thread) ((uint32_t) ((thread)->tid))
But that I cannot just "include" that file without a lot of mess, and
then still it does not compile.
So could you point me to where this private part of struct thread is
hidding?
I do not understand your confusion. The thr_private.h header is only
for use by libthr, the FreeBSD threading library implementation. The
function that you are trying to implement, requires understanding of the
libthr internals and can only be implemented as part of libthr.
Any other attempt to translate libthr handle for thread into tid needs
same access to the struct pthread.
Oke,
I don't have more knowledge of (p)threads than just how to use it.
I was trying to do this as a piece of code in the compat.cc of my ceph port.
But trying to reread what you write is boils down to: there is no way to
link a value returned by (struct pthread *)pthread_self() to the kd_tid
value that can be found in the (struct kinfo_proc *) describing that
same thread.
No, this is not what I said.

I am claiming that this functionality must be implemented in libthr.
So if you want this function, it needs to be added to libthr, and it is
quite trivial to do.

You can code it, or you might provide (draft of the) man page, and I
will code it according to the spec.
Post by Willem Jan Withagen
lwpid_t td_tid; /* (b) Thread ID. */
that field seems to be stuck at value td_tid = 32767 every time I look
at it with gdb.
So it is a pity that this is not going to work this way.
--WjW
Yuri Pankov
2018-08-13 00:24:03 UTC
Permalink
Post by Konstantin Belousov
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Hi,
For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
int pthread_get_name_np(pthread_t *thread,
ššššššššššššššššššššššš char *name, size_t len){
ššš struct procstat *procstat;
ššš int pid = getpid();
ššš unsigned int count, i;
ššš struct kinfo_proc *kip, *kipp;
ššš procstat = procstat_open_sysctl();
ššš kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
ššššššššššš pid, &count);
ššš for (i = 0; i < count; i++) {
ššš ššš kipp = &kip[i];
ššš ššš printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread, thread,
kipp->ki_tid, kipp->ki_tid);
ššš ššš if (thread == kipp->ki_tid) {
ššš ššš ššš kinfo_proc_thread_name(kipp, name, len);
ššš ššš }
ššš }
ššš return 0;
}
Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
ššš lwpid_t ki_tid;šššššššššššššššš /* XXXKSE thread id */
What do I need to translate one tid into the other so I can really
compare them?
You need to cast pthread_t * to struct thread *, this is an internal
libthr structure which represents the thread in userspace. The
structure field tid gives you the tid you want to pass to sysctl.
mmmm,
I'm afraid I'm not quit able to followup on your answer.
Trying to find what to include to be able to cast this, I can only find
a small bit defined in /usr/src/lib/libthr/thread/thr_private.h.
/*
* lwpid_t is 32bit but kernel thr API exports tid as long type
* to preserve the ABI for M:N model in very early date (r131431).
*/
#define TID(thread) ((uint32_t) ((thread)->tid))
But that I cannot just "include" that file without a lot of mess, and
then still it does not compile.
So could you point me to where this private part of struct thread is
hidding?
I do not understand your confusion. The thr_private.h header is only
for use by libthr, the FreeBSD threading library implementation. The
function that you are trying to implement, requires understanding of the
libthr internals and can only be implemented as part of libthr.
Any other attempt to translate libthr handle for thread into tid needs
same access to the struct pthread.
Oke,
I don't have more knowledge of (p)threads than just how to use it.
I was trying to do this as a piece of code in the compat.cc of my ceph port.
But trying to reread what you write is boils down to: there is no way to
link a value returned by (struct pthread *)pthread_self() to the kd_tid
value that can be found in the (struct kinfo_proc *) describing that
same thread.
No, this is not what I said.
I am claiming that this functionality must be implemented in libthr.
So if you want this function, it needs to be added to libthr, and it is
quite trivial to do.
You can code it, or you might provide (draft of the) man page, and I
will code it according to the spec.
How about the attached patch for man page part?
Post by Konstantin Belousov
Post by Willem Jan Withagen
lwpid_t td_tid; /* (b) Thread ID. */
that field seems to be stuck at value td_tid = 32767 every time I look
at it with gdb.
So it is a pity that this is not going to work this way.
Willem Jan Withagen
2018-08-13 08:16:30 UTC
Permalink
Post by Yuri Pankov
Post by Konstantin Belousov
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Post by Konstantin Belousov
Post by Willem Jan Withagen
Hi,
For some porting I'm trying to write a pthread_get_name_np(), but
I have run into a snag....
int pthread_get_name_np(pthread_t *thread,
                            char *name, size_t len){
        struct procstat *procstat;
        int pid = getpid();
        unsigned int count, i;
        struct kinfo_proc *kip, *kipp;
        procstat = procstat_open_sysctl();
        kip = procstat_getprocs(procstat, KERN_PROC_PID |
KERN_PROC_INC_THREAD,
                pid, &count);
        for (i = 0; i < count; i++) {
            kipp = &kip[i];
            printf("thread: %ld(0x%lx), %ld(0x%lx)\n", thread,
thread,
kipp->ki_tid, kipp->ki_tid);
            if (thread == kipp->ki_tid) {
                kinfo_proc_thread_name(kipp, name, len);
            }
        }
        return 0;
}
Problem only is that the TID value in what procstat_getprocs returns in
ki_tid is nowhere near
what pthread_self() returns.
But both manual page and the include file describe the value as Thread ID.
Only in sys/user.h the type is
        lwpid_t ki_tid;                 /* XXXKSE thread id */
What do I need to translate one tid into the other so I can really
compare them?
You need to cast pthread_t * to struct thread *, this is an internal
libthr structure which represents the thread in userspace.  The
structure field tid gives you the tid you want to pass to sysctl.
mmmm,
I'm afraid I'm not quit able to followup on your answer.
Trying to find what to include to be able to cast this, I can only find
a small bit defined in /usr/src/lib/libthr/thread/thr_private.h.
/*
    * lwpid_t is 32bit but kernel thr API exports tid as long type
    * to preserve the ABI for M:N model in very early date (r131431).
    */
#define TID(thread)     ((uint32_t) ((thread)->tid))
But that I cannot just "include" that file without a lot of mess, and
then still it does not compile.
So could you point me to where this private part of struct thread is
hidding?
I do not understand your confusion. The thr_private.h header is only
for use by libthr, the FreeBSD threading library implementation. The
function that you are trying to implement, requires understanding of the
libthr internals and can only be implemented as part of libthr.
Any other attempt to translate libthr handle for thread into tid needs
same access to the struct pthread.
Oke,
I don't have more knowledge of (p)threads than just how to use it.
I was trying to do this as a piece of code in the compat.cc of my ceph port.
But trying to reread what you write is boils down to: there is no way to
link a value returned by (struct pthread *)pthread_self() to the kd_tid
value that can be found in the (struct kinfo_proc *) describing that
same thread.
No, this is not what I said.
I am claiming that this functionality must be implemented in libthr.
So if you want this function, it needs to be added to libthr, and it is
quite trivial to do.
You can code it, or you might provide (draft of the) man page, and I
will code it according to the spec.
How about the attached patch for man page part?
Thanx,

I guess that'll work.

Although I was following the procstat way and when there was no name set
we get a '-'. But if Konstatin is going to write it, it is his prerogative.
And I would expect it to be equivalent partner of thr_{set,get}_name as
well. But that could be added later in the man page.

--WjW
Konstantin Belousov
2018-08-13 15:05:23 UTC
Permalink
Post by Willem Jan Withagen
I guess that'll work.
Although I was following the procstat way and when there was no name set
we get a '-'. But if Konstatin is going to write it, it is his prerogative.
And I would expect it to be equivalent partner of thr_{set,get}_name as
well. But that could be added later in the man page.
There is no thr_get_name(2).

The implementation is available at https://reviews.freebsd.org/D16702.
I do not like void return types for both pthread_get_name_np() and
pthread_set_name_np().

Loading...