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

  1 karl  1.12 //%2005////////////////////////////////////////////////////////////////////////
  2 chuck 1.1  //
  3 karl  1.11 // 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.8  // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.11 // 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.12 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 chuck 1.1  //
 12            // Permission is hereby granted, free of charge, to any person obtaining a copy
 13            // 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            // 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            // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20            // 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            // 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            // 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: Chuck Carmack (carmack@us.ibm.com)
 31            //
 32 chuck 1.1  //%/////////////////////////////////////////////////////////////////////////////
 33            
 34            #ifndef IPC_OS400_include
 35            #define IPC_OS400_include
 36            
 37            #define _MULTI_THREADED  // must be before pthread.h
 38            
 39 chuck 1.2  #include <limits.h>      // has SEM_VALUE_MAX
 40 chuck 1.1  #include <sched.h>
 41            #include <semaphore.h>
 42            #include <pthread.h>
 43            #include <signal.h>
 44            #include <errno.h>
 45            #include <sys/time.h>
 46            #include <time.h>
 47            //#include <sys/timex.h>
 48            #include <unistd.h>
 49            
 50 chuck 1.2  //#define SEM_VALUE_MAX 0xffffffff - defined in limits.h
 51 chuck 1.1  
 52            PEGASUS_NAMESPACE_BEGIN
 53            
 54            //typedef sem_t PEGASUS_SEMAPHORE_TYPE;
 55            
 56            //typedef pthread_t PEGASUS_THREAD_TYPE;
 57            
 58 chuck 1.3  // Redefine PEGASUS_THREAD_TYPE as a class on OS/400.  On other platforms
 59            // this is an int and Pegasus sets this to 0 to indicate
 60            // that the thread is 'dead'.  Also, we cannot use == operator
 61            // on pthread_t, but need to call pthread_equal( ), so the ==
 62            // operation is overloaded.  Other operators are overloaded in this file.
 63 chuck 1.1  typedef class __pegasus_os400_thread_type {
 64              public:
 65                pthread_t thid;           // An opaque struct on OS/400
 66 chuck 1.5      PEGASUS_UINT64 pegasusValue; // Needed because Pegasus sets PEGASUS_THREAD_TYPEs to 0
 67                                          // to indicate the thread is dead, but
 68 chuck 1.3                                // pthread_t structs cannot be changed on OS/400.
 69 chuck 1.1  
 70 chuck 1.3     // Overloaded operators.
 71 chuck 1.1      __pegasus_os400_thread_type& operator=(const PEGASUS_UINT64 & rval);
 72                operator pthread_t*();
 73                operator pthread_t();
 74                operator Uint32 ();
 75            } PEGASUS_THREAD_TYPE;
 76            
 77            typedef pthread_mutex_t PEGASUS_MUTEX_TYPE;
 78            
 79            typedef struct {
 80                sem_t sem;
 81                PEGASUS_THREAD_TYPE owner;
 82            } PEGASUS_SEM_HANDLE ;
 83            
 84            typedef struct {
 85                pthread_mutex_t mut;
 86                pthread_mutexattr_t mutatt;
 87                PEGASUS_THREAD_TYPE owner;
 88            } PEGASUS_MUTEX_HANDLE ;
 89            
 90            typedef PEGASUS_MUTEX_HANDLE PEGASUS_CRIT_TYPE;
 91            
 92 chuck 1.1  
 93            struct _pthread_cleanup_buffer {
 94                void (*__routine) (void *);             /* Function to call.  */
 95                void *__arg;                            /* Its argument.  */
 96                int __canceltype;                       /* Saved cancellation type. */
 97                struct _pthread_cleanup_buffer *__prev;  /* Chaining of cleanup functions.*/
 98            };
 99            typedef struct _pthread_cleanup_buffer  PEGASUS_CLEANUP_HANDLE;
