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
|