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 marek 1.13 #if defined(PEGASUS_OS_ZOS)
44 # include <unistd.h>
45 #endif
|
46 mike 1.2
|
47 karl 1.14 #if defined(PEGASUS_OS_SOLARIS)
48 # include <unistd.h>
49 #endif
50
|
51 mike 1.2 PEGASUS_NAMESPACE_BEGIN
52
53 void Threads::sleep(int msec)
54 {
55 #if defined(PEGASUS_HAVE_NANOSLEEP)
56
|
57 dave.sudlik 1.8 struct timespec wait, remwait;
|
58 mike 1.2 wait.tv_sec = msec / 1000;
59 wait.tv_nsec = (msec % 1000) * 1000000;
|
60 dave.sudlik 1.8
61 while ((nanosleep(&wait, &remwait) == -1) && (errno == EINTR))
62 {
63 wait.tv_sec = remwait.tv_sec;
64 wait.tv_nsec = remwait.tv_nsec;
65 }
|
66 mike 1.2
|
67 a.dunfey 1.7 #elif defined(PEGASUS_OS_TYPE_WINDOWS)
|
68 mike 1.2
69 if (msec == 0)
|
70 kumpf 1.6 {
|
71 mike 1.2 Sleep(0);
72 return;
73 }
74
75 struct _timeb end, now;
76 _ftime( &end );
77 end.time += (msec / 1000);
78 msec -= (msec / 1000);
79 end.millitm += msec;
80
81 do
82 {
83 Sleep(0);
84 _ftime(&now);
|
85 kumpf 1.6 }
86 while (end.millitm > now.millitm && end.time >= now.time);
|
87 mike 1.2
|
88 ouyang.jian 1.12 #else
|
89 mike 1.2 if (msec < 1000)
90 {
91 usleep(msec*1000);
92 }
93 else
94 {
95 // sleep for loop seconds
|
96 mike 1.3 ::sleep(msec / 1000);
|
97 mike 1.2 // Usleep the remaining micro seconds
98 usleep( (msec*1000) % 1000000 );
99 }
|
100 ouyang.jian 1.12
|
101 mike 1.2 #endif
102 }
103
104 //==============================================================================
105 //
106 // _get_stack_multiplier()
107 //
108 //==============================================================================
109
110 static inline int _get_stack_multiplier()
111 {
112 #if defined(PEGASUS_OS_VMS)
113
114 static int _multiplier = 0;
115 static MutexType _multiplier_mutex = PEGASUS_MUTEX_INITIALIZER;
116
|
117 kumpf 1.6 //
118 // This code uses a, 'hidden' (non-documented), VMS only, logical
|
119 mike 1.2 // name (environment variable), PEGASUS_VMS_THREAD_STACK_MULTIPLIER,
120 // to allow in the field adjustment of the thread stack size.
121 //
122 // We only check for the logical name once to not have an
123 // impact on performance.
|
124 kumpf 1.6 //
|
125 mike 1.2 // Note: This code may have problems in a multithreaded environment
126 // with the setting of doneOnce to true.
|
127 kumpf 1.6 //
|
128 mike 1.2 // Current code in Cimserver and the clients do some serial thread
129 // creations first so this is not a problem now.
|
130 kumpf 1.6 //
|
131 mike 1.2
132 if (_multiplier == 0)
133 {
134 mutex_lock(&_multiplier_mutex);
135
136 if (_multiplier == 0)
137 {
138 const char *env = getenv("PEGASUS_VMS_THREAD_STACK_MULTIPLIER");
139
140 if (env)
141 _multiplier = atoi(env);
142
143 if (_multiplier == 0)
144 _multiplier = 2;
145 }
146
147 mutex_unlock(&_multiplier_mutex);
148 }
149
150 return _multiplier;
|
151 kumpf 1.11 #elif defined(PEGASUS_PLATFORM_HPUX_PARISC_ACC)
152 return 2;
|
153 cheng.sp 1.16 #elif defined(PEGASUS_OS_AIX)
154 return 2;
|
155 mike 1.2 #else
|
156 kumpf 1.11 return 1;
|
157 mike 1.2 #endif
158 }
159
160 //==============================================================================
161 //
162 // PEGASUS_HAVE_PTHREADS
163 //
164 //==============================================================================
165
166 #if defined(PEGASUS_HAVE_PTHREADS)
167
168 int Threads::create(
|
169 kumpf 1.6 ThreadType& thread,
|
170 mike 1.2 Type type,
|
171 kumpf 1.6 void* (*start)(void*),
|
172 mike 1.2 void* arg)
173 {
174 // Initialize thread attributes:
175
176 pthread_attr_t attr;
177 pthread_attr_init(&attr);
178
179 // Detached:
180
181 if (type == DETACHED)
182 {
|
183 r.kieninger 1.15 #if defined(PEGASUS_OS_ZOS)
|
184 mike 1.2 int ds = 1;
185 pthread_attr_setdetachstate(&attr, &ds);
186 #else
187 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
188 #endif
189 }
190
191 // Stack size:
192
|
193 kumpf 1.11 int multiplier = _get_stack_multiplier();
194
195 if (multiplier != 1)
|
196 mike 1.2 {
197 size_t stacksize;
198
199 if (pthread_attr_getstacksize(&attr, &stacksize) == 0)
200 {
|
201 kumpf 1.11 int rc = pthread_attr_setstacksize(&attr, stacksize * multiplier);
|
202 mike 1.2 PEGASUS_ASSERT(rc == 0);
203 }
204 }
205
206 // Scheduling policy:
207
|
208 karl 1.14 #if defined(PEGASUS_OS_SOLARIS)
209
|
210 mike 1.2 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
|
211 karl 1.14
212 #endif /* defined(PEGASUS_OS_SOLARIS) */
|
213 mike 1.2
214 // Create thread:
215
|
216 mike 1.4 int rc = pthread_create(&thread.thread, &attr, start, arg);
|
217 mike 1.2
218 if (rc != 0)
219 {
220 thread = ThreadType();
221 return rc;
222 }
223
224 // Destroy attributes now.
225
226 pthread_attr_destroy(&attr);
227
228 // Return:
229
230 return 0;
231 }
232
|
233 kumpf 1.6 ThreadType Threads::self()
|
234 mike 1.2 {
|
235 mike 1.4 ThreadType tt;
236 tt.thread = pthread_self();
237 return tt;
|
238 mike 1.2 }
239
240 #endif /* PEGASUS_HAVE_PTHREADS */
241
242 PEGASUS_NAMESPACE_END
|