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

  1 karl  1.25 //%2005////////////////////////////////////////////////////////////////////////
  2 mike  1.2  //
  3 karl  1.23 // 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 karl  1.18 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.23 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.25 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 mike  1.2  //
 12            // Permission is hereby granted, free of charge, to any person obtaining a copy
 13 kumpf 1.10 // of this software and associated documentation files (the "Software"), to
 14            // deal in the Software without restriction, including without limitation the
 15            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 16 mike  1.2  // sell copies of the Software, and to permit persons to whom the Software is
 17            // furnished to do so, subject to the following conditions:
 18            // 
 19 kumpf 1.10 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20 mike  1.2  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 21            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 22 kumpf 1.10 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 23            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 24            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 25 mike  1.2  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27            //
 28            //==============================================================================
 29            //
 30            // Author: Markus Mueller (sedgewick_de@yahoo.de)
 31            //
 32            // Modified By: Mike Day (mdday@us.ibm.com)
 33            //
 34            //%/////////////////////////////////////////////////////////////////////////////
 35            
 36            #ifndef IPC_UNIX_include
 37            #define IPC_UNIX_include
 38            
 39            #include <sched.h>
 40            #include <semaphore.h>
 41            #include <pthread.h>
 42            #include <signal.h>
 43            #include <errno.h>
 44            #include <sys/time.h>
 45            #include <time.h>
 46 dudhe.girish 1.21 #if !defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU)
 47 mike         1.2  #include <sys/timex.h>
 48 dudhe.girish 1.21 #endif
 49 mike         1.2  
 50 konrad.r     1.26 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
 51                   #if GCC_VERSION > 30202
 52                   	#define USE_PTHREAD_COND_IN_SEMAPHORE
 53                   #endif
 54                   #endif
 55                   
 56 mike         1.2  PEGASUS_NAMESPACE_BEGIN
 57                   
 58 mday         1.5  int timeval_subtract (struct timeval *result, 
 59                   		      struct timeval *x, 
 60                   		      struct timeval *y);
 61                   
 62                   
 63 mike         1.3  #ifdef PEGASUS_NEED_CRITICAL_TYPE
 64 konrad.r     1.22 #if !defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU) 
 65 mike         1.2  typedef pthread_spinlock_t PEGASUS_CRIT_TYPE;
 66 dudhe.girish 1.21 #else
 67                   typedef pthread_mutex_t PEGASUS_CRIT_TYPE;
 68                   #endif
 69 mike         1.3  #endif
 70                   
 71 mike         1.2  typedef sem_t PEGASUS_SEMAPHORE_TYPE;
 72                   typedef pthread_t PEGASUS_THREAD_TYPE;
 73                   typedef pthread_mutex_t PEGASUS_MUTEX_TYPE;
 74                   
 75 konrad.r     1.26 #if !defined(PEGASUS_OS_ZOS_ZSERIES_IBM) && !defined(PEGASUS_OS_DARWIN) && !defined(USE_PTHREAD_COND_IN_SEMAPHORE)
 76 mike         1.2  typedef struct {
 77                       sem_t sem;
 78                       pthread_t owner;
 79                   } PEGASUS_SEM_HANDLE ;
 80 dudhe.girish 1.21 #elif defined(PEGASUS_OS_DARWIN)
 81                   typedef struct {
 82                       sem_t * sem;
 83                       pthread_t owner;
 84                       Uint32 waiters;
 85                   } PEGASUS_SEM_HANDLE ;
 86 mike         1.2  #else
 87                   typedef struct {
 88 konrad.r     1.24     Uint32 waiters;
 89 mike         1.2      pthread_mutex_t mutex;
 90                       pthread_cond_t cond;
 91                       pthread_t owner;
 92                   } PEGASUS_SEM_HANDLE ;
 93                   #endif
 94                   
 95                   typedef struct {
 96                       pthread_mutex_t mut;
 97                       pthread_mutexattr_t mutatt;
 98                       pthread_t owner;
 99                   } PEGASUS_MUTEX_HANDLE ;
