1 martin 1.17 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.18 //
|
3 martin 1.17 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.18 //
|
10 martin 1.17 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.18 //
|
17 martin 1.17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.18 //
|
20 martin 1.17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.18 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.18 //
|
28 martin 1.17 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
|
32 mike 1.5 #include <errno.h>
|
33 mike 1.2 #include "Threads.h"
34 #include "IDFactory.h"
35 #include "TSDKey.h"
36 #include "Once.h"
37
|
38 a.dunfey 1.7 #if defined(PEGASUS_OS_TYPE_WINDOWS)
|
39 mike 1.2 # include <sys/timeb.h>
40 #endif
|
41 marek 1.13 #if defined(PEGASUS_OS_ZOS)
42 # include <unistd.h>
43 #endif
|
44 mike 1.2
|
45 karl 1.14 #if defined(PEGASUS_OS_SOLARIS)
46 # include <unistd.h>
47 #endif
48
|
49 mike 1.2 PEGASUS_NAMESPACE_BEGIN
50
|
51 sahana.prabhakar 1.20 namespace
52 {
53 //mutex used for synchronising threads calling _get_stack_multiplier
54 MutexType _multiplier_mutex = PEGASUS_MUTEX_INITIALIZER;
55 }
56
|
57 mike 1.2 void Threads::sleep(int msec)
58 {
59 #if defined(PEGASUS_HAVE_NANOSLEEP)
60
|
61 dave.sudlik 1.8 struct timespec wait, remwait;
|
62 mike 1.2 wait.tv_sec = msec / 1000;
63 wait.tv_nsec = (msec % 1000) * 1000000;
|
64 dave.sudlik 1.8
65 while ((nanosleep(&wait, &remwait) == -1) && (errno == EINTR))
66 {
67 wait.tv_sec = remwait.tv_sec;
68 wait.tv_nsec = remwait.tv_nsec;
69 }
|
70 mike 1.2
|
71 a.dunfey 1.7 #elif defined(PEGASUS_OS_TYPE_WINDOWS)
|
72 mike 1.2
73 if (msec == 0)
|
74 kumpf 1.6 {
|
75 mike 1.2 Sleep(0);
76 return;
77 }
78
79 struct _timeb end, now;
80 _ftime( &end );
81 end.time += (msec / 1000);
82 msec -= (msec / 1000);
83 end.millitm += msec;
84
85 do
86 {
87 Sleep(0);
88 _ftime(&now);
|
89 kumpf 1.6 }
90 while (end.millitm > now.millitm && end.time >= now.time);
|
91 mike 1.2
|
92 ouyang.jian 1.12 #else
|
93 mike 1.2 if (msec < 1000)
94 {
95 usleep(msec*1000);
96 }
97 else
98 {
99 // sleep for loop seconds
|
100 mike 1.3 ::sleep(msec / 1000);
|
101 mike 1.2 // Usleep the remaining micro seconds
102 usleep( (msec*1000) % 1000000 );
103 }
|
104 ouyang.jian 1.12
|
105 mike 1.2 #endif
106 }
107
108 //==============================================================================
109 //
110 // _get_stack_multiplier()
111 //
112 //==============================================================================
113
114 static inline int _get_stack_multiplier()
115 {
116 #if defined(PEGASUS_OS_VMS)
117
118 static int _multiplier = 0;
119
|
120 kumpf 1.6 //
121 // This code uses a, 'hidden' (non-documented), VMS only, logical
|
122 mike 1.2 // name (environment variable), PEGASUS_VMS_THREAD_STACK_MULTIPLIER,
123 // to allow in the field adjustment of the thread stack size.
124 //
125 // We only check for the logical name once to not have an
126 // impact on performance.
|
127 kumpf 1.6 //
|
128 mike 1.2 // Note: This code may have problems in a multithreaded environment
129 // with the setting of doneOnce to true.
|
130 kumpf 1.6 //
|
131 mike 1.2 // Current code in Cimserver and the clients do some serial thread
132 // creations first so this is not a problem now.
|
133 kumpf 1.6 //
|
134 mike 1.2
135 if (_multiplier == 0)
136 {
137 mutex_lock(&_multiplier_mutex);
138
139 if (_multiplier == 0)
140 {
141 const char *env = getenv("PEGASUS_VMS_THREAD_STACK_MULTIPLIER");
142
143 if (env)
144 _multiplier = atoi(env);
145
146 if (_multiplier == 0)
147 _multiplier = 2;
148 }
149
150 mutex_unlock(&_multiplier_mutex);
151 }
152
153 return _multiplier;
|
154 kumpf 1.11 #elif defined(PEGASUS_PLATFORM_HPUX_PARISC_ACC)
155 return 2;
|
156 cheng.sp 1.16 #elif defined(PEGASUS_OS_AIX)
157 return 2;
|
158 mike 1.2 #else
|
159 kumpf 1.11 return 1;
|
160 mike 1.2 #endif
161 }
162
163 //==============================================================================
164 //
165 // PEGASUS_HAVE_PTHREADS
166 //
167 //==============================================================================
168
169 #if defined(PEGASUS_HAVE_PTHREADS)
170
171 int Threads::create(
|
172 kumpf 1.6 ThreadType& thread,
|
173 mike 1.2 Type type,
|
174 kumpf 1.6 void* (*start)(void*),
|
175 mike 1.2 void* arg)
176 {
177 // Initialize thread attributes:
178
179 pthread_attr_t attr;
|
180 sahana.prabhakar 1.19 int rc = pthread_attr_init(&attr);
181 if(rc != 0)
182 {
183 return rc;
184 }
|
185 mike 1.2
186 // Detached:
187
188 if (type == DETACHED)
189 {
|
190 r.kieninger 1.15 #if defined(PEGASUS_OS_ZOS)
|
191 mike 1.2 int ds = 1;
192 pthread_attr_setdetachstate(&attr, &ds);
193 #else
194 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
195 #endif
196 }
197
198 // Stack size:
199
|
200 kumpf 1.11 int multiplier = _get_stack_multiplier();
201
202 if (multiplier != 1)
|
203 mike 1.2 {
204 size_t stacksize;
205
206 if (pthread_attr_getstacksize(&attr, &stacksize) == 0)
207 {
|
208 kumpf 1.11 int rc = pthread_attr_setstacksize(&attr, stacksize * multiplier);
|
209 mike 1.2 PEGASUS_ASSERT(rc == 0);
210 }
211 }
212
213 // Scheduling policy:
214
|
215 karl 1.14 #if defined(PEGASUS_OS_SOLARIS)
216
|
217 mike 1.2 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
|
218 karl 1.14
219 #endif /* defined(PEGASUS_OS_SOLARIS) */
|
220 mike 1.2
221 // Create thread:
222
|
223 sahana.prabhakar 1.19 rc = pthread_create(&thread.thread, &attr, start, arg);
|
224 mike 1.2
225 if (rc != 0)
226 {
227 thread = ThreadType();
228 }
229
230 // Destroy attributes now.
231
232 pthread_attr_destroy(&attr);
233
234 // Return:
235
|
236 sahana.prabhakar 1.19 return rc;
|
237 mike 1.2 }
238
|
239 kumpf 1.6 ThreadType Threads::self()
|
240 mike 1.2 {
|
241 mike 1.4 ThreadType tt;
242 tt.thread = pthread_self();
243 return tt;
|
244 mike 1.2 }
245
246 #endif /* PEGASUS_HAVE_PTHREADS */
247
248 PEGASUS_NAMESPACE_END
|