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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2