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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2