/[pcsx2_0.9.7]/trunk/3rdparty/w32pthreads/create.c
ViewVC logotype

Contents of /trunk/3rdparty/w32pthreads/create.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 11 months ago) by william
File MIME type: text/plain
File size: 7941 byte(s)
committing r3113 initial commit again...
1 /*
2 * create.c
3 *
4 * Description:
5 * This translation unit implements routines associated with spawning a new
6 * thread.
7 *
8 * --------------------------------------------------------------------------
9 *
10 * Pthreads-win32 - POSIX Threads Library for Win32
11 * Copyright(C) 1998 John E. Bossom
12 * Copyright(C) 1999,2005 Pthreads-win32 contributors
13 *
14 * Contact Email: rpj@callisto.canberra.edu.au
15 *
16 * The current list of contributors is contained
17 * in the file CONTRIBUTORS included with the source
18 * code distribution. The list can also be seen at the
19 * following World Wide Web location:
20 * http://sources.redhat.com/pthreads-win32/contributors.html
21 *
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License as published by the Free Software Foundation; either
25 * version 2 of the License, or (at your option) any later version.
26 *
27 * This library is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 * Lesser General Public License for more details.
31 *
32 * You should have received a copy of the GNU Lesser General Public
33 * License along with this library in the file COPYING.LIB;
34 * if not, write to the Free Software Foundation, Inc.,
35 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
36 */
37
38 #include "ptw32pch.h"
39 #ifndef _UWIN
40 #include <process.h>
41 #endif
42
43 int
44 pthread_create (pthread_t * tid,
45 const pthread_attr_t * attr,
46 void *(*start) (void *), void *arg)
47 /*
48 * ------------------------------------------------------
49 * DOCPUBLIC
50 * This function creates a thread running the start function,
51 * passing it the parameter value, 'arg'. The 'attr'
52 * argument specifies optional creation attributes.
53 * The identity of the new thread is returned
54 * via 'tid', which should not be NULL.
55 *
56 * PARAMETERS
57 * tid
58 * pointer to an instance of pthread_t
59 *
60 * attr
61 * optional pointer to an instance of pthread_attr_t
62 *
63 * start
64 * pointer to the starting routine for the new thread
65 *
66 * arg
67 * optional parameter passed to 'start'
68 *
69 *
70 * DESCRIPTION
71 * This function creates a thread running the start function,
72 * passing it the parameter value, 'arg'. The 'attr'
73 * argument specifies optional creation attributes.
74 * The identity of the new thread is returned
75 * via 'tid', which should not be the NULL pointer.
76 *
77 * RESULTS
78 * 0 successfully created thread,
79 * EINVAL attr invalid,
80 * EAGAIN insufficient resources.
81 *
82 * ------------------------------------------------------
83 */
84 {
85 pthread_t thread;
86 ptw32_thread_t * tp;
87 register pthread_attr_t a;
88 HANDLE threadH = 0;
89 int result = EAGAIN;
90 int run = PTW32_TRUE;
91 ThreadParms *parms = NULL;
92 long stackSize;
93 int priority;
94 pthread_t self;
95
96 /*
97 * Before doing anything, check that tid can be stored through
98 * without invoking a memory protection error (segfault).
99 * Make sure that the assignment below can't be optimised out by the compiler.
100 * This is assured by conditionally assigning *tid again at the end.
101 */
102 tid->x = 0;
103
104 if (attr != NULL)
105 {
106 a = *attr;
107 }
108 else
109 {
110 a = NULL;
111 }
112
113 if ((thread = ptw32_new ()).p == NULL)
114 {
115 goto FAIL0;
116 }
117
118 tp = (ptw32_thread_t *) thread.p;
119
120 priority = tp->sched_priority;
121
122 if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
123 {
124 goto FAIL0;
125 }
126
127 parms->tid = thread;
128 parms->start = start;
129 parms->arg = arg;
130
131 #if defined(HAVE_SIGSET_T)
132
133 /*
134 * Threads inherit their initial sigmask from their creator thread.
135 */
136 self = pthread_self();
137 tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask;
138
139 #endif /* HAVE_SIGSET_T */
140
141
142 if (a != NULL)
143 {
144 stackSize = a->stacksize;
145 tp->detachState = a->detachstate;
146 priority = a->param.sched_priority;
147
148 #if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
149 /* WinCE */
150 #else
151 /* Everything else */
152
153 /*
154 * Thread priority must be set to a valid system level
155 * without altering the value set by pthread_attr_setschedparam().
156 */
157
158 /*
159 * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads
160 * don't inherit their creator's priority. They are started with
161 * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying
162 * an 'attr' arg to pthread_create() is equivalent to defaulting to
163 * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL.
164 */
165 if (PTHREAD_INHERIT_SCHED == a->inheritsched)
166 {
167 /*
168 * If the thread that called pthread_create() is a Win32 thread
169 * then the inherited priority could be the result of a temporary
170 * system adjustment. This is not the case for POSIX threads.
171 */
172 #if ! defined(HAVE_SIGSET_T)
173 self = pthread_self ();
174 #endif
175 priority = ((ptw32_thread_t *) self.p)->sched_priority;
176 }
177
178 #endif
179
180 }
181 else
182 {
183 /*
184 * Default stackSize
185 */
186 stackSize = PTHREAD_STACK_MIN;
187 }
188
189 tp->state = run ? PThreadStateInitial : PThreadStateSuspended;
190
191 tp->keys = NULL;
192
193 /*
194 * Threads must be started in suspended mode and resumed if necessary
195 * after _beginthreadex returns us the handle. Otherwise we set up a
196 * race condition between the creating and the created threads.
197 * Note that we also retain a local copy of the handle for use
198 * by us in case thread.p->threadH gets NULLed later but before we've
199 * finished with it here.
200 */
201
202 #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__)
203
204 tp->threadH =
205 threadH =
206 (HANDLE) _beginthreadex ((void *) NULL, /* No security info */
207 (unsigned) stackSize, /* default stack size */
208 ptw32_threadStart,
209 parms,
210 (unsigned)
211 CREATE_SUSPENDED,
212 (unsigned *) &(tp->thread));
213
214 if (threadH != 0)
215 {
216 if (a != NULL)
217 {
218 (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
219 }
220
221 if (run)
222 {
223 ResumeThread (threadH);
224 }
225 }
226
227 #else /* __MINGW32__ && ! __MSVCRT__ */
228
229 /*
230 * This lock will force pthread_threadStart() to wait until we have
231 * the thread handle and have set the priority.
232 */
233 (void) pthread_mutex_lock (&tp->cancelLock);
234
235 tp->threadH =
236 threadH =
237 (HANDLE) _beginthread (ptw32_threadStart, (unsigned) stackSize, /* default stack size */
238 parms);
239
240 /*
241 * Make the return code match _beginthreadex's.
242 */
243 if (threadH == (HANDLE) - 1L)
244 {
245 tp->threadH = threadH = 0;
246 }
247 else
248 {
249 if (!run)
250 {
251 /*
252 * beginthread does not allow for create flags, so we do it now.
253 * Note that beginthread itself creates the thread in SUSPENDED
254 * mode, and then calls ResumeThread to start it.
255 */
256 SuspendThread (threadH);
257 }
258
259 if (a != NULL)
260 {
261 (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
262 }
263 }
264
265 (void) pthread_mutex_unlock (&tp->cancelLock);
266
267 #endif /* __MINGW32__ && ! __MSVCRT__ */
268
269 result = (threadH != 0) ? 0 : EAGAIN;
270
271 /*
272 * Fall Through Intentionally
273 */
274
275 /*
276 * ------------
277 * Failure Code
278 * ------------
279 */
280
281 FAIL0:
282 if (result != 0)
283 {
284
285 ptw32_threadDestroy (thread);
286 tp = NULL;
287
288 if (parms != NULL)
289 {
290 free (parms);
291 }
292 }
293 else
294 {
295 *tid = thread;
296 }
297
298 #ifdef _UWIN
299 if (result == 0)
300 pthread_count++;
301 #endif
302 return (result);
303
304 } /* pthread_create */

  ViewVC Help
Powered by ViewVC 1.1.22