Reputation: 635
A thread has a mutex of type pthread_mutex_t
locked for itself. Another thread wants to know the thread id of the thread holding this locked mutex.
There are two types of thread ids as I understand. The POSIX/pthread thread id, returned by pthread_self()
, and the linux thread id returned by the system call gettid()
. These two are independent and have no relation, AFAIK (please correct me If I am wrong).
There is a field in the structure pthread_mutex_t
, int __owner
which stores the thread id of the thread that current holds the lock. This field can be accessed by,
pthread_mutex_t mutex;
int tid;
tid = mutex.__data.__owner;
As described here - Is it possible to determine the thread holding a mutex?.
This __owner
field has the linux system thread id (as would be returned by gettid()
) and not the POSIX/pthread thread id (as would be returned by pthread_self()
) .
I want to compare whether the current scheduled thread is owning the mutex or not. So, I should be comparing pthread_self()
with the __owner
value.
I could use gettid()
instead of pthread_self()
, but I am restricted to use pthread_self()
only. (some portability features).
Is there any way to correctly determine the thread id of the locked mutex which would return pthread_t
and not the system thread id?
I will appreciate any help, Thanks!
Regards,
Yusuf Husainy.
Upvotes: 3
Views: 5146
Reputation: 1
How about using the stack trace for this? For example, if I use the pstack command on my multi-threaded app with a locked mutex I see the following:
# pstack <PID>
Thread 3 (Thread 0x7fb94a4f4700 (LWP 25157)):
#0 0x00000034a7e0e264 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00000034a7e09508 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x00000034a7e093d7 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x000000000040af63 in read_from_pbx_loop(void*) ()
#4 0x00000034a7e079d1 in start_thread () from /lib64/libpthread.so.0
#5 0x00000034a7ae88fd in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7fb949cf3700 (LWP 25158)):
#0 0x00000034a7aaca3d in nanosleep () from /lib64/libc.so.6
#1 0x00000034a7ae1be4 in usleep () from /lib64/libc.so.6
#2 0x00000000004074f0 in read_from_agent_loop(void*) ()
#3 0x00000034a7e079d1 in start_thread () from /lib64/libpthread.so.0
#4 0x00000034a7ae88fd in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7fb94a4f6720 (LWP 25156)):
#0 0x00000034a7aaca3d in nanosleep () from /lib64/libc.so.6
#1 0x00000034a7ae1be4 in usleep () from /lib64/libc.so.6
#2 0x000000000040c600 in main ()
So you can get a stack trace of your thread and use some simple heuristic checks to see if the last step of the stack trace for your thread is __lll_lock_wait
.
Upvotes: 0
Reputation:
1)
These two are independent and have no relation, AFAIK (please correct me If I am wrong).
That is correct. from man pthread_self
:
The thread ID returned by pthread_self() is not the same thing as the kernel thread ID returned by a call to gettid(2).
2)
so, I should be comparing pthread_self() with the __owner value
That is incorrect, man pthread_self
:
Thread identifiers should be considered opaque: any attempt to use a thread ID other than in pthreads calls is non-portable and can lead to unspecified results.
3)
Is there any way to correctly determine the thread id of the locked mutex which would return pthread_t and not the system thread id?
I guess, no. pthread_mutex_t has the field int __owner;
and does not have any field like pthread_owner
that would contain pthread_t of the thread:
/* Data structures for mutex handling. The structure of the attribute
type is not exposed on purpose. */
typedef union
{
struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
int __owner;
#if __WORDSIZE == 64
unsigned int __nusers;
#endif
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
#if __WORDSIZE == 64
int __spins;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
#else
unsigned int __nusers;
__extension__ union
{
int __spins;
__pthread_slist_t __list;
};
#endif
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
} pthread_mutex_t;
Upvotes: 2