(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           //-----------------------------------------------------------------
106           /// Conditionals to support native or generic Conditional Semaphore
107 chuck 1.1 //-----------------------------------------------------------------
108           
109           #define PEGASUS_CONDITIONAL_NATIVE = 1
110           
111           typedef pthread_cond_t PEGASUS_COND_TYPE;
112           
113           typedef struct {
114               pthread_cond_t cond;
115               PEGASUS_THREAD_TYPE owner;
116           } PEGASUS_COND_HANDLE;
117           
118           //-----------------------------------------------------------------
119           /// Conditionals to support native or generic atomic variables
120           //-----------------------------------------------------------------
121           
122           
123           //-----------------------------------------------------------------
124           /// Conditionals to support native or generic read/write semaphores
125           //-----------------------------------------------------------------
126           
127 gerarda 1.4 /* Gerarda - commented out the following code */
128             /*
129 chuck   1.1 #define PEGASUS_READWRITE_NATIVE = 1
130             
131             typedef struct {
132                  pthread_rwlock_t rwlock;
133                  PEGASUS_THREAD_TYPE owner;
134             } PEGASUS_RWLOCK_HANDLE;
135 gerarda 1.4 */
136 chuck   1.1 
137             
138             inline void pegasus_yield(void)
139             {
140                   sched_yield();
141             }
142             
143             // pthreads cancellation calls 
144             inline void disable_cancel(void)
145             {
146                pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
147             }
148             
149             inline void enable_cancel(void)
150             {
151                pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
152             }
153             
154             
155             inline void pegasus_sleep(int msec)
156             {
157 gerarda 1.4    /* Gerarda - redid the sleep routine */ 
158                int loop;
159                int microsecs = msec * 1000; /* convert from milliseconds to microseconds */
160             
161                if (microsecs < 1000000)
162                    usleep(microsecs);
163                else
164                {
165                    loop = microsecs / 1000000;
166                    for(int i = 0; i < loop; i++)
167             	   usleep(1000000);
168                    if ((loop*1000000) < microsecs)
169             	   usleep(microsecs - (loop*1000000));
170                }
171             
172                /* Turns out the following code does not induce sleep on OS400 */ 
173                /*
174 chuck   1.1    struct timespec wait;
175                pthread_mutex_t sleep_mut = PTHREAD_MUTEX_INITIALIZER;
176                pthread_cond_t sleep_cond;
177                pthread_cond_init (&sleep_cond, NULL);
178                pthread_mutex_lock(&sleep_mut);
179                wait.tv_sec = msec / 1000;
180 kumpf   1.6    wait.tv_nsec = (msec % 1000) * 1000000;
181 chuck   1.1    pthread_cond_timedwait(&sleep_cond,&sleep_mut,&wait);
182                pthread_mutex_unlock(&sleep_mut);
183                pthread_cond_destroy(&sleep_cond);
184 gerarda 1.4    */
185 chuck   1.1 }
186             
187             inline void init_crit(PEGASUS_CRIT_TYPE *crit)
188             {
189                pthread_mutex_init(&(crit->mut), NULL);
190             }
191             
192             inline void enter_crit(PEGASUS_CRIT_TYPE *crit)
193             {
194                pthread_mutex_lock(&(crit->mut));
195             }
196             
197             inline void try_crit(PEGASUS_CRIT_TYPE *crit)
198             {
199                pthread_mutex_trylock(&(crit->mut));
200             }
201             
202             inline void exit_crit(PEGASUS_CRIT_TYPE *crit)
203             {
204                pthread_mutex_unlock(&(crit->mut));
205             }
206 chuck   1.1 
207             inline void destroy_crit(PEGASUS_CRIT_TYPE *crit)
208             {
209                pthread_mutexattr_destroy(&(crit->mutatt));
210             }
211             
212             inline static int pegasus_gettimeofday(struct timeval *tv)
213             {
214                return gettimeofday(tv,NULL);
215             }
216             
217             inline void exit_thread(PEGASUS_THREAD_RETURN rc)
218             {
219               pthread_exit(rc);
220             }
221             
222 chuck   1.3 // Overload pegasus_thread_self to construct our
223             // PEGASUS_THREAD_TYPE with all the variables set.
224 chuck   1.1 inline PEGASUS_THREAD_TYPE pegasus_thread_self(void)
225             {
226 chuck   1.3     // Construct a PEGASUS_THREAD_TYPE with the 
227                 // pegasusValue initialized to 1 (ie. the thread
228                 // is 'alive')
229                 PEGASUS_THREAD_TYPE thrd = {pthread_self(),1};
230 chuck   1.1     return thrd; 
231             }
232             
233             inline void destroy_thread(PEGASUS_THREAD_TYPE th, PEGASUS_THREAD_RETURN rc)
234             {
235                pthread_cancel(th.thid);
236             
237             }
238             
239             // Need to overload some operators because Pegasus does compares,
240             // and assignments using the thread type, but pthread_t is a structure
241             // on OS/400
242             inline int operator==(const PEGASUS_THREAD_TYPE & lval,
243                                   const PEGASUS_THREAD_TYPE & rval)
244             {
245                 return pthread_equal(lval.thid, rval.thid);
246             }
247             
248             inline int operator==(const PEGASUS_THREAD_TYPE & lval,
249                                   const PEGASUS_UINT64 & rval)
250             {
251 chuck   1.3    return ( lval.pegasusValue == rval);
252 chuck   1.1 }
253             
254             
255             inline int operator!=(const PEGASUS_THREAD_TYPE & lval,
256                                   const PEGASUS_THREAD_TYPE & rval)
257             {
258                 return !operator==(lval,rval);
259             }  
260             
261             
262             inline int operator!=(const PEGASUS_THREAD_TYPE & lval,
263                                   const PEGASUS_UINT64 &  rval)
264             {
265                 return !operator==(lval,rval);
266             }
267             
268             inline int operator!=(const PEGASUS_THREAD_TYPE & lval,
269                                   const int &  rval)
270             {
271                 return !operator==(lval,(PEGASUS_UINT64)rval);
272             }
273 chuck   1.1 
274             inline int operator==(const PEGASUS_THREAD_TYPE & lval,
275                                   const int &  rval)
276             {
277                 return operator==(lval,(PEGASUS_UINT64)rval);
278             }
279              
280             inline __pegasus_os400_thread_type& __pegasus_os400_thread_type::operator=(const PEGASUS_UINT64 & rval)
281             {
282 chuck   1.3   pegasusValue = rval;
283 chuck   1.1   return *this;
284             }
285             
286             inline __pegasus_os400_thread_type::operator pthread_t *()
287             {
288                 return &thid;
289             }
290             
291             inline __pegasus_os400_thread_type::operator pthread_t ()
292             {
293                 return thid;
294             }
295             
296             inline __pegasus_os400_thread_type::operator Uint32 ()
297             {
298 chuck   1.5   pthread_id_np_t   tid;
299               pthread_getunique_np(&thid, &tid);
300               return (Uint32)(tid.intId.lo);
301 chuck   1.1 }
302             
303             PEGASUS_NAMESPACE_END
304             
305             #endif // IPCOS400Include

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2