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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years ago) by william
File MIME type: text/plain
File size: 7941 byte(s)
committing r3113 initial commit again...
1 william 31 /*
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