100                   
101 keith.petley 1.17 #ifdef PEGASUS_OS_SOLARIS
102 mike         1.3  typedef _cleanup_t PEGASUS_CLEANUP_HANDLE;
103 dudhe.girish 1.21 #elif defined(PEGASUS_OS_DARWIN)
104                   typedef void * PEGASUS_CLEANUP_HANDLE;
105 mike         1.3  #else
106                   typedef struct _pthread_cleanup_buffer  PEGASUS_CLEANUP_HANDLE;
107                   #endif
108 mike         1.2  
109                   typedef void *PEGASUS_THREAD_RETURN;
110                   
111                   #define PEGASUS_THREAD_CDECL
112                   
113                   typedef struct {
114                       pthread_t thid;
115                       pthread_attr_t thatt;
116                   } PEGASUS_THREAD_HANDLE ;
117                   
118                   //-----------------------------------------------------------------
119                   /// Conditionals to support native or generic Conditional Semaphore
120                   //-----------------------------------------------------------------
121                   
122 david.eger   1.15 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
123 kumpf        1.19 #define PEGASUS_CONDITIONAL_NATIVE
124 mike         1.2  
125                   typedef pthread_cond_t PEGASUS_COND_TYPE;
126                   
127                   typedef struct {
128                       pthread_cond_t cond;
129                       pthread_t owner;
130                   } PEGASUS_COND_HANDLE;
131                   
132                   #endif // linux platform conditional type
133                   
134                   //-----------------------------------------------------------------
135                   /// Conditionals to support native or generic atomic variables
136                   //-----------------------------------------------------------------
137                   
138 kumpf        1.20 // Linux IA32 offers a built-in integer type for atomic access.
139                   // Linux IA64 does not allow for built-in atomic access.
140                   // Spinlock on some Linux IA64 distributions does not work.
141                   // Other unix platforms HPUX, AIX, may have different types
142 mike         1.2  // implementors should use the native type for faster operations
143                   
144 konrad.r     1.22 #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) && !defined(PEGASUS_OS_LSB)
145 kumpf        1.19 #define PEGASUS_ATOMIC_INT_NATIVE
146 konrad.r     1.22   typedef pthread_spinlock_t PEGASUS_ATOMIC_TYPE;
147 kumpf        1.12 #endif
148 mike         1.2  
149                   //-----------------------------------------------------------------
150                   /// Conditionals to support native or generic read/write semaphores
151                   //-----------------------------------------------------------------
152                   
153                   
154                   //-----------------------------------------------------------------
155                   // NOTE: Tue Oct  9 13:36:53 2001 mdday
156                   //
157                   //  I put some read/write counting into the Thread test program to see
158                   //  how native r/w performance compares to generic r/w on linux. 
159                   //  For RH linux 7.1, the generic r/w lock in IPC.cpp performs 
160                   //  much better than the pthreads native implementation.
161                   //  
162                   //  Here are the data (remember that there are 4 readers for every one
163                   //  writer):
164                   // 
165                   //  Generic  read operations  6538     <- 4:1 ratio of reads to writes
166                   //           write operations 1422
167                   //
168                   //  Native   read operations   2060    <- 1:1 even though there are 
169 mike         1.2  //           write operations  2033       4 readers for every writer
170                   //
171                   //
172                   //  Comments -
173                   // 
174                   // The native implementation prefers writers, which slows the entire
175                   // test down because write operations take longer than read operations.
176                   // Moreover, as soon as one writer gains the lock, the next owner will 
177                   // always be a writer until there are no further writers. Readers are 
178                   // blocked out until all writers are sleeping. 
179                   //
180                   // In the test there are 4 readers for every writer. However, the 
181                   // native r/w lock severely skews resources toward writers.
182                   // 
183                   // The generic implementation has no preference among readers and writers. 
184                   // Therefore whichever thread is ready to read or write will gain the lock
185                   // with no dependence on whether the predecessor is a reader or writer. 
186                   // This results in higher throughput in the test program for linux.
187                   //
188                   // I would encourage all the platform maintainers to run their own tests
189                   // so we can decide which implementation to use for production builds. 
190 mike         1.2  //
191                   //-----------------------------------------------------------------
192                   
193                   
194                   //#if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) 
195 kumpf        1.19 // #define PEGASUS_READWRITE_NATIVE
196 mike         1.2  
197                   // typedef struct {
198                   //     pthread_rwlock_t rwlock;
199                   //     pthread_t owner;
200                   // } PEGASUS_RWLOCK_HANDLE;
201                   
202                   //#endif // linux platform read/write type
203                   
204                   inline void pegasus_yield(void)
205                   {
206 mike         1.3  #ifdef PEGASUS_NEED_CRITICAL_TYPE
207 dudhe.girish 1.21       #if !defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU)
208 mike         1.2        pthread_yield();
209 dudhe.girish 1.21       #else
210                         pthread_yield_np();
211                         #endif  
212 mike         1.3  #else
213                         sched_yield();
214                   #endif
215 mike         1.2  }
216                   
217                   // pthreads cancellation calls 
218                   inline void disable_cancel(void)
219                   {
220 kumpf        1.27    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
221 mike         1.2  }
222                   
223                   inline void enable_cancel(void)
224                   {
225 kumpf        1.27    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
226 mike         1.2  }
227                   
228                   inline void pegasus_sleep(int msec)
229                   {
230                      struct timespec wait;
231                      wait.tv_sec = msec / 1000;
232 kumpf        1.14    wait.tv_nsec = (msec % 1000) * 1000000;
233 mike         1.2     nanosleep(&wait, NULL);
234                   }
235                   
236 mike         1.3  #ifdef PEGASUS_NEED_CRITICAL_TYPE
237 dudhe.girish 1.21 #if !defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU)
238 mike         1.3  
239 mike         1.2  inline void init_crit(PEGASUS_CRIT_TYPE *crit)
240                   {
241                      pthread_spin_init(crit, 0);
242                   }
243                   
244                   inline void enter_crit(PEGASUS_CRIT_TYPE *crit)
245                   {
246                      pthread_spin_lock(crit);
247                   }
248                   
249                   inline void try_crit(PEGASUS_CRIT_TYPE *crit)
250                   {
251                      pthread_spin_trylock(crit);
252                   }
253                   
254                   inline void exit_crit(PEGASUS_CRIT_TYPE *crit)
255                   {
256                      pthread_spin_unlock(crit);
257                   }
258                   
259                   inline void destroy_crit(PEGASUS_CRIT_TYPE *crit)
260 mike         1.2  {
261                      pthread_spin_destroy(crit);
262                   }
263 dudhe.girish 1.21 #else
264                   
265                   inline void init_crit(PEGASUS_CRIT_TYPE *crit)
266                   {
267                      pthread_mutex_init(crit, 0);
268                   }
269 mike         1.2  
270 dudhe.girish 1.21 inline void enter_crit(PEGASUS_CRIT_TYPE *crit)
271                   {
272                      pthread_mutex_lock(crit);
273                   }
274                   
275                   inline void try_crit(PEGASUS_CRIT_TYPE *crit)
276                   {
277                      pthread_mutex_trylock(crit);
278                   }
279                   
280                   inline void exit_crit(PEGASUS_CRIT_TYPE *crit)
281                   {
282                      pthread_mutex_unlock(crit);
283                   }
284                   
285                   inline void destroy_crit(PEGASUS_CRIT_TYPE *crit)
286                   {
287                      pthread_mutex_destroy(crit);
288                   }
289                   
290                   #endif
291 mike         1.3  #endif /* PEGASUS_NEED_CRITICAL_TYPE */
292 mike         1.2  
293                   //-----------------------------------------------------------------
294                   /// accurate version of gettimeofday for unix systems
295                   //  posix glibc implementation does not return microseconds.
296                   //  mdday Wed Aug  1 16:05:26 2001
297                   //-----------------------------------------------------------------
298 konrad.r     1.22 #if !defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU) && !defined(PEGASUS_OS_LSB)
299 mike         1.2  inline static int pegasus_gettimeofday(struct timeval *tv)
300                   {
301                      struct ntptimeval ntp;
302                      int err;
303                      if(tv == NULL)
304                         return(EINVAL);
305                      err = ntp_gettime(&ntp);
306                      tv->tv_sec = ntp.time.tv_sec;
307                      tv->tv_usec = ntp.time.tv_usec;
308                      return(err);
309                   }
310 dudhe.girish 1.21 #else
311                   inline static int pegasus_gettimeofday(struct timeval *tv)
312                   {
313                      int err;
314                      if(tv == NULL)
315                         return(EINVAL);
316                      err = gettimeofday(tv,NULL);
317                      return err;
318                   }
319                   #endif	
320 mike         1.2     
321                   inline void exit_thread(PEGASUS_THREAD_RETURN rc)
322                   {
323                     pthread_exit(rc);
324                   }
325                   
326                   inline PEGASUS_THREAD_TYPE pegasus_thread_self(void) 
327                   { 
328                      return(pthread_self());
329                   }
330                   
331 chuck        1.16 // l10n start
332                   typedef pthread_key_t PEGASUS_THREAD_KEY_TYPE;
333                   
334                   inline Uint32 pegasus_key_create(PEGASUS_THREAD_KEY_TYPE * key)
335                   {
336                   	// Note: a destructor is not supported 
337                   	// (because not supported on Windows (?))
338                   	return pthread_key_create(key, NULL);
339                   } 
340                   
341                   inline Uint32 pegasus_key_delete(PEGASUS_THREAD_KEY_TYPE key)
342                   {
343                   	return pthread_key_delete(key);
344                   } 
345                   
346                   inline void * pegasus_get_thread_specific(PEGASUS_THREAD_KEY_TYPE key)
347                   {
348                   	return pthread_getspecific(key);
349                   } 
350                   
351                   inline Uint32 pegasus_set_thread_specific(PEGASUS_THREAD_KEY_TYPE key,
352 chuck        1.16 										 void * value)
353                   {
354                   	return pthread_setspecific(key, value);
355                   } 
356                   // l10n end
357                   
358                   
359 mike         1.2  inline void destroy_thread(PEGASUS_THREAD_TYPE th, PEGASUS_THREAD_RETURN rc)
360                   {
361                      pthread_cancel(th);
362                   
363                   }
364                   
365                   PEGASUS_NAMESPACE_END
366                   
367                   #endif // IPCUNIXInclude

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2