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

  1 mike  1.2 //%2006////////////////////////////////////////////////////////////////////////
  2           //
  3           // 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           // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12           // EMC Corporation; Symantec Corporation; The Open Group.
 13           //
 14           // Permission is hereby granted, free of charge, to any person obtaining a copy
 15           // of this software and associated documentation files (the "Software"), to
 16           // deal in the Software without restriction, including without limitation the
 17           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18           // sell copies of the Software, and to permit persons to whom the Software is
 19           // furnished to do so, subject to the following conditions:
 20           // 
 21           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29           //
 30           //==============================================================================
 31           //
 32           //%/////////////////////////////////////////////////////////////////////////////
 33           
 34 mike  1.5 #include <errno.h>
 35 mike  1.2 #include "Threads.h"
 36           #include "IDFactory.h"
 37           #include "TSDKey.h"
 38           #include "Once.h"
 39           
 40 a.dunfey 1.7 #if defined(PEGASUS_OS_TYPE_WINDOWS)
 41 mike     1.2 # include <sys/timeb.h>
 42              #endif
 43              
 44              PEGASUS_NAMESPACE_BEGIN
 45              
 46              void Threads::sleep(int msec)
 47              {
 48              #if defined(PEGASUS_HAVE_NANOSLEEP)
 49              
 50 dave.sudlik 1.8     struct timespec wait, remwait;
 51 mike        1.2     wait.tv_sec = msec / 1000;
 52                     wait.tv_nsec = (msec % 1000) * 1000000;
 53 dave.sudlik 1.8 
 54                     while ((nanosleep(&wait, &remwait) == -1) && (errno == EINTR))
 55                     {
 56                         wait.tv_sec = remwait.tv_sec;
 57                         wait.tv_nsec = remwait.tv_nsec;
 58                     }
 59 mike        1.2 
 60                 #elif defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM)
 61                 
 62                    int loop;
 63                    int microsecs = msec * 1000; /* convert from milliseconds to microseconds */
 64                 
 65                    if (microsecs < 1000000)
 66                        usleep(microsecs);
 67                    else
 68                    {
 69                        loop = microsecs / 1000000;
 70 kumpf       1.6        for (int i = 0; i < loop; i++)
 71 mike        1.2            usleep(1000000);
 72                        if ((loop*1000000) < microsecs)
 73                            usleep(microsecs - (loop*1000000));
 74                    }
 75                 
 76 a.dunfey    1.7 #elif defined(PEGASUS_OS_TYPE_WINDOWS)
 77 mike        1.2 
 78                     if (msec == 0)
 79 kumpf       1.6     {
 80 mike        1.2         Sleep(0);
 81                         return;
 82                     }
 83                 
 84                     struct _timeb end, now;
 85                     _ftime( &end );
 86                     end.time += (msec / 1000);
 87                     msec -= (msec / 1000);
 88                     end.millitm += msec;
 89                 
 90                     do
 91                     {
 92                         Sleep(0);
 93                         _ftime(&now);
 94 kumpf       1.6     }
 95                     while (end.millitm > now.millitm && end.time >= now.time);
 96 mike        1.2 
 97                 #elif defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
 98                     int seconds;
 99                     if (msec < 1000)
100                     {
101                         usleep(msec*1000);
102                     }
103                     else
104                     {
105                         // sleep for loop seconds
106 mike        1.3         ::sleep(msec / 1000);
107 mike        1.2         // Usleep the remaining micro seconds
108                         usleep( (msec*1000) % 1000000 );
109                     }
110                 #elif defined(PEGASUS_OS_VMS)
111                 
112 mike        1.3     ::sleep(msec / 1000);
113 mike        1.2 
114                 #endif
115                 }
116                 
117                 //==============================================================================
118                 //
119                 // Thread id TSD:
120                 //
121                 //==============================================================================
122                 
123                 static Once _once = PEGASUS_ONCE_INITIALIZER;
124                 static TSDKeyType _key;
125                 
126                 static void _create_key()
127                 {
128                     TSDKey::create(&_key);
129                 }
130                 
131                 static inline void _set_id_tsd(Uint32 id)
132                 {
133                     once(&_once, _create_key);
134 mike        1.2     TSDKey::set_thread_specific(_key, (void*)(long)id);
135                 }
136                 
137                 static inline Uint32 _get_id_tsd()
138                 {
139                     once(&_once, _create_key);
140                     void* ptr = TSDKey::get_thread_specific(_key);
141                 
142                     if (!ptr)
143                     {
144                         // Main thread's id is 1!
145                         return 1;
146                     }
147                 
148                     return (Uint32)(long)ptr;
149                 }
150                 
151                 //==============================================================================
152                 //
153                 // _get_stack_multiplier()
154                 //
155 mike        1.2 //==============================================================================
156                 
157                 static inline int _get_stack_multiplier()
158                 {
159                 #if defined(PEGASUS_OS_VMS)
160                 
161                     static int _multiplier = 0;
162                     static MutexType _multiplier_mutex = PEGASUS_MUTEX_INITIALIZER;
163                 
164 kumpf       1.6     //
165                     // This code uses a, 'hidden' (non-documented), VMS only, logical
166 mike        1.2     //  name (environment variable), PEGASUS_VMS_THREAD_STACK_MULTIPLIER,
167                     //  to allow in the field adjustment of the thread stack size.
168                     //
169                     // We only check for the logical name once to not have an
170                     //  impact on performance.
171 kumpf       1.6     //
172 mike        1.2     // Note:  This code may have problems in a multithreaded environment
173                     //  with the setting of doneOnce to true.
174 kumpf       1.6     //
175 mike        1.2     // Current code in Cimserver and the clients do some serial thread
176                     //  creations first so this is not a problem now.
177 kumpf       1.6     //
178 mike        1.2 
179                     if (_multiplier == 0)
180                     {
181                         mutex_lock(&_multiplier_mutex);
182                 
183                         if (_multiplier == 0)
184                         {
185                             const char *env = getenv("PEGASUS_VMS_THREAD_STACK_MULTIPLIER");
186                 
187                             if (env)
188                                 _multiplier = atoi(env);
189                 
190                             if (_multiplier == 0)
191                                 _multiplier = 2;
192                         }
193                 
194                         mutex_unlock(&_multiplier_mutex);
195                     }
196                 
197                     return _multiplier;
198                 #else
199 mike        1.2     return 2;
200                 #endif
201                 }
202                 
203                 //==============================================================================
204                 //
205                 // PEGASUS_HAVE_PTHREADS
206                 //
207                 //==============================================================================
208                 
209                 #if defined(PEGASUS_HAVE_PTHREADS)
210                 
211                 int Threads::create(
212 kumpf       1.6     ThreadType& thread,
213 mike        1.2     Type type,
214 kumpf       1.6     void* (*start)(void*),
215 mike        1.2     void* arg)
216                 {
217                     // Initialize thread attributes:
218                 
219                     pthread_attr_t attr;
220                     pthread_attr_init(&attr);
221                 
222                     // Detached:
223                 
224                     if (type == DETACHED)
225                     {
226                 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
227                         int ds = 1;
228                         pthread_attr_setdetachstate(&attr, &ds);
229                 #else
230                         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
231                 #endif
232                     }
233                 
234                     // Stack size:
235                 
236 mike        1.2 #if defined(PEGASUS_PLATFORM_HPUX_PARISC_ACC) || defined(PEGASUS_OS_VMS)
237                     {
238                         size_t stacksize;
239                 
240                         if (pthread_attr_getstacksize(&attr, &stacksize) == 0)
241                         {
242                             int m = _get_stack_multiplier();
243                             int rc = pthread_attr_setstacksize(&attr, stacksize * m);
244                             PEGASUS_ASSERT(rc == 0);
245                         }
246                     }
247                 #endif
248                 
249                     // Scheduling policy:
250                 
251                 #if defined(PEGASUS_PLATFORM_SOLARIS_SPARC_GNU) || \
252                     defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
253                 # if defined SUNOS_5_7
254                     pthread_attr_setschedpolicy(&attr, SCHED_RR);
255                 # else
256                     pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
257 mike        1.2 # endif
258                 #endif // PEGASUS_PLATFORM_SOLARIS_SPARC_GNU
259                 
260                     // Create thread:
261                 
262 mike        1.4     int rc = pthread_create(&thread.thread, &attr, start, arg);
263 mike        1.2 
264                     if (rc != 0)
265                     {
266                         thread = ThreadType();
267                         return rc;
268                     }
269                 
270                     // Destroy attributes now.
271                 
272                     pthread_attr_destroy(&attr);
273                 
274                     // Return:
275                 
276                     return 0;
277                 }
278                 
279 kumpf       1.6 ThreadType Threads::self()
280 mike        1.2 {
281 mike        1.4     ThreadType tt;
282                     tt.thread = pthread_self();
283                     return tt;
284 mike        1.2 }
285                 
286                 #endif /* PEGASUS_HAVE_PTHREADS */
287                 
288                 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2