Flush (work in progress)
[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
406         if (ret != 0) {
407 #ifdef DEBUG
408                 g_message ("%s: Thread create error: %s", __func__,
409                            strerror(ret));
410 #endif
411
412                 /* Two, because of the reference we took above */
413                 unrefs = 2;
414                 
415                 goto cleanup;
416         }
417         ct_ret = handle;
418         
419 #ifdef DEBUG
420         g_message("%s: Started thread handle %p ID %ld", __func__, handle,
421                   thread_handle_p->id);
422 #endif
423         
424         if (tid != NULL) {
425 #ifdef PTHREAD_POINTER_ID
426                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
427                  * sizeof(void *) > sizeof(uint) when a cast to uint
428                  * would overflow
429                  */
430                 *tid = (gsize)(thread_handle_p->id);
431 #else
432                 *tid = thread_handle_p->id;
433 #endif
434         }
435
436 cleanup:
437         thr_ret = _wapi_handle_unlock_handle (handle);
438         g_assert (thr_ret == 0);
439         pthread_cleanup_pop (0);
440         
441         /* Must not call _wapi_handle_unref() with the shared handles
442          * already locked
443          */
444         for (i = 0; i < unrefs; i++) {
445                 _wapi_handle_unref (handle);
446         }
447         
448         return(ct_ret);
449 }
450
451 /* The only time this function is called when tid != pthread_self ()
452  * is from OpenThread (), so we can fast-path most cases by just
453  * looking up the handle in TLS.  OpenThread () must cope with a NULL
454  * return and do a handle search in that case.
455  */
456 gpointer _wapi_thread_handle_from_id (pthread_t tid)
457 {
458         gpointer ret;
459
460         if (pthread_equal (tid, pthread_self ()) &&
461             (ret = pthread_getspecific (thread_hash_key)) != NULL) {
462                 /* We know the handle */
463
464 #ifdef DEBUG
465                 g_message ("%s: Returning %p for self thread %ld from TLS",
466                            __func__, ret, tid);
467 #endif
468                 
469                 return(ret);
470         }
471         
472 #ifdef DEBUG
473         g_message ("%s: Returning NULL for unknown or non-self thread %ld",
474                    __func__, tid);
475 #endif
476                 
477
478         return(NULL);
479 }
480
481 static gboolean find_thread_by_id (gpointer handle, gpointer user_data)
482 {
483         pthread_t tid = (pthread_t)user_data;
484         struct _WapiHandle_thread *thread_handle;
485         gboolean ok;
486         
487         /* Ignore threads that have already exited (ie they are signalled) */
488         if (_wapi_handle_issignalled (handle) == FALSE) {
489                 ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
490                                           (gpointer *)&thread_handle);
491                 if (ok == FALSE) {
492                         /* It's possible that the handle has vanished
493                          * during the _wapi_search_handle before it
494                          * gets here, so don't spam the console with
495                          * warnings.
496                          */
497                         return(FALSE);
498                 }
499                 
500 #ifdef DEBUG
501                 g_message ("%s: looking at thread %ld from process %d", __func__, thread_handle->id, 0);
502 #endif
503
504                 if (pthread_equal (thread_handle->id, tid)) {
505 #ifdef DEBUG
506                         g_message ("%s: found the thread we are looking for",
507                                    __func__);
508 #endif
509                         return(TRUE);
510                 }
511         }
512         
513 #ifdef DEBUG
514         g_message ("%s: not found %ld, returning FALSE", __func__, tid);
515 #endif
516         
517         return(FALSE);
518 }
519
520 /* NB tid is 32bit in MS API, but we need 64bit on amd64 and s390x
521  * (and probably others)
522  */
523 gpointer OpenThread (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, gsize tid)
524 {
525         gpointer ret=NULL;
526         
527         mono_once (&thread_hash_once, thread_hash_init);
528         mono_once (&thread_ops_once, thread_ops_init);
529         
530 #ifdef DEBUG
531         g_message ("%s: looking up thread %"G_GSIZE_FORMAT, __func__, tid);
532 #endif
533
534         ret = _wapi_thread_handle_from_id ((pthread_t)tid);
535         if (ret == NULL) {
536                 /* We need to search for this thread */
537                 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 */
538         } else {
539                 /* if _wapi_search_handle() returns a found handle, it
540                  * refs it itself
541                  */
542                 _wapi_handle_ref (ret);
543         }
544         
545 #ifdef DEBUG
546         g_message ("%s: returning thread handle %p", __func__, ret);
547 #endif
548         
549         return(ret);
550 }
551
552 /**
553  * ExitThread:
554  * @exitcode: Sets the thread's exit code, which can be read from
555  * another thread with GetExitCodeThread().
556  *
557  * Terminates the calling thread.  A thread can also exit by returning
558  * from its start function. When the last thread in a process
559  * terminates, the process itself terminates.
560  */
561 void ExitThread(guint32 exitcode)
562 {
563         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
564         
565         if (thread != NULL) {
566                 thread_exit(exitcode, thread);
567         } else {
568                 /* Just blow this thread away */
569                 pthread_exit (NULL);
570         }
571 }
572
573 /**
574  * GetExitCodeThread:
575  * @handle: The thread handle to query
576  * @exitcode: The thread @handle exit code is stored here
577  *
578  * Finds the exit code of @handle, and stores it in @exitcode.  If the
579  * thread @handle is still running, the value stored is %STILL_ACTIVE.
580  *
581  * Return value: %TRUE, or %FALSE on error.
582  */
583 gboolean GetExitCodeThread(gpointer handle, guint32 *exitcode)
584 {
585         struct _WapiHandle_thread *thread_handle;
586         gboolean ok;
587         
588         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
589                                   (gpointer *)&thread_handle);
590         if (ok == FALSE) {
591                 g_warning ("%s: error looking up thread handle %p", __func__,
592                            handle);
593                 return (FALSE);
594         }
595         
596 #ifdef DEBUG
597         g_message ("%s: Finding exit status for thread handle %p id %ld",
598                    __func__, handle, thread_handle->id);
599 #endif
600
601         if (exitcode == NULL) {
602 #ifdef DEBUG
603                 g_message ("%s: Nowhere to store exit code", __func__);
604 #endif
605                 return(FALSE);
606         }
607         
608         if (thread_handle->state != THREAD_STATE_EXITED) {
609 #ifdef DEBUG
610                 g_message ("%s: Thread still active (state %d, exited is %d)",
611                            __func__, thread_handle->state,
612                            THREAD_STATE_EXITED);
613 #endif
614                 *exitcode = STILL_ACTIVE;
615                 return(TRUE);
616         }
617         
618         *exitcode = thread_handle->exitstatus;
619         
620         return(TRUE);
621 }
622
623 /**
624  * GetCurrentThreadId:
625  *
626  * Looks up the thread ID of the current thread.  This ID can be
627  * passed to OpenThread() to create a new handle on this thread.
628  *
629  * Return value: the thread ID.  NB this is defined as DWORD (ie 32
630  * bit) in the MS API, but we need to cope with 64 bit IDs for s390x
631  * and amd64.  This doesn't really break the API, it just embraces and
632  * extends it on 64bit platforms :)
633  */
634 gsize GetCurrentThreadId(void)
635 {
636         pthread_t tid = pthread_self();
637         
638 #ifdef PTHREAD_POINTER_ID
639         /* Don't use GPOINTER_TO_UINT here, it can't cope with
640          * sizeof(void *) > sizeof(uint) when a cast to uint would
641          * overflow
642          */
643         return((gsize)tid);
644 #else
645         return(tid);
646 #endif
647 }
648
649 static gpointer thread_attach(gsize *tid)
650 {
651         struct _WapiHandle_thread thread_handle = {0}, *thread_handle_p;
652         gpointer handle;
653         gboolean ok;
654         int thr_ret;
655         
656         mono_once (&thread_hash_once, thread_hash_init);
657         mono_once (&thread_ops_once, thread_ops_init);
658
659         thread_handle.state = THREAD_STATE_START;
660         thread_handle.owned_mutexes = g_ptr_array_new ();
661
662         handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
663         if (handle == _WAPI_HANDLE_INVALID) {
664                 g_warning ("%s: error creating thread handle", __func__);
665                 
666                 SetLastError (ERROR_GEN_FAILURE);
667                 return (NULL);
668         }
669
670         pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
671                               handle);
672         thr_ret = _wapi_handle_lock_handle (handle);
673         g_assert (thr_ret == 0);
674         
675         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
676                                   (gpointer *)&thread_handle_p);
677         if (ok == FALSE) {
678                 g_warning ("%s: error looking up thread handle %p", __func__,
679                            handle);
680                 
681                 SetLastError (ERROR_GEN_FAILURE);
682                 goto cleanup;
683         }
684
685         /* Hold a reference while the thread is active, because we use
686          * the handle to store thread exit information
687          */
688         _wapi_handle_ref (handle);
689
690         /* suspend_sem is not used for attached threads, but
691          * thread_exit() might try to destroy it
692          */
693         MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
694         thread_handle_p->handle = handle;
695         thread_handle_p->id = pthread_self ();
696
697         thr_ret = pthread_setspecific (thread_hash_key, (void *)handle);
698         g_assert (thr_ret == 0);
699
700         thr_ret = pthread_setspecific (thread_attached_key, (void *)handle);
701         g_assert (thr_ret == 0);
702         
703 #ifdef DEBUG
704         g_message("%s: Attached thread handle %p ID %ld", __func__, handle,
705                   thread_handle_p->id);
706 #endif
707
708         if (tid != NULL) {
709 #ifdef PTHREAD_POINTER_ID
710                 /* Don't use GPOINTER_TO_UINT here, it can't cope with
711                  * sizeof(void *) > sizeof(uint) when a cast to uint
712                  * would overflow
713                  */
714                 *tid = (gsize)(thread_handle_p->id);
715 #else
716                 *tid = thread_handle_p->id;
717 #endif
718         }
719
720 cleanup:
721         thr_ret = _wapi_handle_unlock_handle (handle);
722         g_assert (thr_ret == 0);
723         pthread_cleanup_pop (0);
724         
725         return(handle);
726 }
727
728 gpointer _wapi_thread_duplicate ()
729 {
730         gpointer ret = NULL;
731         
732         mono_once (&thread_hash_once, thread_hash_init);
733         mono_once (&thread_ops_once, thread_ops_init);
734         
735         ret = _wapi_thread_handle_from_id (pthread_self ());
736         if (!ret) {
737                 ret = thread_attach (NULL);
738         } else {
739                 _wapi_handle_ref (ret);
740         }
741         
742         return(ret);
743 }
744
745 /**
746  * GetCurrentThread:
747  *
748  * Looks up the handle associated with the current thread.  Under
749  * Windows this is a pseudohandle, and must be duplicated with
750  * DuplicateHandle() for some operations.
751  *
752  * Return value: The current thread handle, or %NULL on failure.
753  * (Unknown whether Windows has a possible failure here.  It may be
754  * necessary to implement the pseudohandle-constant behaviour).
755  */
756 gpointer GetCurrentThread(void)
757 {
758         mono_once(&thread_hash_once, thread_hash_init);
759         mono_once (&thread_ops_once, thread_ops_init);
760         
761         return(_WAPI_THREAD_CURRENT);
762 }
763
764 /**
765  * ResumeThread:
766  * @handle: the thread handle to resume
767  *
768  * Decrements the suspend count of thread @handle. A thread can only
769  * run if its suspend count is zero.
770  *
771  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
772  */
773 guint32 ResumeThread(gpointer handle)
774 {
775         struct _WapiHandle_thread *thread_handle;
776         gboolean ok;
777         
778         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
779                                   (gpointer *)&thread_handle);
780         if (ok == FALSE) {
781                 g_warning ("%s: error looking up thread handle %p", __func__,
782                            handle);
783                 
784                 return (0xFFFFFFFF);
785         }
786
787         /* This is still a kludge that only copes with starting a
788          * thread that was suspended on create, so don't bother with
789          * the suspend count crap yet
790          */
791         _wapi_thread_resume (thread_handle);
792         return(0xFFFFFFFF);
793 }
794
795 /**
796  * SuspendThread:
797  * @handle: the thread handle to suspend
798  *
799  * Increments the suspend count of thread @handle. A thread can only
800  * run if its suspend count is zero.
801  *
802  * Return value: the previous suspend count, or 0xFFFFFFFF on error.
803  */
804 guint32 SuspendThread(gpointer handle)
805 {
806         return(0xFFFFFFFF);
807 }
808
809 /*
810  * We assume here that TLS_MINIMUM_AVAILABLE is less than
811  * PTHREAD_KEYS_MAX, allowing enough overhead for a few TLS keys for
812  * library usage.
813  *
814  * Currently TLS_MINIMUM_AVAILABLE is 64 and _POSIX_THREAD_KEYS_MAX
815  * (the minimum value for PTHREAD_KEYS_MAX) is 128, so we should be
816  * fine.
817  */
818
819 static pthread_key_t TLS_keys[TLS_MINIMUM_AVAILABLE];
820 static gboolean TLS_used[TLS_MINIMUM_AVAILABLE]={FALSE};
821 static guint32 TLS_spinlock=0;
822
823 guint32
824 mono_pthread_key_for_tls (guint32 idx)
825 {
826         return (guint32)TLS_keys [idx];
827 }
828
829 /**
830  * TlsAlloc:
831  *
832  * Allocates a Thread Local Storage (TLS) index.  Any thread in the
833  * same process can use this index to store and retrieve values that
834  * are local to that thread.
835  *
836  * Return value: The index value, or %TLS_OUT_OF_INDEXES if no index
837  * is available.
838  */
839 guint32 TlsAlloc(void)
840 {
841         guint32 i;
842         int thr_ret;
843         
844         MONO_SPIN_LOCK (TLS_spinlock);
845         
846         for(i=0; i<TLS_MINIMUM_AVAILABLE; i++) {
847                 if(TLS_used[i]==FALSE) {
848                         TLS_used[i]=TRUE;
849                         thr_ret = pthread_key_create(&TLS_keys[i], NULL);
850                         g_assert (thr_ret == 0);
851
852                         MONO_SPIN_UNLOCK (TLS_spinlock);
853         
854 #ifdef TLS_DEBUG
855                         g_message ("%s: returning key %d", __func__, i);
856 #endif
857                         
858                         return(i);
859                 }
860         }
861
862         MONO_SPIN_UNLOCK (TLS_spinlock);
863         
864 #ifdef TLS_DEBUG
865         g_message ("%s: out of indices", __func__);
866 #endif
867                         
868         
869         return(TLS_OUT_OF_INDEXES);
870 }
871
872 #define MAKE_GC_ID(idx) (GUINT_TO_POINTER((idx)|(GetCurrentThreadId()<<8)))
873
874 /**
875  * TlsFree:
876  * @idx: The TLS index to free
877  *
878  * Releases a TLS index, making it available for reuse.  This call
879  * will delete any TLS data stored under index @idx in all threads.
880  *
881  * Return value: %TRUE on success, %FALSE otherwise.
882  */
883 gboolean TlsFree(guint32 idx)
884 {
885         int thr_ret;
886         
887 #ifdef TLS_DEBUG
888         g_message ("%s: freeing key %d", __func__, idx);
889 #endif
890
891         MONO_SPIN_LOCK (TLS_spinlock);
892         
893         if(TLS_used[idx]==FALSE) {
894                 MONO_SPIN_UNLOCK (TLS_spinlock);
895
896                 return(FALSE);
897         }
898         
899         TLS_used[idx]=FALSE;
900         thr_ret = pthread_key_delete(TLS_keys[idx]);
901         g_assert (thr_ret == 0);
902         
903         MONO_SPIN_UNLOCK (TLS_spinlock);
904         
905         return(TRUE);
906 }
907
908 /**
909  * TlsGetValue:
910  * @idx: The TLS index to retrieve
911  *
912  * Retrieves the TLS data stored under index @idx.
913  *
914  * Return value: The value stored in the TLS index @idx in the current
915  * thread, or %NULL on error.  As %NULL can be a valid return value,
916  * in this case GetLastError() returns %ERROR_SUCCESS.
917  */
918 gpointer TlsGetValue(guint32 idx)
919 {
920         gpointer ret;
921         
922 #ifdef TLS_DEBUG
923         g_message ("%s: looking up key %d", __func__, idx);
924 #endif
925         
926         ret=pthread_getspecific(TLS_keys[idx]);
927
928 #ifdef TLS_DEBUG
929         g_message ("%s: returning %p", __func__, ret);
930 #endif
931         
932         return(ret);
933 }
934
935 /**
936  * TlsSetValue:
937  * @idx: The TLS index to store
938  * @value: The value to store under index @idx
939  *
940  * Stores @value at TLS index @idx.
941  *
942  * Return value: %TRUE on success, %FALSE otherwise.
943  */
944 gboolean TlsSetValue(guint32 idx, gpointer value)
945 {
946         int ret;
947
948 #ifdef TLS_DEBUG
949         g_message ("%s: setting key %d to %p", __func__, idx, value);
950 #endif
951         
952         
953         ret=pthread_setspecific(TLS_keys[idx], value);
954 #ifdef TLS_DEBUG
955         if(ret!=0)
956                 g_message ("%s: pthread_setspecific error: %s", __func__,
957                            strerror (ret));
958 #endif
959         
960         return(ret == 0);
961 }
962
963 /**
964  * SleepEx:
965  * @ms: The time in milliseconds to suspend for
966  * @alertable: if TRUE, the wait can be interrupted by an APC call
967  *
968  * Suspends execution of the current thread for @ms milliseconds.  A
969  * value of zero causes the thread to relinquish its time slice.  A
970  * value of %INFINITE causes an infinite delay.
971  */
972 guint32 SleepEx(guint32 ms, gboolean alertable)
973 {
974         struct timespec req, rem;
975         int ms_quot, ms_rem;
976         int ret;
977         gpointer current_thread = NULL;
978         
979 #ifdef DEBUG
980         g_message("%s: Sleeping for %d ms", __func__, ms);
981 #endif
982
983         if (alertable) {
984                 current_thread = _wapi_thread_handle_from_id (pthread_self ());
985                 if (current_thread == NULL) {
986                         SetLastError (ERROR_INVALID_HANDLE);
987                         return(WAIT_FAILED);
988                 }
989                 
990                 if (_wapi_thread_apc_pending (current_thread)) {
991                         _wapi_thread_dispatch_apc_queue (current_thread);
992                         return WAIT_IO_COMPLETION;
993                 }
994         }
995         
996         if(ms==0) {
997                 sched_yield();
998                 return 0;
999         }
1000         
1001         /* FIXME: check for INFINITE and sleep forever */
1002         ms_quot = ms / 1000;
1003         ms_rem = ms % 1000;
1004         
1005         req.tv_sec=ms_quot;
1006         req.tv_nsec=ms_rem*1000000;
1007         
1008 again:
1009         ret=nanosleep(&req, &rem);
1010
1011         if (alertable && _wapi_thread_apc_pending (current_thread)) {
1012                 _wapi_thread_dispatch_apc_queue (current_thread);
1013                 return WAIT_IO_COMPLETION;
1014         }
1015         
1016         if(ret==-1) {
1017                 /* Sleep interrupted with rem time remaining */
1018 #ifdef DEBUG
1019                 guint32 rems=rem.tv_sec*1000 + rem.tv_nsec/1000000;
1020                 
1021                 g_message("%s: Still got %d ms to go", __func__, rems);
1022 #endif
1023                 req=rem;
1024                 goto again;
1025         }
1026
1027         return 0;
1028 }
1029
1030 void Sleep(guint32 ms)
1031 {
1032         SleepEx(ms, FALSE);
1033 }
1034
1035 gboolean _wapi_thread_cur_apc_pending (void)
1036 {
1037         gpointer thread = _wapi_thread_handle_from_id (pthread_self ());
1038         
1039         if (thread == NULL) {
1040                 SetLastError (ERROR_INVALID_HANDLE);
1041                 return(FALSE);
1042         }
1043         
1044         return(_wapi_thread_apc_pending (thread));
1045 }
1046
1047 gboolean _wapi_thread_apc_pending (gpointer handle)
1048 {
1049         struct _WapiHandle_thread *thread;
1050         gboolean ok;
1051         
1052         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1053                                   (gpointer *)&thread);
1054         if (ok == FALSE) {
1055 #ifdef DEBUG
1056                 /* This might happen at process shutdown, as all
1057                  * thread handles are forcibly closed.  If a thread
1058                  * still has an alertable wait the final
1059                  * _wapi_thread_apc_pending check will probably fail
1060                  * to find the handle
1061                  */
1062                 g_warning ("%s: error looking up thread handle %p", __func__,
1063                            handle);
1064 #endif
1065                 return (FALSE);
1066         }
1067         
1068         return(thread->has_apc || thread->wait_handle == INTERRUPTION_REQUESTED_HANDLE);
1069 }
1070
1071 gboolean _wapi_thread_dispatch_apc_queue (gpointer handle)
1072 {
1073         /* We don't support calling APC functions */
1074         struct _WapiHandle_thread *thread;
1075         gboolean ok;
1076         
1077         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1078                                   (gpointer *)&thread);
1079         g_assert (ok);
1080
1081         thread->has_apc = FALSE;
1082
1083         return(TRUE);
1084 }
1085
1086 /*
1087  * In this implementation, APC_CALLBACK is ignored.
1088  * if HANDLE refers to the current thread, the only effect this function has 
1089  * that if called from a signal handler, and the thread was waiting when receiving 
1090  * the signal, the wait will be broken after the signal handler returns.
1091  * In this case, this function is async-signal-safe.
1092  */
1093 guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer handle, 
1094                       gpointer param)
1095 {
1096         struct _WapiHandle_thread *thread_handle;
1097         gboolean ok;
1098         
1099         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
1100                                   (gpointer *)&thread_handle);
1101         if (ok == FALSE) {
1102                 g_warning ("%s: error looking up thread handle %p", __func__,
1103                            handle);
1104                 return (0);
1105         }
1106
1107         g_assert (thread_handle->id == GetCurrentThreadId ());
1108         /* No locking/memory barriers are needed here */
1109         thread_handle->has_apc = TRUE;
1110         return(1);
1111 }
1112
1113 /*
1114  * wapi_interrupt_thread:
1115  *
1116  *   This is not part of the WIN32 API.
1117  * The state of the thread handle HANDLE is set to 'interrupted' which means that
1118  * if the thread calls one of the WaitFor functions, the function will return with 
1119  * WAIT_IO_COMPLETION instead of waiting. Also, if the thread was waiting when
1120  * this function was called, the wait will be broken.
1121  * It is possible that the wait functions return WAIT_IO_COMPLETION, but the
1122  * target thread didn't receive the interrupt signal yet, in this case it should
1123  * call the wait function again. This essentially means that the target thread will
1124  * busy wait until it is ready to process the interruption.
1125  * FIXME: get rid of QueueUserAPC and thread->has_apc, SleepEx seems to require it.
1126  */
1127 void wapi_interrupt_thread (gpointer thread_handle)
1128 {
1129         struct _WapiHandle_thread *thread;
1130         gboolean ok;
1131         gpointer prev_handle, wait_handle;
1132         guint32 idx;
1133         pthread_cond_t *cond;
1134         mono_mutex_t *mutex;
1135         
1136         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1137                                   (gpointer *)&thread);
1138         g_assert (ok);
1139
1140         while (TRUE) {
1141                 wait_handle = thread->wait_handle;
1142
1143                 /* 
1144                  * Atomically obtain the handle the thread is waiting on, and
1145                  * change it to a flag value.
1146                  */
1147                 prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1148                                                                                                                  INTERRUPTION_REQUESTED_HANDLE, wait_handle);
1149                 if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1150                         /* Already interrupted */
1151                         return;
1152                 if (prev_handle == wait_handle)
1153                         break;
1154
1155                 /* Try again */
1156         }
1157
1158         WAIT_DEBUG (printf ("%p: state -> INTERRUPTED.\n", thread_handle->id););
1159
1160         if (!wait_handle)
1161                 /* Not waiting */
1162                 return;
1163
1164         /* If we reach here, then wait_handle is set to the flag value, 
1165          * which means that the target thread is either
1166          * - before the first CAS in timedwait, which means it won't enter the
1167          * wait.
1168          * - it is after the first CAS, so it is already waiting, or it will 
1169          * enter the wait, and it will be interrupted by the broadcast.
1170          */
1171         idx = GPOINTER_TO_UINT(wait_handle);
1172         cond = &_WAPI_PRIVATE_HANDLES(idx).signal_cond;
1173         mutex = &_WAPI_PRIVATE_HANDLES(idx).signal_mutex;
1174
1175         mono_mutex_lock (mutex);
1176         mono_cond_broadcast (cond);
1177         mono_mutex_unlock (mutex);
1178
1179         /* ref added by set_wait_handle */
1180         _wapi_handle_unref (wait_handle);
1181 }
1182
1183 /*
1184  * wapi_self_interrupt:
1185  *
1186  *   This is not part of the WIN32 API.
1187  * Set the 'interrupted' state of the calling thread if it's NULL.
1188  */
1189 void wapi_self_interrupt (void)
1190 {
1191         struct _WapiHandle_thread *thread;
1192         gboolean ok;
1193         gpointer prev_handle, wait_handle;
1194         gpointer thread_handle;
1195
1196
1197         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1198         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1199                                                           (gpointer *)&thread);
1200         g_assert (ok);
1201
1202         while (TRUE) {
1203                 wait_handle = thread->wait_handle;
1204
1205                 /*
1206                  * Atomically obtain the handle the thread is waiting on, and
1207                  * change it to a flag value.
1208                  */
1209                 prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1210                                                                                                                  INTERRUPTION_REQUESTED_HANDLE, wait_handle);
1211                 if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1212                         /* Already interrupted */
1213                         goto cleanup;
1214                 /*We did not get interrupted*/
1215                 if (prev_handle == wait_handle)
1216                         break;
1217
1218                 /* Try again */
1219         }
1220
1221         if (wait_handle) {
1222                 /* ref added by set_wait_handle */
1223                 _wapi_handle_unref (wait_handle);
1224         }
1225
1226 cleanup:
1227         _wapi_handle_unref (thread_handle);
1228 }
1229
1230 /*
1231  * wapi_clear_interruption:
1232  *
1233  *   This is not part of the WIN32 API. 
1234  * Clear the 'interrupted' state of the calling thread.
1235  * This function is signal safe
1236  */
1237 void wapi_clear_interruption (void)
1238 {
1239         struct _WapiHandle_thread *thread;
1240         gboolean ok;
1241         gpointer prev_handle;
1242         gpointer thread_handle;
1243
1244         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1245         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1246                                                           (gpointer *)&thread);
1247         g_assert (ok);
1248
1249         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1250                                                                                                          NULL, INTERRUPTION_REQUESTED_HANDLE);
1251         if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
1252                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1253
1254         _wapi_handle_unref (thread_handle);
1255 }
1256
1257 char* wapi_current_thread_desc ()
1258 {
1259         struct _WapiHandle_thread *thread;
1260         int i;
1261         gboolean ok;
1262         gpointer handle;
1263         gpointer thread_handle;
1264         GString* text;
1265         char *res;
1266
1267         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1268         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1269                                                           (gpointer *)&thread);
1270         if (!ok)
1271                 return g_strdup_printf ("thread handle %p state : lookup failure", thread_handle);
1272
1273         handle = thread->wait_handle;
1274         text = g_string_new (0);
1275         g_string_append_printf (text, "thread handle %p state : ", thread_handle);
1276
1277         if (!handle)
1278                 g_string_append_printf (text, "not waiting");
1279         else if (handle == INTERRUPTION_REQUESTED_HANDLE)
1280                 g_string_append_printf (text, "interrupted state");
1281         else
1282                 g_string_append_printf (text, "waiting on %p : %s ", handle, _wapi_handle_typename[_wapi_handle_type (handle)]);
1283         g_string_append_printf (text, " owns (");
1284         for (i = 0; i < thread->owned_mutexes->len; i++) {
1285                 gpointer mutex = g_ptr_array_index (thread->owned_mutexes, i);
1286                 if (i > 0)
1287                         g_string_append_printf (text, ", %p", mutex);
1288                 else
1289                         g_string_append_printf (text, "%p", mutex);
1290         }
1291         g_string_append_printf (text, ")");
1292
1293         res = text->str;
1294         g_string_free (text, FALSE);
1295         return res;
1296 }
1297
1298 /**
1299  * wapi_thread_set_wait_handle:
1300  *
1301  *   Set the wait handle for the current thread to HANDLE. Return TRUE on success, FALSE
1302  * if the thread is in interrupted state, and cannot start waiting.
1303  */
1304 gboolean wapi_thread_set_wait_handle (gpointer handle)
1305 {
1306         struct _WapiHandle_thread *thread;
1307         gboolean ok;
1308         gpointer prev_handle;
1309         gpointer thread_handle;
1310
1311         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1312         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1313                                                           (gpointer *)&thread);
1314         g_assert (ok);
1315
1316         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1317                                                                                                          handle, NULL);
1318         _wapi_handle_unref (thread_handle);
1319
1320         if (prev_handle == NULL) {
1321                 /* thread->wait_handle acts as an additional reference to the handle */
1322                 _wapi_handle_ref (handle);
1323
1324                 WAIT_DEBUG (printf ("%p: state -> WAITING.\n", GetCurrentThreadId ()););
1325         } else {
1326                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
1327                 WAIT_DEBUG (printf ("%p: unable to set state to WAITING.\n", GetCurrentThreadId ()););
1328         }
1329
1330         return prev_handle == NULL;
1331 }
1332
1333 /**
1334  * wapi_thread_clear_wait_handle:
1335  *
1336  *   Clear the wait handle of the current thread.
1337  */
1338 void wapi_thread_clear_wait_handle (gpointer handle)
1339 {
1340         struct _WapiHandle_thread *thread;
1341         gboolean ok;
1342         gpointer prev_handle;
1343         gpointer thread_handle;
1344
1345         thread_handle = OpenThread (0, 0, GetCurrentThreadId ());
1346         ok = _wapi_lookup_handle (thread_handle, WAPI_HANDLE_THREAD,
1347                                                           (gpointer *)&thread);
1348         g_assert (ok);
1349
1350         prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
1351                                                                                                          NULL, handle);
1352
1353         if (prev_handle == handle) {
1354                 _wapi_handle_unref (handle);
1355                 WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
1356         } else {
1357                 /*It can be NULL if it was asynchronously cleared*/
1358                 g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE || prev_handle == NULL);
1359                 WAIT_DEBUG (printf ("%p: finished waiting.\n", GetCurrentThreadId ()););
1360         }
1361
1362         _wapi_handle_unref (thread_handle);
1363 }
1364
1365 void _wapi_thread_own_mutex (gpointer mutex)
1366 {
1367         struct _WapiHandle_thread *thread_handle;
1368         gboolean ok;
1369         gpointer thread;
1370         
1371         thread = _wapi_thread_handle_from_id (pthread_self ());
1372         if (thread == NULL) {
1373                 g_warning ("%s: error looking up thread by ID", __func__);
1374                 return;
1375         }
1376
1377         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1378                                   (gpointer *)&thread_handle);
1379         if (ok == FALSE) {
1380                 g_warning ("%s: error looking up thread handle %p", __func__,
1381                            thread);
1382                 return;
1383         }
1384
1385         _wapi_handle_ref (mutex);
1386         
1387         g_ptr_array_add (thread_handle->owned_mutexes, mutex);
1388 }
1389
1390 void _wapi_thread_disown_mutex (gpointer mutex)
1391 {
1392         struct _WapiHandle_thread *thread_handle;
1393         gboolean ok;
1394         gpointer thread;
1395
1396         thread = _wapi_thread_handle_from_id (pthread_self ());
1397         if (thread == NULL) {
1398                 g_warning ("%s: error looking up thread by ID", __func__);
1399                 return;
1400         }
1401
1402         ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
1403                                   (gpointer *)&thread_handle);
1404         if (ok == FALSE) {
1405                 g_warning ("%s: error looking up thread handle %p", __func__,
1406                            thread);
1407                 return;
1408         }
1409
1410         _wapi_handle_unref (mutex);
1411         
1412         g_ptr_array_remove (thread_handle->owned_mutexes, mutex);
1413 }