100            
101            //#define PEGASUS_THREAD_CDECL __cdecl
102            #define PEGASUS_THREAD_CDECL
103            
104            typedef void *PEGASUS_THREAD_RETURN;
105            
106            typedef struct {
107                PEGASUS_THREAD_TYPE thid;
108                pthread_attr_t thatt;
109            } PEGASUS_THREAD_HANDLE ;
110            
111 chuck 1.7  
112 chuck 1.1  //-----------------------------------------------------------------
113            /// Conditionals to support native or generic Conditional Semaphore
114            //-----------------------------------------------------------------
115            
116 kumpf 1.10 #define PEGASUS_CONDITIONAL_NATIVE
117 chuck 1.1  
118            typedef pthread_cond_t PEGASUS_COND_TYPE;
119            
120            typedef struct {
121                pthread_cond_t cond;
122                PEGASUS_THREAD_TYPE owner;
123            } PEGASUS_COND_HANDLE;
124            
125            //-----------------------------------------------------------------
126            /// Conditionals to support native or generic atomic variables
127            //-----------------------------------------------------------------
128            
129            
130            //-----------------------------------------------------------------
131            /// Conditionals to support native or generic read/write semaphores
132            //-----------------------------------------------------------------
133            
134 gerarda 1.4  /* Gerarda - commented out the following code */
135              /*
136 kumpf   1.10 #define PEGASUS_READWRITE_NATIVE
137 chuck   1.1  
138              typedef struct {
139                   pthread_rwlock_t rwlock;
140                   PEGASUS_THREAD_TYPE owner;
141              } PEGASUS_RWLOCK_HANDLE;
142 gerarda 1.4  */
143 chuck   1.1  
144              
145              inline void pegasus_yield(void)
146              {
147                    sched_yield();
148              }
149              
150              // pthreads cancellation calls 
151              inline void disable_cancel(void)
152              {
153                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
154              }
155              
156              inline void enable_cancel(void)
157              {
158                 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
159              }
160              
161              
162              inline void pegasus_sleep(int msec)
163              {
164 gerarda 1.4     /* Gerarda - redid the sleep routine */ 
165                 int loop;
166                 int microsecs = msec * 1000; /* convert from milliseconds to microseconds */
167              
168                 if (microsecs < 1000000)
169                     usleep(microsecs);
170                 else
171                 {
172                     loop = microsecs / 1000000;
173                     for(int i = 0; i < loop; i++)
174              	   usleep(1000000);
175                     if ((loop*1000000) < microsecs)
176              	   usleep(microsecs - (loop*1000000));
177                 }
178              
179                 /* Turns out the following code does not induce sleep on OS400 */ 
180                 /*
181 chuck   1.1     struct timespec wait;
182                 pthread_mutex_t sleep_mut = PTHREAD_MUTEX_INITIALIZER;
183                 pthread_cond_t sleep_cond;
184                 pthread_cond_init (&sleep_cond, NULL);
185                 pthread_mutex_lock(&sleep_mut);
186                 wait.tv_sec = msec / 1000;
187 kumpf   1.6     wait.tv_nsec = (msec % 1000) * 1000000;
188 chuck   1.1     pthread_cond_timedwait(&sleep_cond,&sleep_mut,&wait);
189                 pthread_mutex_unlock(&sleep_mut);
190                 pthread_cond_destroy(&sleep_cond);
191 gerarda 1.4     */
192 chuck   1.1  }
193              
194              inline void init_crit(PEGASUS_CRIT_TYPE *crit)
195              {
196                 pthread_mutex_init(&(crit->mut), NULL);
197              }
198              
199              inline void enter_crit(PEGASUS_CRIT_TYPE *crit)
200              {
201                 pthread_mutex_lock(&(crit->mut));
202              }
203              
204              inline void try_crit(PEGASUS_CRIT_TYPE *crit)
205              {
206                 pthread_mutex_trylock(&(crit->mut));
207              }
208              
209              inline void exit_crit(PEGASUS_CRIT_TYPE *crit)
210              {
211                 pthread_mutex_unlock(&(crit->mut));
212              }
213 chuck   1.1  
214              inline void destroy_crit(PEGASUS_CRIT_TYPE *crit)
215              {
216                 pthread_mutexattr_destroy(&(crit->mutatt));
217              }
218              
219              inline static int pegasus_gettimeofday(struct timeval *tv)
220              {
221                 return gettimeofday(tv,NULL);
222              }
223              
224              inline void exit_thread(PEGASUS_THREAD_RETURN rc)
225              {
226                pthread_exit(rc);
227              }
228              
229 chuck   1.3  // Overload pegasus_thread_self to construct our
230              // PEGASUS_THREAD_TYPE with all the variables set.
231 chuck   1.1  inline PEGASUS_THREAD_TYPE pegasus_thread_self(void)
232              {
233 chuck   1.3      // Construct a PEGASUS_THREAD_TYPE with the 
234                  // pegasusValue initialized to 1 (ie. the thread
235                  // is 'alive')
236                  PEGASUS_THREAD_TYPE thrd = {pthread_self(),1};
237 chuck   1.1      return thrd; 
238              }
239 chuck   1.7  
240              // l10n start
241              typedef pthread_key_t PEGASUS_THREAD_KEY_TYPE;
242              
243              inline Uint32 pegasus_key_create(PEGASUS_THREAD_KEY_TYPE * key)
244              {
245              	// Note: a destructor is not supported 
246              	// (because not supported on Windows (?))
247              	return pthread_key_create(key, NULL);
248              } 
249              
250              inline Uint32 pegasus_key_delete(PEGASUS_THREAD_KEY_TYPE key)
251              {
252              	return pthread_key_delete(key);
253              } 
254              
255              inline void * pegasus_get_thread_specific(PEGASUS_THREAD_KEY_TYPE key)
256              {
257              	return pthread_getspecific(key);
258              } 
259              
260 chuck   1.7  inline Uint32 pegasus_set_thread_specific(PEGASUS_THREAD_KEY_TYPE key,
261              										 void * value)
262              {
263              	return pthread_setspecific(key, value);
264              } 
265              // l10n end
266 chuck   1.1  
267              inline void destroy_thread(PEGASUS_THREAD_TYPE th, PEGASUS_THREAD_RETURN rc)
268              {
269                 pthread_cancel(th.thid);
270              
271              }
272              
273              // Need to overload some operators because Pegasus does compares,
274              // and assignments using the thread type, but pthread_t is a structure
275              // on OS/400
276              inline int operator==(const PEGASUS_THREAD_TYPE & lval,
277                                    const PEGASUS_THREAD_TYPE & rval)
278              {
279 chuck   1.9      return (pthread_equal(lval.thid, rval.thid) &&
280                          (lval.pegasusValue == rval.pegasusValue));
281 chuck   1.1  }
282              
283              inline int operator==(const PEGASUS_THREAD_TYPE & lval,
284                                    const PEGASUS_UINT64 & rval)
285              {
286 chuck   1.3     return ( lval.pegasusValue == rval);
287 chuck   1.1  }
288              
289              
290              inline int operator!=(const PEGASUS_THREAD_TYPE & lval,
291                                    const PEGASUS_THREAD_TYPE & rval)
292              {
293                  return !operator==(lval,rval);
294              }  
295              
296              
297              inline int operator!=(const PEGASUS_THREAD_TYPE & lval,
298                                    const PEGASUS_UINT64 &  rval)
299              {
300                  return !operator==(lval,rval);
301              }
302              
303              inline int operator!=(const PEGASUS_THREAD_TYPE & lval,
304                                    const int &  rval)
305              {
306                  return !operator==(lval,(PEGASUS_UINT64)rval);
307              }
308 chuck   1.1  
309              inline int operator==(const PEGASUS_THREAD_TYPE & lval,
310                                    const int &  rval)
311              {
312                  return operator==(lval,(PEGASUS_UINT64)rval);
313              }
314               
315              inline __pegasus_os400_thread_type& __pegasus_os400_thread_type::operator=(const PEGASUS_UINT64 & rval)
316              {
317 chuck   1.3    pegasusValue = rval;
318 chuck   1.1    return *this;
319              }
320              
321              inline __pegasus_os400_thread_type::operator pthread_t *()
322              {
323                  return &thid;
324              }
325              
326              inline __pegasus_os400_thread_type::operator pthread_t ()
327              {
328                  return thid;
329              }
330              
331              inline __pegasus_os400_thread_type::operator Uint32 ()
332              {
333 chuck   1.5    pthread_id_np_t   tid;
334                pthread_getunique_np(&thid, &tid);
335                return (Uint32)(tid.intId.lo);
336 chuck   1.1  }
337              
338              PEGASUS_NAMESPACE_END
339              
340              #endif // IPCOS400Include

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2