1 martin 1.19 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.20 //
|
3 martin 1.19 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.20 //
|
10 martin 1.19 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.20 //
|
17 martin 1.19 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.20 //
|
20 martin 1.19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.20 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.20 //
|
28 martin 1.19 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #ifndef Pegasus_Threads_h
33 #define Pegasus_Threads_h
34
35 #include <cstring>
|
36 mike 1.5 #include <cstdio>
37 #include <cstring>
|
38 mike 1.2 #include <Pegasus/Common/Config.h>
39 #include <Pegasus/Common/Linkage.h>
40
41 // ATTN: can we consolidate these someplace?
42
|
43 marek 1.15 #ifdef PEGASUS_OS_ZOS
44 # include <sched.h>
45 #endif
|
46 mike 1.2 #if defined(PEGASUS_HAVE_PTHREADS)
47 # include <pthread.h>
48 # include <errno.h>
49 # include <sys/time.h>
50 #elif defined(PEGASUS_HAVE_WINDOWS_THREADS)
51 # include <windows.h>
52 # include <process.h>
53 #else
54 # error "<Pegasus/Common/Threads.h>: not implemented"
55 #endif
56
|
57 karl 1.17 #if defined(PEGASUS_OS_SOLARIS)
58 # include <string.h>
59 # include <stdio.h>
60 #endif
61
|
62 mike 1.2 PEGASUS_NAMESPACE_BEGIN
63
64 //==============================================================================
65 //
66 // PEGASUS_THREAD_CDECL
67 //
68 //==============================================================================
69
|
70 a.dunfey 1.12 #if defined(PEGASUS_OS_TYPE_WINDOWS)
|
71 mike 1.2 # define PEGASUS_THREAD_CDECL __stdcall
72 #else
73 # define PEGASUS_THREAD_CDECL /* empty */
74 #endif
75
76 //==============================================================================
77 //
|
78 mike 1.4 // ThreadId
79 //
80 //==============================================================================
81
82 struct ThreadId
83 {
|
84 kumpf 1.10 // The character representation of a uint64 requires 22 bytes including the
|
85 mike 1.4 // null terminator.
86 char buffer[22];
87 };
88
89 //==============================================================================
90 //
|
91 mike 1.2 // ThreadType
92 //
93 //==============================================================================
94
95 #if defined(PEGASUS_HAVE_PTHREADS)
96 struct ThreadType
97 {
98 ThreadType()
99 {
|
100 mike 1.3 memset(&thread, 0, sizeof(thread));
|
101 mike 1.2 }
102
|
103 mike 1.3 ThreadType(pthread_t thread_) : thread(thread_)
|
104 mike 1.2 {
105 }
106
|
107 mike 1.3 pthread_t thread;
108 };
|
109 mike 1.2 #endif /* PEGASUS_HAVE_PTHREADS */
110
111 #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
112 struct ThreadType
113 {
|
114 kumpf 1.10 ThreadType() : handle(NULL)
115 {
|
116 mike 1.3 }
117
|
118 mike 1.2 HANDLE handle;
119 };
120 #endif /* PEGASUS_HAVE_WINDOWS_THREADS */
121
122 //==============================================================================
123 //
124 // ThreadReturnType
125 //
126 //==============================================================================
127
128 #if defined(PEGASUS_HAVE_PTHREADS)
129 typedef void* ThreadReturnType;
130 #endif
131
132 #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
133 typedef unsigned ThreadReturnType;
134 #endif
135
136 //==============================================================================
137 //
138 // ThreadHandle
139 mike 1.2 //
140 //==============================================================================
141
142 #if defined(PEGASUS_HAVE_PTHREADS)
143 struct ThreadHandle
144 {
145 ThreadType thid;
146 };
147 #elif defined(PEGASUS_HAVE_WINDOWS_THREADS)
148 struct ThreadHandle
149 {
150 ThreadType thid;
151 };
152 #endif
153
154 //==============================================================================
155 //
156 // Threads
157 //
158 //==============================================================================
159
160 mike 1.2 class PEGASUS_COMMON_LINKAGE Threads
161 {
162 public:
163
164 enum Type { DETACHED, JOINABLE };
165
166 static int create(
|
167 kumpf 1.10 ThreadType& thread,
|
168 mike 1.2 Type type,
|
169 kumpf 1.10 void* (*start)(void*),
|
170 mike 1.2 void* arg);
171
172 static ThreadType self();
173
174 static bool equal(ThreadType x, ThreadType y);
175
176 static void exit(ThreadReturnType rc);
177
178 static void yield();
179
180 static void sleep(int msec);
181
|
182 mike 1.3 static ThreadId id(const ThreadType& x = Threads::self());
183
184 static bool null(const ThreadType& x = Threads::self());
|
185 mike 1.2
186 static void clear(ThreadType& x);
187 };
188
189 //==============================================================================
190 //
191 // POSIX Threads Implementation
192 //
193 //==============================================================================
194
195 #if defined(PEGASUS_HAVE_PTHREADS)
196
|
197 kumpf 1.10 inline bool Threads::equal(ThreadType x, ThreadType y)
198 {
|
199 mike 1.3 return pthread_equal(x.thread, y.thread);
|
200 mike 1.2 }
201
202 inline void Threads::exit(ThreadReturnType rc)
203 {
|
204 marek 1.9 // NOTE: pthread_exit exhibits unusual behavior on RHEL 3 U2, as
205 // documented in Bugzilla 3836. Where feasible, it may be advantageous
206 // to avoid using this function.
|
207 mike 1.2 pthread_exit(rc);
208 }
209
210 inline void Threads::yield()
211 {
|
212 marek 1.16 #ifdef PEGASUS_OS_LINUX
213 pthread_yield();
214 #else
|
215 mike 1.2 sched_yield();
216 #endif
217 }
218
|
219 mike 1.3 inline ThreadId Threads::id(const ThreadType& x)
|
220 mike 1.2 {
|
221 karl 1.17 ThreadId tid = { { 0 } };
|
222 mike 1.3
|
223 r.kieninger 1.18 #if defined(PEGASUS_OS_ZOS)
|
224 mike 1.3 const char* s = x.thread.__;
|
225 kumpf 1.10 sprintf(tid.buffer, "%X%X%X%X%X%X%X%X",
|
226 mike 1.3 s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
227 #else
|
228 kumpf 1.10 sprintf(tid.buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u",
|
229 mike 1.6 Uint64(x.thread));
|
230 mike 1.3 #endif
231
232 return tid;
233 }
234
235 inline bool Threads::null(const ThreadType& x)
236 {
|
237 r.kieninger 1.18 #if defined(PEGASUS_OS_ZOS)
|
238 mike 1.3 Uint64 tmp;
|
239 marek 1.7 memcpy(&tmp, x.thread.__, sizeof(Uint64));
|
240 mike 1.3 return tmp == 0;
241 #else
242 return x.thread == 0;
243 #endif
|
244 mike 1.2 }
245
246 inline void Threads::clear(ThreadType& x)
247 {
248 memset(&x, 0, sizeof(x));
249 }
250
251 #endif /* defined(PEGASUS_HAVE_PTHREADS) */
252
253 //==============================================================================
254 //
255 // Windows Threads Implementation
256 //
257 //==============================================================================
258
259 #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
260
|
261 kumpf 1.10 inline ThreadType Threads::self()
|
262 mike 1.2 {
263 ThreadType tt;
|
264 mike 1.5 tt.handle = GetCurrentThread();
|
265 mike 1.2 return tt;
266 }
267
|
268 kumpf 1.10 inline bool Threads::equal(ThreadType x, ThreadType y)
|
269 mike 1.2 {
270 return x.handle == y.handle;
271 }
272
273 inline void Threads::exit(ThreadReturnType rc)
274 {
275 _endthreadex(rc);
276 }
277
278 inline void Threads::yield()
279 {
280 Sleep(0);
281 }
282
|
283 mike 1.3 inline ThreadId Threads::id(const ThreadType& x)
284 {
285 ThreadId tmp;
286
|
287 kumpf 1.10 sprintf(tmp.buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u",
|
288 mike 1.5 Uint64(x.handle));
|
289 mike 1.3
290 return tmp;
291 }
292
293 inline bool Threads::null(const ThreadType& x)
|
294 mike 1.2 {
|
295 mike 1.3 return x.handle == NULL;
|
296 mike 1.2 }
297
298 inline void Threads::clear(ThreadType& x)
299 {
300 x.handle = NULL;
301 }
302
303 #endif /* defined(PEGASUS_HAVE_WINDOWS_THREADS) */
304
305 PEGASUS_NAMESPACE_END
306
307 #endif /* Pegasus_Threads_h */
|