xref: /unit/src/nxt_thread_id.h (revision 2084:7d479274f334)
10Sigor@sysoev.ru 
20Sigor@sysoev.ru /*
30Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
40Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
50Sigor@sysoev.ru  */
60Sigor@sysoev.ru 
70Sigor@sysoev.ru #ifndef _NXT_UNIX_THREAD_ID_H_INCLUDED_
80Sigor@sysoev.ru #define _NXT_UNIX_THREAD_ID_H_INCLUDED_
90Sigor@sysoev.ru 
100Sigor@sysoev.ru 
110Sigor@sysoev.ru #if (NXT_LINUX)
120Sigor@sysoev.ru 
13735Sigor@sysoev.ru /*
14735Sigor@sysoev.ru  * Linux thread id is a pid of thread created by clone(2),
15735Sigor@sysoev.ru  * glibc does not provide a wrapper for gettid().
16735Sigor@sysoev.ru  */
17735Sigor@sysoev.ru 
18735Sigor@sysoev.ru typedef pid_t  nxt_tid_t;
19735Sigor@sysoev.ru 
20735Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)21735Sigor@sysoev.ru nxt_thread_get_tid(void)
22735Sigor@sysoev.ru {
23735Sigor@sysoev.ru     return syscall(SYS_gettid);
24735Sigor@sysoev.ru }
250Sigor@sysoev.ru 
260Sigor@sysoev.ru #elif (NXT_FREEBSD)
270Sigor@sysoev.ru 
28735Sigor@sysoev.ru /*
29735Sigor@sysoev.ru  * FreeBSD 9.0 provides pthread_getthreadid_np(), here is its
30735Sigor@sysoev.ru  * emulation.  Kernel thread id is the first field of struct pthread.
31735Sigor@sysoev.ru  * Although kernel exports a thread id as long type, lwpid_t is 32bit.
32735Sigor@sysoev.ru  * Thread id is a number above 100,000.
33735Sigor@sysoev.ru  */
34735Sigor@sysoev.ru 
35735Sigor@sysoev.ru typedef uint32_t  nxt_tid_t;
36735Sigor@sysoev.ru 
37735Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)38735Sigor@sysoev.ru nxt_thread_get_tid(void)
39735Sigor@sysoev.ru {
40735Sigor@sysoev.ru     return (uint32_t) (*(long *) pthread_self());
41735Sigor@sysoev.ru }
420Sigor@sysoev.ru 
430Sigor@sysoev.ru #elif (NXT_SOLARIS)
440Sigor@sysoev.ru 
45735Sigor@sysoev.ru /* Solaris pthread_t are numbers starting with 1. */
46735Sigor@sysoev.ru 
470Sigor@sysoev.ru typedef pthread_t  nxt_tid_t;
480Sigor@sysoev.ru 
49735Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)50735Sigor@sysoev.ru nxt_thread_get_tid(void)
51735Sigor@sysoev.ru {
52735Sigor@sysoev.ru     return pthread_self();
53735Sigor@sysoev.ru }
54735Sigor@sysoev.ru 
550Sigor@sysoev.ru #elif (NXT_MACOSX)
560Sigor@sysoev.ru 
57735Sigor@sysoev.ru /*
58735Sigor@sysoev.ru  * MacOSX thread has two thread ids:
59735Sigor@sysoev.ru  *
60735Sigor@sysoev.ru  * 1) MacOSX 10.6 (Snow Leoprad) has pthread_threadid_np() returning
61735Sigor@sysoev.ru  *    an uint64_t value, which is obtained using the __thread_selfid()
62735Sigor@sysoev.ru  *    syscall.  It is a number above 300,000.
63735Sigor@sysoev.ru  */
64735Sigor@sysoev.ru 
65735Sigor@sysoev.ru typedef uint64_t  nxt_tid_t;
66735Sigor@sysoev.ru 
67735Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)68735Sigor@sysoev.ru nxt_thread_get_tid(void)
69735Sigor@sysoev.ru {
70735Sigor@sysoev.ru     uint64_t  tid;
71735Sigor@sysoev.ru 
72735Sigor@sysoev.ru     (void) pthread_threadid_np(NULL, &tid);
73735Sigor@sysoev.ru     return tid;
74735Sigor@sysoev.ru }
75735Sigor@sysoev.ru 
76735Sigor@sysoev.ru /*
77735Sigor@sysoev.ru  * 2) Kernel thread mach_port_t returned by pthread_mach_thread_np().
78735Sigor@sysoev.ru  *    It is a number in range 100-100,000.
79735Sigor@sysoev.ru  *
80735Sigor@sysoev.ru  * return pthread_mach_thread_np(pthread_self());
81735Sigor@sysoev.ru  */
820Sigor@sysoev.ru 
83736Sigor@sysoev.ru #elif (NXT_OPENBSD)
84736Sigor@sysoev.ru 
85736Sigor@sysoev.ru typedef pid_t  nxt_tid_t;
86736Sigor@sysoev.ru 
87736Sigor@sysoev.ru /* OpenBSD 3.9 getthrid(). */
88736Sigor@sysoev.ru 
89736Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)90736Sigor@sysoev.ru nxt_thread_get_tid(void)
91736Sigor@sysoev.ru {
92736Sigor@sysoev.ru     return getthrid();
93736Sigor@sysoev.ru }
94736Sigor@sysoev.ru 
950Sigor@sysoev.ru #elif (NXT_AIX)
960Sigor@sysoev.ru 
97735Sigor@sysoev.ru /*
98735Sigor@sysoev.ru  * pthread_self() in main thread returns 1.
99735Sigor@sysoev.ru  * pthread_self() in other threads returns 258, 515, etc.
100735Sigor@sysoev.ru  *
101735Sigor@sysoev.ru  * pthread_getthrds_np(PTHRDSINFO_QUERY_TID) returns kernel tid
102735Sigor@sysoev.ru  * shown in "ps -ef -m -o THREAD" output.
103735Sigor@sysoev.ru  */
104735Sigor@sysoev.ru 
105735Sigor@sysoev.ru typedef tid_t  nxt_tid_t;
106735Sigor@sysoev.ru 
107735Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)108735Sigor@sysoev.ru nxt_thread_get_tid(void)
109735Sigor@sysoev.ru {
110735Sigor@sysoev.ru     int                  err, size;
111735Sigor@sysoev.ru     pthread_t            pt;
112735Sigor@sysoev.ru     struct __pthrdsinfo  ti;
113735Sigor@sysoev.ru 
114735Sigor@sysoev.ru     size = 0;
115735Sigor@sysoev.ru     pt = pthread_self();
116735Sigor@sysoev.ru 
117735Sigor@sysoev.ru     err = pthread_getthrds_np(&pt, PTHRDSINFO_QUERY_TID, &ti,
118735Sigor@sysoev.ru                             sizeof(struct __pthrdsinfo), NULL, size);
119735Sigor@sysoev.ru 
120735Sigor@sysoev.ru     if (nxt_fast_path(err == 0)) {
121735Sigor@sysoev.ru         return ti.__pi_tid;
122735Sigor@sysoev.ru     }
123735Sigor@sysoev.ru 
124735Sigor@sysoev.ru     nxt_main_log_alert("pthread_getthrds_np(PTHRDSINFO_QUERY_TID) failed %E",
125735Sigor@sysoev.ru                        err);
126735Sigor@sysoev.ru     return 0;
127735Sigor@sysoev.ru }
128735Sigor@sysoev.ru 
129735Sigor@sysoev.ru /*
130735Sigor@sysoev.ru  * AIX pthread_getunique_np() returns thread unique number starting with 1.
131735Sigor@sysoev.ru  * OS/400 and i5/OS have pthread_getthreadid_np(), but AIX lacks their
132735Sigor@sysoev.ru  * counterpart.
133735Sigor@sysoev.ru  *
134735Sigor@sysoev.ru  *
135735Sigor@sysoev.ru  * int        tid;
136735Sigor@sysoev.ru  * pthread_t  pt;
137735Sigor@sysoev.ru  *
138735Sigor@sysoev.ru  * pt = pthread_self();
139735Sigor@sysoev.ru  * pthread_getunique_np(&pt, &tid);
140735Sigor@sysoev.ru  * return tid;
141735Sigor@sysoev.ru  */
1420Sigor@sysoev.ru 
1430Sigor@sysoev.ru #elif (NXT_HPUX)
1440Sigor@sysoev.ru 
145735Sigor@sysoev.ru /* HP-UX pthread_t are numbers starting with 1. */
146735Sigor@sysoev.ru 
1470Sigor@sysoev.ru typedef pthread_t  nxt_tid_t;
1480Sigor@sysoev.ru 
149735Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)150735Sigor@sysoev.ru nxt_thread_get_tid(void)
151735Sigor@sysoev.ru {
152735Sigor@sysoev.ru     return pthread_self();
153735Sigor@sysoev.ru }
154735Sigor@sysoev.ru 
1550Sigor@sysoev.ru #else
1560Sigor@sysoev.ru 
1570Sigor@sysoev.ru typedef pthread_t  nxt_tid_t;
1580Sigor@sysoev.ru 
159735Sigor@sysoev.ru nxt_inline nxt_tid_t
nxt_thread_get_tid(void)160735Sigor@sysoev.ru nxt_thread_get_tid(void)
161735Sigor@sysoev.ru {
162735Sigor@sysoev.ru     return pthread_self();
163735Sigor@sysoev.ru }
164735Sigor@sysoev.ru 
1650Sigor@sysoev.ru #endif
1660Sigor@sysoev.ru 
1670Sigor@sysoev.ru 
1680Sigor@sysoev.ru NXT_EXPORT nxt_tid_t nxt_thread_tid(nxt_thread_t *thr);
1690Sigor@sysoev.ru 
1700Sigor@sysoev.ru 
1710Sigor@sysoev.ru /*
1720Sigor@sysoev.ru  * On Linux pthread_t is unsigned long integer.
1730Sigor@sysoev.ru  * On FreeBSD, MacOSX, NetBSD, and OpenBSD pthread_t is pointer to a struct.
1740Sigor@sysoev.ru  * On Solaris and AIX pthread_t is unsigned integer.
1750Sigor@sysoev.ru  * On HP-UX pthread_t is int.
1760Sigor@sysoev.ru  * On Cygwin pthread_t is pointer to void.
1770Sigor@sysoev.ru  * On z/OS pthread_t is "struct { char __[0x08]; }".
1780Sigor@sysoev.ru  */
1790Sigor@sysoev.ru typedef pthread_t  nxt_thread_handle_t;
1800Sigor@sysoev.ru 
1810Sigor@sysoev.ru 
182*2084Salx.manpages@gmail.com #define nxt_thread_handle_clear(th)                                           \
1830Sigor@sysoev.ru     th = (pthread_t) 0
1840Sigor@sysoev.ru 
185*2084Salx.manpages@gmail.com #define nxt_thread_handle_equal(th0, th1)                                     \
1860Sigor@sysoev.ru     pthread_equal(th0, th1)
1870Sigor@sysoev.ru 
1880Sigor@sysoev.ru 
1890Sigor@sysoev.ru #endif /* _NXT_UNIX_THREAD_ID_H_INCLUDED_ */
190