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