(file) Return to Threads.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 mike  1.2 //%2006////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6           // IBM Corp.; EMC Corporation, The Open Group.
  7           // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12           // EMC Corporation; Symantec Corporation; The Open Group.
 13           //
 14           // Permission is hereby granted, free of charge, to any person obtaining a copy
 15           // of this software and associated documentation files (the "Software"), to
 16           // deal in the Software without restriction, including without limitation the
 17           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18           // sell copies of the Software, and to permit persons to whom the Software is
 19           // furnished to do so, subject to the following conditions:
 20           // 
 21           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29           //
 30           //==============================================================================
 31           //
 32           //%/////////////////////////////////////////////////////////////////////////////
 33           
 34           #ifndef Pegasus_Threads_h
 35           #define Pegasus_Threads_h
 36           
 37           #include <cstring>
 38 mike  1.5 #include <cstdio>
 39           #include <cstring>
 40 mike  1.2 #include <Pegasus/Common/Config.h>
 41           #include <Pegasus/Common/Linkage.h>
 42           
 43           // ATTN: can we consolidate these someplace?
 44           
 45 marek 1.15 #ifdef PEGASUS_OS_ZOS
 46            # include <sched.h>
 47            #endif
 48 mike  1.2  #if defined(PEGASUS_HAVE_PTHREADS)
 49            # include <pthread.h>
 50            # include <errno.h>
 51            # include <sys/time.h>
 52            #elif defined(PEGASUS_HAVE_WINDOWS_THREADS)
 53            # include <windows.h>
 54            # include <process.h>
 55            #else
 56            # error "<Pegasus/Common/Threads.h>: not implemented"
 57            #endif
 58            
 59 karl  1.17 #if defined(PEGASUS_OS_SOLARIS)
 60            # include <string.h>
 61            # include <stdio.h>
 62            #endif
 63            
 64 mike  1.2  PEGASUS_NAMESPACE_BEGIN
 65            
 66            //==============================================================================
 67            //
 68            // PEGASUS_THREAD_CDECL
 69            //
 70            //==============================================================================
 71            
 72 a.dunfey 1.12 #if defined(PEGASUS_OS_TYPE_WINDOWS)
 73 mike     1.2  # define PEGASUS_THREAD_CDECL __stdcall
 74               #else
 75               # define PEGASUS_THREAD_CDECL /* empty */
 76               #endif
 77               
 78               //==============================================================================
 79               //
 80 mike     1.4  // ThreadId
 81               //
 82               //==============================================================================
 83               
 84               struct ThreadId
 85               {
 86 kumpf    1.10     // The character representation of a uint64 requires 22 bytes including the
 87 mike     1.4      // null terminator.
 88                   char buffer[22];
 89               };
 90               
 91               //==============================================================================
 92               //
 93 mike     1.2  // ThreadType
 94               //
 95               //==============================================================================
 96               
 97               #if defined(PEGASUS_HAVE_PTHREADS)
 98               struct ThreadType
 99               {
100                   ThreadType()
101                   {
102 mike     1.3          memset(&thread, 0, sizeof(thread));
103 mike     1.2      }
104               
105 mike     1.3      ThreadType(pthread_t thread_) : thread(thread_)
106 mike     1.2      {
107                   }
108               
109 mike     1.3      pthread_t thread;
110               };
111 mike     1.2  #endif /* PEGASUS_HAVE_PTHREADS */
112               
113               #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
114               struct ThreadType
115               {
116 kumpf    1.10     ThreadType() : handle(NULL)
117                   {
118 mike     1.3      }
119               
120 mike     1.2      HANDLE handle;
121               };
122               #endif /* PEGASUS_HAVE_WINDOWS_THREADS */
123               
124               //==============================================================================
125               //
126               // ThreadReturnType
127               //
128               //==============================================================================
129               
130               #if defined(PEGASUS_HAVE_PTHREADS)
131               typedef void* ThreadReturnType;
132               #endif
133               
134               #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
135               typedef unsigned ThreadReturnType;
136               #endif
137               
138               //==============================================================================
139               //
140               // ThreadHandle
141 mike     1.2  //
142               //==============================================================================
143               
144               #if defined(PEGASUS_HAVE_PTHREADS)
145               struct ThreadHandle
146               {
147                   ThreadType thid;
148               };
149               #elif defined(PEGASUS_HAVE_WINDOWS_THREADS)
150               struct ThreadHandle
151               {
152                   ThreadType thid;
153               };
154               #endif
155               
156               //==============================================================================
157               //
158               // Threads
159               //
160               //==============================================================================
161               
162 mike     1.2  class PEGASUS_COMMON_LINKAGE Threads
163               {
164               public:
165               
166                   enum Type { DETACHED, JOINABLE };
167               
168                   static int create(
169 kumpf    1.10         ThreadType& thread,
170 mike     1.2          Type type,
171 kumpf    1.10         void* (*start)(void*),
172 mike     1.2          void* arg);
173               
174                   static ThreadType self();
175               
176                   static bool equal(ThreadType x, ThreadType y);
177               
178                   static void exit(ThreadReturnType rc);
179               
180                   static void cancel(ThreadType th, ThreadReturnType rc);
181               
182                   static void yield();
183               
184                   static void sleep(int msec);
185               
186                   static void cleanup_push(void (*start)(void*), void* arg);
187               
188                   static void cleanup_pop(int execute);
189               
190 mike     1.3      static ThreadId id(const ThreadType& x = Threads::self());
191               
192                   static bool null(const ThreadType& x = Threads::self());
193 mike     1.2  
194                   static void clear(ThreadType& x);
195               };
196               
197               //==============================================================================
198               //
199               // POSIX Threads Implementation
200               //
201               //==============================================================================
202               
203               #if defined(PEGASUS_HAVE_PTHREADS)
204               
205 kumpf    1.10 inline bool Threads::equal(ThreadType x, ThreadType y)
206               {
207 mike     1.3      return pthread_equal(x.thread, y.thread);
208 mike     1.2  }
209               
210               inline void Threads::exit(ThreadReturnType rc)
211               {
212 marek    1.9      // NOTE: pthread_exit exhibits unusual behavior on RHEL 3 U2, as
213                   // documented in Bugzilla 3836.  Where feasible, it may be advantageous
214                   // to avoid using this function.
215 mike     1.2      pthread_exit(rc);
216               }
217               
218               inline void Threads::cancel(ThreadType th, ThreadReturnType rc)
219               {
220 mike     1.3      pthread_cancel(th.thread);
221 mike     1.2  }
222               
223               inline void Threads::yield()
224               {
225 marek    1.16 #ifdef PEGASUS_OS_LINUX
226                   pthread_yield();
227               #else
228 mike     1.2      sched_yield();
229               #endif
230               }
231               
232               inline void Threads::cleanup_push(void (*func)(void*), void* arg)
233               {
234                   // ATTN: it is doubtful whether cleanup handlers ever really worked.
235                   //       They are only used in two places and not used in many other
236                   //       places where mutexes are obtained. Further, they are only
237                   //       implemented correctly on one or two platforms. For now, we
238                   //       will defer their implementation until we can find a way to
239                   //       implement them on all platforms (using thread local storage).
240               }
241               
242               inline void Threads::cleanup_pop(int execute)
243               {
244                   // ATTN: not implemented.
245               }
246               
247 mike     1.3  inline ThreadId Threads::id(const ThreadType& x)
248 mike     1.2  {
249 karl     1.17     ThreadId tid = { { 0 } };
250 mike     1.3  
251               #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
252                   const char* s = x.thread.__;
253 kumpf    1.10     sprintf(tid.buffer, "%X%X%X%X%X%X%X%X",
254 mike     1.3          s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
255               #else
256 kumpf    1.10     sprintf(tid.buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u",
257 mike     1.6          Uint64(x.thread));
258 mike     1.3  #endif
259               
260                   return tid;
261               }
262               
263               inline bool Threads::null(const ThreadType& x)
264               {
265               #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
266                   Uint64 tmp;
267 marek    1.7      memcpy(&tmp, x.thread.__, sizeof(Uint64));
268 mike     1.3      return tmp == 0;
269               #else
270                   return x.thread == 0;
271               #endif
272 mike     1.2  }
273               
274               inline void Threads::clear(ThreadType& x)
275               {
276                   memset(&x, 0, sizeof(x));
277               }
278               
279               #endif /* defined(PEGASUS_HAVE_PTHREADS) */
280               
281               //==============================================================================
282               //
283               // Windows Threads Implementation
284               //
285               //==============================================================================
286               
287               #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
288               
289 kumpf    1.10 inline ThreadType Threads::self()
290 mike     1.2  {
291                   ThreadType tt;
292 mike     1.5      tt.handle = GetCurrentThread();
293 mike     1.2      return tt;
294               }
295               
296 kumpf    1.10 inline bool Threads::equal(ThreadType x, ThreadType y)
297 mike     1.2  {
298                   return x.handle == y.handle;
299               }
300               
301               inline void Threads::exit(ThreadReturnType rc)
302               {
303                   _endthreadex(rc);
304               }
305               
306               inline void Threads::cancel(ThreadType th, ThreadReturnType rc)
307               {
308                   TerminateThread(th.handle, rc);
309               }
310               
311               inline void Threads::yield()
312               {
313                   Sleep(0);
314               }
315               
316               inline void Threads::cleanup_push(void (*func)(void*), void* arg)
317               {
318 mike     1.2      // ATTN: Not implemented on Windows.
319               }
320               
321               inline void Threads::cleanup_pop(int execute)
322               {
323                   // ATTN: Not implemented on Windows.
324               }
325               
326 mike     1.3  inline ThreadId Threads::id(const ThreadType& x)
327               {
328                   ThreadId tmp;
329               
330 kumpf    1.10     sprintf(tmp.buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u",
331 mike     1.5          Uint64(x.handle));
332 mike     1.3  
333                   return tmp;
334               }
335               
336               inline bool Threads::null(const ThreadType& x)
337 mike     1.2  {
338 mike     1.3      return x.handle == NULL;
339 mike     1.2  }
340               
341               inline void Threads::clear(ThreadType& x)
342               {
343                   x.handle = NULL;
344               }
345               
346               #endif /* defined(PEGASUS_HAVE_WINDOWS_THREADS) */
347               
348               PEGASUS_NAMESPACE_END
349               
350               #endif /* Pegasus_Threads_h */

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2