5
* This translation unit implements routines associated with spawning a new
8
* --------------------------------------------------------------------------
10
* Pthreads-win32 - POSIX Threads Library for Win32
11
* Copyright(C) 1998 John E. Bossom
12
* Copyright(C) 1999,2005 Pthreads-win32 contributors
14
* Contact Email: rpj@callisto.canberra.edu.au
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
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.
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.
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
39
#include "implement.h"
40
#if ! defined(_UWIN) && ! defined(WINCE)
45
pthread_create (pthread_t * tid,
46
const pthread_attr_t * attr,
47
void *(*start) (void *), void *arg)
49
* ------------------------------------------------------
51
* This function creates a thread running the start function,
52
* passing it the parameter value, 'arg'. The 'attr'
53
* argument specifies optional creation attributes.
54
* The identity of the new thread is returned
55
* via 'tid', which should not be NULL.
59
* pointer to an instance of pthread_t
62
* optional pointer to an instance of pthread_attr_t
65
* pointer to the starting routine for the new thread
68
* optional parameter passed to 'start'
72
* This function creates a thread running the start function,
73
* passing it the parameter value, 'arg'. The 'attr'
74
* argument specifies optional creation attributes.
75
* The identity of the new thread is returned
76
* via 'tid', which should not be the NULL pointer.
79
* 0 successfully created thread,
80
* EINVAL attr invalid,
81
* EAGAIN insufficient resources.
83
* ------------------------------------------------------
88
register pthread_attr_t a;
92
ThreadParms *parms = NULL;
98
* Before doing anything, check that tid can be stored through
99
* without invoking a memory protection error (segfault).
100
* Make sure that the assignment below can't be optimised out by the compiler.
101
* This is assured by conditionally assigning *tid again at the end.
114
if ((thread = ptw32_new ()).p == NULL)
119
tp = (ptw32_thread_t *) thread.p;
121
priority = tp->sched_priority;
123
if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
129
parms->start = start;
132
#if defined(HAVE_SIGSET_T)
135
* Threads inherit their initial sigmask from their creator thread.
137
self = pthread_self();
138
tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask;
140
#endif /* HAVE_SIGSET_T */
145
stackSize = a->stacksize;
146
tp->detachState = a->detachstate;
147
priority = a->param.sched_priority;
149
#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
152
/* Everything else */
155
* Thread priority must be set to a valid system level
156
* without altering the value set by pthread_attr_setschedparam().
160
* PTHREAD_EXPLICIT_SCHED is the default because Win32 threads
161
* don't inherit their creator's priority. They are started with
162
* THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying
163
* an 'attr' arg to pthread_create() is equivalent to defaulting to
164
* PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL.
166
if (PTHREAD_INHERIT_SCHED == a->inheritsched)
169
* If the thread that called pthread_create() is a Win32 thread
170
* then the inherited priority could be the result of a temporary
171
* system adjustment. This is not the case for POSIX threads.
173
#if ! defined(HAVE_SIGSET_T)
174
self = pthread_self ();
176
priority = ((ptw32_thread_t *) self.p)->sched_priority;
187
stackSize = PTHREAD_STACK_MIN;
190
tp->state = run ? PThreadStateInitial : PThreadStateSuspended;
195
* Threads must be started in suspended mode and resumed if necessary
196
* after _beginthreadex returns us the handle. Otherwise we set up a
197
* race condition between the creating and the created threads.
198
* Note that we also retain a local copy of the handle for use
199
* by us in case thread.p->threadH gets NULLed later but before we've
200
* finished with it here.
203
#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__)
207
(HANDLE) _beginthreadex ((void *) NULL, /* No security info */
208
(unsigned) stackSize, /* default stack size */
213
(unsigned *) &(tp->thread));
219
(void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
224
ResumeThread (threadH);
228
#else /* __MINGW32__ && ! __MSVCRT__ */
231
* This lock will force pthread_threadStart() to wait until we have
232
* the thread handle and have set the priority.
234
(void) pthread_mutex_lock (&tp->cancelLock);
238
(HANDLE) _beginthread (ptw32_threadStart, (unsigned) stackSize, /* default stack size */
242
* Make the return code match _beginthreadex's.
244
if (threadH == (HANDLE) - 1L)
246
tp->threadH = threadH = 0;
253
* beginthread does not allow for create flags, so we do it now.
254
* Note that beginthread itself creates the thread in SUSPENDED
255
* mode, and then calls ResumeThread to start it.
257
SuspendThread (threadH);
262
(void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
266
(void) pthread_mutex_unlock (&tp->cancelLock);
268
#endif /* __MINGW32__ && ! __MSVCRT__ */
270
result = (threadH != 0) ? 0 : EAGAIN;
273
* Fall Through Intentionally
286
ptw32_threadDestroy (thread);
305
} /* pthread_create */