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