(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                 #endif
111                 }
112                 
113                 //==============================================================================
114                 //
115                 // Thread id TSD:
116                 //
117                 //==============================================================================
118                 
119                 static Once _once = PEGASUS_ONCE_INITIALIZER;
120                 static TSDKeyType _key;
121                 
122                 static void _create_key()
123                 {
124                     TSDKey::create(&_key);
125                 }
126                 
127                 static inline void _set_id_tsd(Uint32 id)
128 mike        1.2 {
129                     once(&_once, _create_key);
130                     TSDKey::set_thread_specific(_key, (void*)(long)id);
131                 }
132                 
133                 static inline Uint32 _get_id_tsd()
134                 {
135                     once(&_once, _create_key);
136                     void* ptr = TSDKey::get_thread_specific(_key);
137                 
138                     if (!ptr)
139                     {
140                         // Main thread's id is 1!
141                         return 1;
142                     }
143                 
144                     return (Uint32)(long)ptr;
145                 }
146                 
147                 //==============================================================================
148                 //
149 mike        1.2 // _get_stack_multiplier()
150                 //
151                 //==============================================================================
152                 
153                 static inline int _get_stack_multiplier()
154                 {
155                 #if defined(PEGASUS_OS_VMS)
156                 
157                     static int _multiplier = 0;
158                     static MutexType _multiplier_mutex = PEGASUS_MUTEX_INITIALIZER;
159                 
160 kumpf       1.6     //
161                     // This code uses a, 'hidden' (non-documented), VMS only, logical
162 mike        1.2     //  name (environment variable), PEGASUS_VMS_THREAD_STACK_MULTIPLIER,
163                     //  to allow in the field adjustment of the thread stack size.
164                     //
165                     // We only check for the logical name once to not have an
166                     //  impact on performance.
167 kumpf       1.6     //
168 mike        1.2     // Note:  This code may have problems in a multithreaded environment
169                     //  with the setting of doneOnce to true.
170 kumpf       1.6     //
171 mike        1.2     // Current code in Cimserver and the clients do some serial thread
172                     //  creations first so this is not a problem now.
173 kumpf       1.6     //
174 mike        1.2 
175                     if (_multiplier == 0)
176                     {
177                         mutex_lock(&_multiplier_mutex);
178                 
179                         if (_multiplier == 0)
180                         {
181                             const char *env = getenv("PEGASUS_VMS_THREAD_STACK_MULTIPLIER");
182                 
183                             if (env)
184                                 _multiplier = atoi(env);
185                 
186                             if (_multiplier == 0)
187                                 _multiplier = 2;
188                         }
189                 
190                         mutex_unlock(&_multiplier_mutex);
191                     }
192                 
193                     return _multiplier;
194                 #else
195 mike        1.2     return 2;
196                 #endif
197                 }
198                 
199                 //==============================================================================
200                 //
201                 // PEGASUS_HAVE_PTHREADS
202                 //
203                 //==============================================================================
204                 
205                 #if defined(PEGASUS_HAVE_PTHREADS)
206                 
207                 int Threads::create(
208 kumpf       1.6     ThreadType& thread,
209 mike        1.2     Type type,
210 kumpf       1.6     void* (*start)(void*),
211 mike        1.2     void* arg)
212                 {
213                     // Initialize thread attributes:
214                 
215                     pthread_attr_t attr;
216                     pthread_attr_init(&attr);
217                 
218                     // Detached:
219                 
220                     if (type == DETACHED)
221                     {
222                 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
223                         int ds = 1;
224                         pthread_attr_setdetachstate(&attr, &ds);
225                 #else
226                         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
227                 #endif
228                     }
229                 
230                     // Stack size:
231                 
232 mike        1.2 #if defined(PEGASUS_PLATFORM_HPUX_PARISC_ACC) || defined(PEGASUS_OS_VMS)
233                     {
234                         size_t stacksize;
235                 
236                         if (pthread_attr_getstacksize(&attr, &stacksize) == 0)
237                         {
238                             int m = _get_stack_multiplier();
239                             int rc = pthread_attr_setstacksize(&attr, stacksize * m);
240                             PEGASUS_ASSERT(rc == 0);
241                         }
242                     }
243                 #endif
244                 
245                     // Scheduling policy:
246                 
247                 #if defined(PEGASUS_PLATFORM_SOLARIS_SPARC_GNU) || \
248                     defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
249                 # if defined SUNOS_5_7
250                     pthread_attr_setschedpolicy(&attr, SCHED_RR);
251                 # else
252                     pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
253 mike        1.2 # endif
254                 #endif // PEGASUS_PLATFORM_SOLARIS_SPARC_GNU
255                 
256                     // Create thread:
257                 
258 mike        1.4     int rc = pthread_create(&thread.thread, &attr, start, arg);
259 mike        1.2 
260                     if (rc != 0)
261                     {
262                         thread = ThreadType();
263                         return rc;
264                     }
265                 
266                     // Destroy attributes now.
267                 
268                     pthread_attr_destroy(&attr);
269                 
270                     // Return:
271                 
272                     return 0;
273                 }
274                 
275 kumpf       1.6 ThreadType Threads::self()
276 mike        1.2 {
277 mike        1.4     ThreadType tt;
278                     tt.thread = pthread_self();
279                     return tt;
280 mike        1.2 }
281                 
282                 #endif /* PEGASUS_HAVE_PTHREADS */
283                 
284                 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2