2009-05-21 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mono / io-layer / wthreads.c
1 /*
2  * threads.c:  Thread handles
3  *
4  * Author:
5  *      Dick Porter (dick@ximian.com)
6  *
7  * (C) 2002-2006 Ximian, Inc.
8  */
9
10 #include <config.h>
11 #include <stdio.h>
12 #include <glib.h>
13 #include <string.h>
14 #include <mono/utils/gc_wrapper.h>
15 #include <pthread.h>
16 #include <signal.h>
17 #include <sched.h>
18 #include <sys/time.h>
19 #include <errno.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include <mono/io-layer/wapi.h>
24 #include <mono/io-layer/wapi-private.h>
25 #include <mono/io-layer/handles-private.h>
26 #include <mono/io-layer/misc-private.h>
27 #include <mono/io-layer/mono-mutex.h>
28 #include <mono/io-layer/thread-private.h>
29 #include <mono/io-layer/mono-spinlock.h>
30 #include <mono/io-layer/mutex-private.h>
31 #include <mono/io-layer/atomic.h>
32
33 #ifdef HAVE_VALGRIND_MEMCHECK_H
34 #include <valgrind/memcheck.h>
35 #endif
36
37 #undef DEBUG
38 #undef TLS_DEBUG
39
40 #if 0
41 #define WAIT_DEBUG(code) do { code } while (0)
42 #else
43 #define WAIT_DEBUG(code) do { } while (0)
44 #endif
45
46 /* Hash threads with tids. I thought of using TLS for this, but that
47  * would have to set the data in the new thread, which is more hassle
48  */
49 static mono_once_t thread_hash_once = MONO_ONCE_INIT;
50 static pthread_key_t thread_hash_key;
51
52 /* This key is used with attached threads and a destructor to signal
53  * when attached threads exit, as they don't have the thread_exit()
54  * infrastructure
55  */
56 static pthread_key_t thread_attached_key;
57
58 struct _WapiHandleOps _wapi_thread_ops = {
59         NULL,                           /* close */
60         NULL,                           /* signal */
61         NULL,                           /* own */
62         NULL,                           /* is_owned */
63         NULL,                           /* special_wait */
64         NULL                            /* prewait */
65 };
66
67 static mono_once_t thread_ops_once=MONO_ONCE_INIT;
68
69 static void thread_ops_init (void)
70 {
71         _wapi_handle_register_capabilities (WAPI_HANDLE_THREAD,
72                                             WAPI_HANDLE_CAP_WAIT);
73 }
74
75 void _wapi_thread_cleanup (void)
76 {
77         int ret;
78         
79         ret = pthread_key_delete (thread_hash_key);
80         g_assert (ret == 0);
81         
82         ret = pthread_key_delete (thread_attached_key);
83         g_assert (ret == 0);
84 }
85
86 /* Called by thread_exit(), but maybe indirectly by
87  * mono_thread_manage() via mono_thread_signal_self() too
88  */
89 static void _wapi_thread_abandon_mutexes (gpointer handle)
90 {
91         struct _WapiHandle_thread *thread_handle;
92         gboolean ok;
93         int i;
94         pid_t pid = _wapi_getpid ();
95         pthread_t tid = pthread_self ();
96         
97 #ifdef DEBUG
98         g_message ("%s: Thread %p abandoning held mutexes", __func__, handle);
99 #endif
100
101         if (handle == NULL) {
102                 handle = _wapi_thread_handle_from_id (pthread_self ());
103                 if (handle == NULL) {
104                         /* Something gone badly wrong... */
105                         return;
106                 }
107         }
108         
109         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
110                                   (gpointer *)&thread_handle);
111         if (ok == FALSE) {
112                 g_warning ("%s: error looking up thread handle %p", __func__,
113                            handle);
114                 return;
115         }
116         
117         if (!pthread_equal (thread_handle->id, tid)) {
118                 return;
119         }
120         
121         for (i = 0; i < thread_handle->owned_mutexes->len; i++) {
122                 gpointer mutex = g_ptr_array_index (thread_handle->owned_mutexes, i);
123                 
124                 _wapi_mutex_abandon (mutex, pid, tid);
125                 _wapi_thread_disown_mutex (mutex);
126         }
127 }
128
129 void _wapi_thread_set_termination_details (gpointer handle,
130                                            guint32 exitstatus)
131 {
132         struct _WapiHandle_thread *thread_handle;
133         gboolean ok;
134         int thr_ret;
135         
136         if (_wapi_handle_issignalled (handle) ||
137             _wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
138                 /* We must have already deliberately finished with
139                  * this thread, so don't do any more now
140                  */
141                 return;
142         }
143
144 #ifdef DEBUG
145         g_message ("%s: Thread %p terminating", __func__, handle);
146 #endif
147
148         _wapi_thread_abandon_mutexes (handle);
149         
150         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
151                                   (gpointer *)&thread_handle);
152         if (ok == FALSE) {
153                 g_warning ("%s: error looking up thread handle %p", __func__,
154                            handle);
155
156                 return;
157         }
158         
159         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
160                               handle);
161         thr_ret = _wapi_handle_lock_handle (handle);
162         g_assert (thr_ret == 0);
163         
164         thread_handle->exitstatus = exitstatus;
165         thread_handle->state = THREAD_STATE_EXITED;
166         MONO_SEM_DESTROY (&thread_handle->suspend_sem);
167         g_ptr_array_free (thread_handle->owned_mutexes, TRUE);
168
169         _wapi_handle_set_signal_state (handle, TRUE, TRUE);
170
171         thr_ret = _wapi_handle_unlock_handle (handle);
172         g_assert (thr_ret == 0);
173         pthread_cleanup_pop (0);
174         
175 #ifdef DEBUG
176         g_message("%s: Recording thread handle %p id %ld status as %d",
177                   __func__, handle, thread_handle->id, exitstatus);
178 #endif
179         
180         /* The thread is no longer active, so unref it */
181         _wapi_handle_unref (handle);
182 }
183
184 void _wapi_thread_signal_self (guint32 exitstatus)
185 {
186         gpointer handle;
187         
188         handle = _wapi_thread_handle_from_id (pthread_self ());
189         if (handle == NULL) {
190                 /* Something gone badly wrong... */
191                 return;
192         }
193         
194         _wapi_thread_set_termination_details (handle, exitstatus);
195 }
196
197 /* Called by the thread creation code as a thread is finishing up, and
198  * by ExitThread()
199 */
200 static void thread_exit (guint32 exitstatus, gpointer handle) G_GNUC_NORETURN;
201 static void thread_exit (guint32 exitstatus, gpointer handle)
202 {
203         _wapi_thread_set_termination_details (handle, exitstatus);
204         
205         /* Call pthread_exit() to call destructors and really exit the
206          * thread
207          */
208         pthread_exit (NULL);
209 }
210
211 static void thread_attached_exit (gpointer handle)
212 {
213         /* Drop the extra reference we take in thread_attach, now this
214          * thread is dead
215          */
216         
217         _wapi_thread_set_termination_details (handle, 0);
218 }
219
220 static void thread_hash_init(void)
221 {
222         int thr_ret;
223         
224         thr_ret = pthread_key_create (&thread_hash_key, NULL);
225         g_assert (thr_ret == 0);
226
227         thr_ret = pthread_key_create (&thread_attached_key,
228                                       thread_attached_exit);
229         g_assert (thr_ret == 0);
230 }
231
232 static void _wapi_thread_suspend (struct _WapiHandle_thread *thread)
233 {
234         g_assert (pthread_equal (thread->id, pthread_self ()));
235         
236         while (MONO_SEM_WAIT (&thread->suspend_sem) != 0 &&
237                errno == EINTR);
238 }
239
240 static void _wapi_thread_resume (struct _WapiHandle_thread *thread)
241 {
242         MONO_SEM_POST (&thread->suspend_sem);
243 }
244
245 static void *thread_start_routine (gpointer args) G_GNUC_NORETURN;
246 static void *thread_start_routine (gpointer args)
247 {
248         struct _WapiHandle_thread *thread = (struct _WapiHandle_thread *)args;
249         int thr_ret;
250         
251         thr_ret = pthread_detach (pthread_self ());
252         g_assert (thr_ret == 0);
253
254         thr_ret = pthread_setspecific (thread_hash_key,
255                                        (void *)thread->handle);
256         if (thr_ret != 0) {
257                 /* This is only supposed to happen when Mono is
258                    shutting down.  We cannot assert on it, though,
259                    because we must not depend on metadata, which is
260                    where the shutdown code is.
261
262                    This is a race condition which arises because
263                    pthreads don't allow creation of suspended threads.
264                    Once Mono is set to shut down no new thread is
265                    allowed to start, even though threads may still be
266                    created.  We emulate suspended threads in this
267                    function by calling _wapi_thread_suspend() below.
268
269                    So it can happen that even though Mono is already
270                    shutting down we still end up here, and at this
271                    point the thread_hash_key might already be
272                    destroyed. */
273                 pthread_exit (NULL);
274         }
275
276         thread->id = pthread_self();
277
278 #ifdef DEBUG
279         g_message ("%s: started thread id %ld", __func__, thread->id);
280 #endif
281
282         if (thread->create_flags & CREATE_SUSPENDED) {
283                 _wapi_thread_suspend (thread);
284         }
285         
286         thread_exit (thread->start_routine (thread->start_arg),
287                      thread->handle);
288
289 #ifndef __GNUC__
290         /* Even though we tell gcc that this function doesn't return,
291          * other compilers won't see that.
292          */
293         return(NULL);
294 #endif
295 }
296
297 /**
298  * CreateThread:
299  * @security: Ignored for now.
300  * @stacksize: the size in bytes of the new thread's stack. Use 0 to
301  * default to the normal stack size. (Ignored for now).
302  * @start: The function that the new thread should start with
303  * @param: The parameter to give to @start.
304  * @create: If 0, the new thread is ready to run immediately.  If
305  * %CREATE_SUSPENDED, the new thread will be in the suspended state,
306  * requiring a ResumeThread() call to continue running.
307  * @tid: If non-NULL, the ID of the new thread is stored here.  NB
308  * this is defined as a DWORD (ie 32bit) in the MS API, but we need to
309  * cope with 64 bit IDs for s390x and amd64.
310  *
311  * Creates a new threading handle.
312  *
313  * Return value: a new handle, or NULL
314  */
315 gpointer CreateThread(WapiSecurityAttributes *security G_GNUC_UNUSED, guint32 stacksize,
316                       WapiThreadStart start, gpointer param, guint32 create,
317                       gsize *tid) 
318 {
319         struct _WapiHandle_thread thread_handle = {0}, *thread_handle_p;
320         pthread_attr_t attr;
321         gpointer handle;
322         gboolean ok;
323         int ret;
324         int thr_ret;
325         int i, unrefs = 0;
326         gpointer ct_ret = NULL;
327         
328         mono_once (&thread_hash_once, thread_hash_init);
329         mono_once (&thread_ops_once, thread_ops_init);
330         
331         if (start == NULL) {
332                 return(NULL);
333         }
334
335         thread_handle.state = THREAD_STATE_START;
336         thread_handle.owned_mutexes = g_ptr_array_new ();
337         thread_handle.create_flags = create;
338         thread_handle.start_routine = start;
339         thread_handle.start_arg = param;
340         
341         handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
342         if (handle == _WAPI_HANDLE_INVALID) {
343                 g_warning ("%s: error creating thread handle", __func__);
344                 SetLastError (ERROR_GEN_FAILURE);
345                 
346                 return (NULL);
347         }
348
349         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
350                               handle);
351         thr_ret = _wapi_handle_lock_handle (handle);
352         g_assert (thr_ret == 0);
353         
354         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
355                                   (gpointer *)&thread_handle_p);
356         if (ok == FALSE) {
357                 g_warning ("%s: error looking up thread handle %p", __func__,
358                            handle);
359                 SetLastError (ERROR_GEN_FAILURE);
360                 
361                 goto cleanup;
362         }
363
364         /* Hold a reference while the thread is active, because we use
365          * the handle to store thread exit information
366          */
367         _wapi_handle_ref (handle);
368         
369         /* Set a 2M stack size.  This is the default on Linux, but BSD
370          * needs it.  (The original bug report from Martin Dvorak <md@9ll.cz>
371          * set the size to 2M-4k.  I don't know why it's short by 4k, so
372          * I'm leaving it as 2M until I'm told differently.)
373          */
374         thr_ret = pthread_attr_init(&attr);
375         g_assert (thr_ret == 0);
376         
377         /* defaults of 2Mb for 32bits and 4Mb for 64bits */
378         /* temporarily changed to use 1 MB: this allows more threads
379          * to be used, as well as using less virtual memory and so
380          * more is available for the GC heap.
381          */
382         if (stacksize == 0){
383 #if HAVE_VALGRIND_MEMCHECK_H
384                 if (RUNNING_ON_VALGRIND) {
385                         stacksize = 1 << 20;
386                 } else {
387                         stacksize = (SIZEOF_VOID_P / 4) * 1024 * 1024;
388                 }
389 #else
390                 stacksize = (SIZEOF_VOID_P / 4) * 1024 * 1024;
391 #endif
392         }
393
394 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
395         thr_ret = pthread_attr_setstacksize(&attr, stacksize);
396         g_assert (thr_ret == 0);
397 #endif
398
399         MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
400         thread_handle_p->handle = handle;
401         
402
403         ret = pthread_create (&thread_handle_p->id, &attr,
404                               thread_start_routine, (void *)thread_handle_p);
405 #ifdef MONO_REGISTER_THREAD_ATTR
406         mono_register_thread_attr (&attr, &thread_handle_p->id);
407 #endif
408
409         if (ret != 0) {
410 #ifdef DEBUG
411                 g_message ("%s: Thread create error: %s", __func__,
412                            strerror(ret));
413 #endif
414
415                 /* Two, because of the reference we took above */
416                 unrefs = 2;
417                 
418                 goto cleanup;
419         }
420         ct_ret = handle;
421         
422 #ifdef DEBUG
423         g_message("%s: Started thread handle %p ID %ld", __func__, handle,
424                   thread_handle_p->id);
425 #endif
426         
427         if (tid != NULL) {
428 #ifdef PTHREAD_POINTER_ID
429                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
430                  * sizeof(void *) > sizeof(uint) when a cast to uint
431                  * would overflow
432                  */
433                 *tid = (gsize)(thread_handle_p->id);
434 #else
435                 *tid = thread_handle_p->id;
436 #endif
437         }
438
439 cleanup:
440         thr_ret = _wapi_handle_unlock_handle (handle);
441         g_assert (thr_ret == 0);
442         pthread_cleanup_pop (0);
443         
444         /* Must not call _wapi_handle_unref() with the shared handles
445          * already locked
446          */
447         for (i = 0; i < unrefs; i++) {
448                 _wapi_handle_unref (handle);
449         }
450         
451         return(ct_ret);
452 }
453
454 /* The only time this function is called when tid != pthread_self ()
455  * is from OpenThread (), so we can fast-path most cases by just
456  * looking up the handle in TLS.  OpenThread () must cope with a NULL
457  * return and do a handle search in that case.
458  */
459 gpointer _wapi_thread_handle_from_id (pthread_t tid)
460 {
461         gpointer ret;
462
463         if (pthread_equal (tid, pthread_self ()) &&
464             (ret = pthread_getspecific (thread_hash_key)) != NULL) {
465                 /* We know the handle */
466
467 #ifdef DEBUG
468                 g_message ("%s: Returning %p for self thread %ld from TLS",
469                            __func__, ret, tid);
470 #endif
471                 
472                 return(ret);
473         }
474         
475 #ifdef DEBUG
476         g_message ("%s: Returning NULL for unknown or non-self thread %ld",
477                    __func__, tid);
478 #endif
479                 
480
481         return(NULL);
482 }
483
484 static gboolean find_thread_by_id (gpointer handle, gpointer user_data)
485 {
486         pthread_t tid = (pthread_t)user_data;
487         struct _WapiHandle_thread *thread_handle;
488         gboolean ok;
489         
490         /* Ignore threads that have already exited (ie they are signalled) */
491         if (_wapi_handle_issignalled (handle) == FALSE) {
492                 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
493                                           (gpointer *)&thread_handle);
494                 if (ok == FALSE) {
495                         /* It's possible that the handle has vanished
496                          * during the _wapi_search_handle before it
497                          * gets here, so don't spam the console with
498                          * warnings.
499                          */
500                         return(FALSE);
501                 }
502                 
503 #ifdef DEBUG
504                 g_message ("%s: looking at thread %ld from process %d", __func__, thread_handle->id, 0);
505 #endif
506
507                 if (pthread_equal (thread_handle->id, tid)) {
508 #ifdef DEBUG
509                         g_message ("%s: found the thread we are looking for",
510                                    __func__);
511 #endif
512                         return(TRUE);
513                 }
514         }
515         
516 #ifdef DEBUG
517         g_message ("%s: not found %ld, returning FALSE", __func__, tid);
518 #endif
519         
520         return(FALSE);
521 }
522
523 /* NB tid is 32bit in MS API, but we need 64bit on amd64 and s390x
524  * (and probably others)
525  */
526 gpointer OpenThread (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, gsize tid)
527 {
528         gpointer ret=NULL;
529         
530         mono_once (&thread_hash_once, thread_hash_init);
531         mono_once (&thread_ops_once, thread_ops_init);
532         
533 #ifdef DEBUG
534         g_message ("%s: looking up thread %"G_GSIZE_FORMAT, __func__, tid);
535 #endif
536
537         ret = _wapi_thread_handle_from_id ((pthread_t)tid);
538         if (ret == NULL) {
539                 /* We need to search for this thread */
540                 ret = _wapi_search_handle (WAPI_HANDLE_THREAD, find_thread_by_id, (gpointer)tid, NULL, FALSE/*TRUE*/);  /* FIXME: have a proper look at this, me might not need to set search_shared = TRUE */
541         } else {
542                 /* if _wapi_search_handle() returns a found handle, it
543                  * refs it itself
544                  */
545                 _wapi_handle_ref (ret);
546         }
547         
548 #ifdef DEBUG
549         g_message ("%s: returning thread handle %p", __func__, ret);
550 #endif
551         
552         return(ret);
553 }
554
555 /**
556  * ExitThread:
557  * @exitcode: Sets the thread's exit code, which can be read from
558  * another thread with GetExitCodeThread().
559  *
560  * Terminates the calling thread.  A thread can also exit by returning
561  * from its start function. When the last thread in a process
562  * terminates, the process itself terminates.
563  */
564 void ExitThread(guint32 exitcode)
565 {
566         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
567         
568         if (thread != NULL) {
569                 thread_exit(exitcode, thread);
570         } else {
571                 /* Just blow this thread away */
572                 pthread_exit (NULL);
573         }
574 }
575
576 /**
577  * GetExitCodeThread:
578  * @handle: The thread handle to query
579  * @exitcode: The thread @handle exit code is stored here
580  *
581  * Finds the exit code of @handle, and stores it in @exitcode.  If the
582  * thread @handle is still running, the value stored is %STILL_ACTIVE.
583  *
584  * Return value: %TRUE, or %FALSE on error.
585  */
586 gboolean GetExitCodeThread(gpointer handle, guint32 *exitcode)
587 {
588         struct _WapiHandle_thread *thread_handle;
589         gboolean ok;
590         
591         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
592                                   (gpointer *)&thread_handle);
593         if (ok == FALSE) {
594                 g_warning ("%s: error looking up thread handle %p", __func__,
595                            handle);
596                 return (FALSE);
597         }
598         
599 #ifdef DEBUG
600         g_message ("%s: Finding exit status for thread handle %p id %ld",
601                    __func__, handle, thread_handle->id);
602 #endif
603
604         if (exitcode == NULL) {
605 #ifdef DEBUG
606                 g_message ("%s: Nowhere to store exit code", __func__);
607 #endif
608                 return(FALSE);
609         }
610         
611         if (thread_handle->state != THREAD_STATE_EXITED) {
612 #ifdef DEBUG
613                 g_message ("%s: Thread still active (state %d, exited is %d)",
614                            __func__, thread_handle->state,
615                            THREAD_STATE_EXITED);
616 #endif
617                 *exitcode = STILL_ACTIVE;
618                 return(TRUE);
619         }
620         
621         *exitcode = thread_handle->exitstatus;
622         
623         return(TRUE);
624 }
625
626 /**
627  * GetCurrentThreadId:
628  *
629  * Looks up the thread ID of the current thread.  This ID can be
630  * passed to OpenThread() to create a new handle on this thread.
631  *
632  * Return value: the thread ID.  NB this is defined as DWORD (ie 32
633  * bit) in the MS API, but we need to cope with 64 bit IDs for s390x
634  * and amd64.  This doesn't really break the API, it just embraces and
635  * extends it on 64bit platforms :)
636  */
637 gsize GetCurrentThreadId(void)
638 {
639         pthread_t tid = pthread_self();
640         
641 #ifdef PTHREAD_POINTER_ID
642         /* Don't use GPOINTER_TO_UINT here, it can't cope with
643          * sizeof(void *) > sizeof(uint) when a cast to uint would
644          * overflow
645          */
646         return((gsize)tid);
647 #else
648         return(tid);
649 #endif
650 }
651
652 static gpointer thread_attach(gsize *tid)
653 {
654         struct _WapiHandle_thread thread_handle = {0}, *thread_handle_p;
655         gpointer handle;
656         gboolean ok;
657         int thr_ret;
658         
659         mono_once (&thread_hash_once, thread_hash_init);
660         mono_once (&thread_ops_once, thread_ops_init);
661
662         thread_handle.state = THREAD_STATE_START;
663         thread_handle.owned_mutexes = g_ptr_array_new ();
664
665         handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
666         if (handle == _WAPI_HANDLE_INVALID) {
667                 g_warning ("%s: error creating thread handle", __func__);
668                 
669                 SetLastError (ERROR_GEN_FAILURE);
670                 return (NULL);
671         }
672
673         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
674                               handle);
675         thr_ret = _wapi_handle_lock_handle (handle);
676         g_assert (thr_ret == 0);
677         
678         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
679                                   (gpointer *)&thread_handle_p);
680         if (ok == FALSE) {
681                 g_warning ("%s: error looking up thread handle %p", __func__,
682                            handle);
683                 
684                 SetLastError (ERROR_GEN_FAILURE);
685                 goto cleanup;
686         }
687
688         /* Hold a reference while the thread is active, because we use
689          * the handle to store thread exit information
690          */
691         _wapi_handle_ref (handle);
692
693         /* suspend_sem is not used for attached threads, but
694          * thread_exit() might try to destroy it
695          */
696         MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
697         thread_handle_p->handle = handle;
698         thread_handle_p->id = pthread_self ();
699
700         thr_ret = pthread_setspecific (thread_hash_key, (void *)handle);
701         g_assert (thr_ret == 0);
702
703         thr_ret = pthread_setspecific (thread_attached_key, (void *)handle);
704         g_assert (thr_ret == 0);
705         
706 #ifdef DEBUG
707         g_message("%s: Attached thread handle %p ID %ld", __func__, handle,
708                   thread_handle_p->id);
709 #endif
710
711         if (tid != NULL) {
712 #ifdef PTHREAD_POINTER_ID
713                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
714                  * sizeof(void *) > sizeof(uint) when a cast to uint
715                  * would overflow
716                  */
717                 *tid = (gsize)(thread_handle_p->id);
718 #else
719                 *tid = thread_handle_p->id;
720 #endif
721         }
722
723 cleanup:
724         thr_ret = _wapi_handle_unlock_handle (handle);
725         g_assert (thr_ret == 0);
726         pthread_cleanup_pop (0);
727         
728         return(handle);
729 }
730
731 gpointer _wapi_thread_duplicate ()
732 {
733         gpointer ret = NULL;
734         
735         mono_once (&thread_hash_once, thread_hash_init);
736         mono_once (&thread_ops_once, thread_ops_init);
737         
738         ret = _wapi_thread_handle_from_id (pthread_self ());
739         if (!ret) {
740                 ret = thread_attach (NULL);
741         } else {
742                 _wapi_handle_ref (ret);
743         }
744         
745         return(ret);
746 }
747
748 /**
749  * GetCurrentThread:
750  *
751  * Looks up the handle associated with the current thread.  Under
752  * Windows this is a pseudohandle, and must be duplicated with
753  * DuplicateHandle() for some operations.
754  *
755  * Return value: The current thread handle, or %NULL on failure.
756  * (Unknown whether Windows has a possible failure here.  It may be
757  * necessary to implement the pseudohandle-constant behaviour).
758  */
759 gpointer GetCurrentThread(void)
760 {
761         mono_once(&thread_hash_once, thread_hash_init);
762         mono_once (&thread_ops_once, thread_ops_init);
763         
764         return(_WAPI_THREAD_CURRENT);
765 }
766
767 /**
768  * ResumeThread:
769  * @handle: the thread handle to resume
770  *
771  * Decrements the suspend count of thread @handle. A thread can only
772  * run if its suspend count is zero.
773  *
774  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
775  */
776 guint32 ResumeThread(gpointer handle)
777 {
778         struct _WapiHandle_thread *thread_handle;
779         gboolean ok;
780         
781         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
782                                   (gpointer *)&thread_handle);
783         if (ok == FALSE) {
784                 g_warning ("%s: error looking up thread handle %p", __func__,
785                            handle);
786                 
787                 return (0xFFFFFFFF);
788         }
789
790         /* This is still a kludge that only copes with starting a
791          * thread that was suspended on create, so don't bother with
792          * the suspend count crap yet
793          */
794         _wapi_thread_resume (thread_handle);
795         return(0xFFFFFFFF);
796 }
797
798 /**
799  * SuspendThread:
800  * @handle: the thread handle to suspend
801  *
802  * Increments the suspend count of thread @handle. A thread can only
803  * run if its suspend count is zero.
804  *
805  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
806  */
807 guint32 SuspendThread(gpointer handle)
808 {
809         return(0xFFFFFFFF);
810 }
811
812 /*
813  * We assume here that TLS_MINIMUM_AVAILABLE is less than
814  * PTHREAD_KEYS_MAX, allowing enough overhead for a few TLS keys for
815  * library usage.
816  *
817  * Currently TLS_MINIMUM_AVAILABLE is 64 and _POSIX_THREAD_KEYS_MAX
818  * (the minimum value for PTHREAD_KEYS_MAX) is 128, so we should be
819  * fine.
820  */
821
822 static pthread_key_t TLS_keys[TLS_MINIMUM_AVAILABLE];
823 static gboolean TLS_used[TLS_MINIMUM_AVAILABLE]={FALSE};
824 static guint32 TLS_spinlock=0;
825
826 guint32
827 mono_pthread_key_for_tls (guint32 idx)
828 {
829         return (guint32)TLS_keys [idx];
830 }
831
832 /**
833  * TlsAlloc:
834  *
835  * Allocates a Thread Local Storage (TLS) index.  Any thread in the
836  * same process can use this index to store and retrieve values that
837  * are local to that thread.
838  *
839  * Return value: The index value, or %TLS_OUT_OF_INDEXES if no index
840  * is available.
841  */
842 guint32 TlsAlloc(void)
843 {
844         guint32 i;
845         int thr_ret;
846         
847         MONO_SPIN_LOCK (TLS_spinlock);
848         
849         for(i=0; i<TLS_MINIMUM_AVAILABLE; i++) {
850                 if(TLS_used[i]==FALSE) {
851                         TLS_used[i]=TRUE;
852                         thr_ret = pthread_key_create(&TLS_keys[i], NULL);
853                         g_assert (thr_ret == 0);
854
855                         MONO_SPIN_UNLOCK (TLS_spinlock);
856         
857 #ifdef TLS_DEBUG
858                         g_message ("%s: returning key %d", __func__, i);
859 #endif
860                         
861                         return(i);
862                 }
863         }
864
865         MONO_SPIN_UNLOCK (TLS_spinlock);
866         
867 #ifdef TLS_DEBUG
868         g_message ("%s: out of indices", __func__);
869 #endif
870                         
871         
872         return(TLS_OUT_OF_INDEXES);
873 }
874
875 #define MAKE_GC_ID(idx) (GUINT_TO_POINTER((idx)|(GetCurrentThreadId()<<8)))
876
877 /**
878  * TlsFree:
879  * @idx: The TLS index to free
880  *
881  * Releases a TLS index, making it available for reuse.  This call
882  * will delete any TLS data stored under index @idx in all threads.
883  *
884  * Return value: %TRUE on success, %FALSE otherwise.
885  */
886 gboolean TlsFree(guint32 idx)
887 {
888         int thr_ret;
889         
890 #ifdef TLS_DEBUG
891         g_message ("%s: freeing key %d", __func__, idx);
892 #endif
893
894         MONO_SPIN_LOCK (TLS_spinlock);
895         
896         if(TLS_used[idx]==FALSE) {
897                 MONO_SPIN_UNLOCK (TLS_spinlock);
898
899                 return(FALSE);
900         }
901         
902         TLS_used[idx]=FALSE;
903         thr_ret = pthread_key_delete(TLS_keys[idx]);
904         g_assert (thr_ret == 0);
905         
906         MONO_SPIN_UNLOCK (TLS_spinlock);
907         
908         return(TRUE);
909 }
910
911 /**
912  * TlsGetValue:
913  * @idx: The TLS index to retrieve
914  *
915  * Retrieves the TLS data stored under index @idx.
916  *
917  * Return value: The value stored in the TLS index @idx in the current
918  * thread, or %NULL on error.  As %NULL can be a valid return value,
919  * in this case GetLastError() returns %ERROR_SUCCESS.
920  */
921 gpointer TlsGetValue(guint32 idx)
922 {
923         gpointer ret;
924         
925 #ifdef TLS_DEBUG
926         g_message ("%s: looking up key %d", __func__, idx);
927 #endif
928         
929         ret=pthread_getspecific(TLS_keys[idx]);
930
931 #ifdef TLS_DEBUG
932         g_message ("%s: returning %p", __func__, ret);
933 #endif
934         
935         return(ret);
936 }
937
938 /**
939  * TlsSetValue:
940  * @idx: The TLS index to store
941  * @value: The value to store under index @idx
942  *
943  * Stores @value at TLS index @idx.
944  *
945  * Return value: %TRUE on success, %FALSE otherwise.
946  */
947 gboolean TlsSetValue(guint32 idx, gpointer value)
948 {
949         int ret;
950
951 #ifdef TLS_DEBUG
952         g_message ("%s: setting key %d to %p", __func__, idx, value);
953 #endif
954         
955         MONO_SPIN_LOCK (TLS_spinlock);
956         
957         if(TLS_used[idx]==FALSE) {
958 #ifdef TLS_DEBUG
959                 g_message ("%s: key %d unused", __func__, idx);
960 #endif
961
962                 MONO_SPIN_UNLOCK (TLS_spinlock);
963
964                 return(FALSE);
965         }
966         
967         ret=pthread_setspecific(TLS_keys[idx], value);
968         if(ret!=0) {
969 #ifdef TLS_DEBUG
970                 g_message ("%s: pthread_setspecific error: %s", __func__,
971                            strerror (ret));
972 #endif
973
974                 MONO_SPIN_UNLOCK (TLS_spinlock);
975
976                 return(FALSE);
977         }
978         
979         MONO_SPIN_UNLOCK (TLS_spinlock);
980         
981         return(TRUE);
982 }
983
984 /**
985  * SleepEx:
986  * @ms: The time in milliseconds to suspend for
987  * @alertable: if TRUE, the wait can be interrupted by an APC call
988  *
989  * Suspends execution of the current thread for @ms milliseconds.  A
990  * value of zero causes the thread to relinquish its time slice.  A
991  * value of %INFINITE causes an infinite delay.
992  */
993 guint32 SleepEx(guint32 ms, gboolean alertable)
994 {
995         struct timespec req, rem;
996         int ms_quot, ms_rem;
997         int ret;
998         gpointer current_thread = NULL;
999         
1000 #ifdef DEBUG
1001         g_message("%s: Sleeping for %d ms", __func__, ms);
1002 #endif
1003
1004         if (alertable) {
1005                 current_thread = _wapi_thread_handle_from_id (pthread_self ());
1006                 if (current_thread == NULL) {
1007                         SetLastError (ERROR_INVALID_HANDLE);
1008                         return(WAIT_FAILED);
1009                 }
1010                 
1011                 if (_wapi_thread_apc_pending (current_thread)) {
1012                         _wapi_thread_dispatch_apc_queue (current_thread);
1013                         return WAIT_IO_COMPLETION;
1014                 }
1015         }
1016         
1017         if(ms==0) {
1018                 sched_yield();
1019                 return 0;
1020         }
1021         
1022         /* FIXME: check for INFINITE and sleep forever */
1023         ms_quot = ms / 1000;
1024         ms_rem = ms % 1000;
1025         
1026         req.tv_sec=ms_quot;
1027         req.tv_nsec=ms_rem*1000000;
1028         
1029 again:
1030         ret=nanosleep(&req, &rem);
1031
1032         if (alertable && _wapi_thread_apc_pending (current_thread)) {
1033                 _wapi_thread_dispatch_apc_queue (current_thread);
1034                 return WAIT_IO_COMPLETION;
1035         }
1036         
1037         if(ret==-1) {
1038                 /* Sleep interrupted with rem time remaining */
1039 #ifdef DEBUG
1040                 guint32 rems=rem.tv_sec*1000 + rem.tv_nsec/1000000;
1041                 
1042                 g_message("%s: Still got %d ms to go", __func__, rems);
1043 #endif
1044                 req=rem;
1045                 goto again;
1046         }
1047
1048         return 0;
1049 }
1050
1051 void Sleep(guint32 ms)
1052 {
1053         SleepEx(ms, FALSE);
1054 }
1055
1056 gboolean _wapi_thread_cur_apc_pending (void)
1057 {
1058         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
1059         
1060         if (thread == NULL) {
1061                 SetLastError (ERROR_INVALID_HANDLE);
1062                 return(FALSE);
1063         }
1064         
1065         return(_wapi_thread_apc_pending (thread));
1066 }
1067
1068 gboolean _wapi_thread_apc_pending (gpointer handle)
1069 {
1070         struct _WapiHandle_thread *thread;
1071         gboolean ok;
1072         
1073         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1074                                   (gpointer *)&thread);
1075         if (ok == FALSE) {
1076 #ifdef DEBUG
1077                 /* This might happen at process shutdown, as all
1078                  * thread handles are forcibly closed.  If a thread
1079                  * still has an alertable wait the final
1080                  * _wapi_thread_apc_pending check will probably fail
1081                  * to find the handle
1082                  */
1083                 g_warning ("%s: error looking up thread handle %p", __func__,
1084                            handle);
1085 #endif
1086                 return (FALSE);
1087         }
1088         
1089         return(thread->has_apc || thread->wait_handle == INTERRUPTION_REQUESTED_HANDLE);
1090 }
1091
1092 gboolean _wapi_thread_dispatch_apc_queue (gpointer handle)
1093 {
1094         /* We don't support calling APC functions */
1095         struct _WapiHandle_thread *thread;
1096         gboolean ok;
1097         
1098         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1099                                   (gpointer *)&thread);
1100         g_assert (ok);
1101
1102         thread->has_apc = FALSE;
1103
1104         return(TRUE);
1105 }
1106
1107 /*
1108  * In this implementation, APC_CALLBACK is ignored.
1109  * if HANDLE refers to the current thread, the only effect this function has 
1110  * that if called from a signal handler, and the thread was waiting when receiving 
1111  * the signal, the wait will be broken after the signal handler returns.
1112  * In this case, this function is async-signal-safe.
1113  */
1114 guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer handle, 
1115                       gpointer param)
1116 {
1117         struct _WapiHandle_thread *thread_handle;
1118         gboolean ok;
1119         
1120         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1121                                   (gpointer *)&thread_handle);
1122         if (ok == FALSE) {
1123                 g_warning ("%s: error looking up thread handle %p", __func__,
1124                            handle);
1125                 return (0);
1126         }
1127
1128         g_assert (thread_handle->id == GetCurrentThreadId ());
1129         /* No locking/memory barriers are needed here */
1130         thread_handle->has_apc = TRUE;
1131         return(1);
1132 }
1133
1134 /*
1135  * wapi_interrupt_thread:
1136  *
1137  *   This is not part of the WIN32 API.
1138  * The state of the thread handle HANDLE is set to 'interrupted' which means that
1139  * if the thread calls one of the WaitFor functions, the function will return with 
1140  * WAIT_IO_COMPLETION instead of waiting. Also, if the thread was waiting when
1141  * this function was called, the wait will be broken.
1142  * It is possible that the wait functions return WAIT_IO_COMPLETION, but the
1143  * target thread didn't receive the interrupt signal yet, in this case it should
1144  * call the wait function again. This essentially means that the target thread will
1145  * busy wait until it is ready to process the interruption.
1146  * FIXME: get rid of QueueUserAPC and thread->has_apc, SleepEx seems to require it.
1147  */
1148 void wapi_interrupt_thread (gpointer thread_handle)
1149 {
1150         struct _WapiHandle_thread *thread;
1151         gboolean ok;
1152         gpointer prev_handle, wait_handle;
1153         guint32 idx;
1154         pthread_cond_t *cond;
1155         mono_mutex_t *mutex;
1156         
1157         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1158                                   (gpointer *)&thread);
1159         g_assert (ok);
1160
1161         while (TRUE) {
1162                 wait_handle = thread->wait_handle;
1163
1164                 /* 
1165                  * Atomically obtain the handle the thread is waiting on, and
1166                  * change it to a flag value.
1167                  */
1168                 prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1169                                                                                                                  INTERRUPTION_REQUESTED_HANDLE, wait_handle);
1170                 if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1171                         /* Already interrupted */
1172                         return;
1173                 if (prev_handle == wait_handle)
1174                         break;
1175
1176                 /* Try again */
1177         }
1178
1179         WAIT_DEBUG (printf ("%p: state -> INTERRUPTED.\n", thread_handle->id););
1180
1181         if (!wait_handle)
1182                 /* Not waiting */
1183                 return;
1184
1185         /* If we reach here, then wait_handle is set to the flag value, 
1186          * which means that the target thread is either
1187          * - before the first CAS in timedwait, which means it won't enter the
1188          * wait.
1189          * - it is after the first CAS, so it is already waiting, or it will 
1190          * enter the wait, and it will be interrupted by the broadcast.
1191          */
1192         idx = GPOINTER_TO_UINT(wait_handle);
1193         cond = &_WAPI_PRIVATE_HANDLES(idx).signal_cond;
1194         mutex = &_WAPI_PRIVATE_HANDLES(idx).signal_mutex;
1195
1196         mono_mutex_lock (mutex);
1197         mono_cond_broadcast (cond);
1198         mono_mutex_unlock (mutex);
1199
1200         /* ref added by set_wait_handle */
1201         _wapi_handle_unref (wait_handle);
1202 }
1203
1204 /*
1205  * wapi_clear_interruption:
1206  *
1207  *   This is not part of the WIN32 API. 
1208  * Clear the 'interrupted' state of the calling thread.
1209  */
1210 void wapi_clear_interruption (void)
1211 {
1212         struct _WapiHandle_thread *thread;
1213         gboolean ok;
1214         gpointer prev_handle;
1215         gpointer thread_handle;
1216
1217         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1218         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1219                                                           (gpointer *)&thread);
1220         g_assert (ok);
1221
1222         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1223                                                                                                          NULL, INTERRUPTION_REQUESTED_HANDLE);
1224         if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1225                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1226
1227         _wapi_handle_unref (thread_handle);
1228 }
1229
1230 char* wapi_current_thread_desc ()
1231 {
1232         struct _WapiHandle_thread *thread;
1233         int i;
1234         gboolean ok;
1235         gpointer handle;
1236         gpointer thread_handle;
1237         GString* text;
1238         char *res;
1239
1240         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1241         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1242                                                           (gpointer *)&thread);
1243         if (!ok)
1244                 return g_strdup_printf ("thread handle %p state : lookup failure", thread_handle);
1245
1246         handle = thread->wait_handle;
1247         text = g_string_new (0);
1248         g_string_append_printf (text, "thread handle %p state : ", thread_handle);
1249
1250         if (!handle)
1251                 g_string_append_printf (text, "not waiting");
1252         else if (handle == INTERRUPTION_REQUESTED_HANDLE)
1253                 g_string_append_printf (text, "interrupted state");
1254         else
1255                 g_string_append_printf (text, "waiting on %p : %s ", handle, _wapi_handle_typename[_wapi_handle_type (handle)]);
1256         g_string_append_printf (text, " owns (");
1257         for (i = 0; i < thread->owned_mutexes->len; i++) {
1258                 gpointer mutex = g_ptr_array_index (thread->owned_mutexes, i);
1259                 if (i > 0)
1260                         g_string_append_printf (text, ", %p", mutex);
1261                 else
1262                         g_string_append_printf (text, "%p", mutex);
1263         }
1264         g_string_append_printf (text, ")");
1265
1266         res = text->str;
1267         g_string_free (text, FALSE);
1268         return res;
1269 }
1270
1271 /**
1272  * wapi_thread_set_wait_handle:
1273  *
1274  *   Set the wait handle for the current thread to HANDLE. Return TRUE on success, FALSE
1275  * if the thread is in interrupted state, and cannot start waiting.
1276  */
1277 gboolean wapi_thread_set_wait_handle (gpointer handle)
1278 {
1279         struct _WapiHandle_thread *thread;
1280         gboolean ok;
1281         gpointer prev_handle;
1282         gpointer thread_handle;
1283
1284         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1285         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1286                                                           (gpointer *)&thread);
1287         g_assert (ok);
1288
1289         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1290                                                                                                          handle, NULL);
1291         _wapi_handle_unref (thread_handle);
1292
1293         if (prev_handle == NULL) {
1294                 /* thread->wait_handle acts as an additional reference to the handle */
1295                 _wapi_handle_ref (handle);
1296
1297                 WAIT_DEBUG (printf ("%p: state -> WAITING.\n", GetCurrentThreadId ()););
1298         } else {
1299                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
1300                 WAIT_DEBUG (printf ("%p: unable to set state to WAITING.\n", GetCurrentThreadId ()););
1301         }
1302
1303         return prev_handle == NULL;
1304 }
1305
1306 /**
1307  * wapi_thread_clear_wait_handle:
1308  *
1309  *   Clear the wait handle of the current thread.
1310  */
1311 void wapi_thread_clear_wait_handle (gpointer handle)
1312 {
1313         struct _WapiHandle_thread *thread;
1314         gboolean ok;
1315         gpointer prev_handle;
1316         gpointer thread_handle;
1317
1318         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1319         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1320                                                           (gpointer *)&thread);
1321         g_assert (ok);
1322
1323         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1324                                                                                                          NULL, handle);
1325
1326         if (prev_handle == handle) {
1327                 _wapi_handle_unref (handle);
1328                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1329         } else {
1330                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
1331                 WAIT_DEBUG (printf ("%p: finished waiting.\n", GetCurrentThreadId ()););
1332         }
1333
1334         _wapi_handle_unref (thread_handle);
1335 }
1336
1337 void _wapi_thread_own_mutex (gpointer mutex)
1338 {
1339         struct _WapiHandle_thread *thread_handle;
1340         gboolean ok;
1341         gpointer thread;
1342         
1343         thread = _wapi_thread_handle_from_id (pthread_self ());
1344         if (thread == NULL) {
1345                 g_warning ("%s: error looking up thread by ID", __func__);
1346                 return;
1347         }
1348
1349         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1350                                   (gpointer *)&thread_handle);
1351         if (ok == FALSE) {
1352                 g_warning ("%s: error looking up thread handle %p", __func__,
1353                            thread);
1354                 return;
1355         }
1356
1357         _wapi_handle_ref (mutex);
1358         
1359         g_ptr_array_add (thread_handle->owned_mutexes, mutex);
1360 }
1361
1362 void _wapi_thread_disown_mutex (gpointer mutex)
1363 {
1364         struct _WapiHandle_thread *thread_handle;
1365         gboolean ok;
1366         gpointer thread;
1367
1368         thread = _wapi_thread_handle_from_id (pthread_self ());
1369         if (thread == NULL) {
1370                 g_warning ("%s: error looking up thread by ID", __func__);
1371                 return;
1372         }
1373
1374         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1375                                   (gpointer *)&thread_handle);
1376         if (ok == FALSE) {
1377                 g_warning ("%s: error looking up thread handle %p", __func__,
1378                            thread);
1379                 return;
1380         }
1381
1382         _wapi_handle_unref (mutex);
1383         
1384         g_ptr_array_remove (thread_handle->owned_mutexes, mutex);
1385 }