* src/threads/thread.hpp (thread_set_object, thread_get_object): Removed.
[cacao.git] / src / threads / posix / thread-posix.cpp
1 /* src/threads/posix/thread-posix.cpp - POSIX thread functions
2
3    Copyright (C) 1996-2011
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 /* XXX cleanup these includes */
29
30 #define __STDC_LIMIT_MACROS
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 #include <sys/time.h>
38 #include <time.h>
39 #include <errno.h>
40
41 #include <pthread.h>
42
43 #include "vm/types.h"
44
45 #include "arch.h"
46
47 #include "mm/gc.hpp"
48 #include "mm/memory.hpp"
49
50 #if defined(ENABLE_GC_CACAO)
51 # include "mm/cacao-gc/gc.h"
52 #endif
53
54 #include "native/llni.h"
55 #include "native/native.hpp"
56
57 #include "threads/condition.hpp"
58 #include "threads/lock.hpp"
59 #include "threads/mutex.hpp"
60 #include "threads/threadlist.hpp"
61 #include "threads/thread.hpp"
62
63 #include "toolbox/logging.hpp"
64
65 #include "vm/jit/builtin.hpp"
66 #include "vm/exceptions.hpp"
67 #include "vm/global.h"
68 #include "vm/globals.hpp"
69 #include "vm/hook.hpp"
70 #include "vm/javaobjects.hpp"
71 #include "vm/options.h"
72 #include "vm/os.hpp"
73 #include "vm/signallocal.hpp"
74 #include "vm/string.hpp"
75 #include "vm/vm.hpp"
76
77 #if defined(ENABLE_STATISTICS)
78 # include "vm/statistics.h"
79 #endif
80
81 #include "vm/jit/asmpart.h"
82
83 #if defined(__DARWIN__)
84
85 typedef struct {
86         Mutex* mutex;
87         Condition* cond;
88         int value;
89 } sem_t;
90
91 #else
92 # include <semaphore.h>
93 #endif
94
95 #if defined(__LINUX__)
96 # define GC_LINUX_THREADS
97 #elif defined(__IRIX__)
98 # define GC_IRIX_THREADS
99 #elif defined(__DARWIN__)
100 # define GC_DARWIN_THREADS
101 #elif defined(__SOLARIS__)
102 # define GC_SOLARIS_THREADS
103 #endif
104
105 #if defined(ENABLE_GC_BOEHM)
106 /* We need to include Boehm's gc.h here because it overrides
107    pthread_create and friends. */
108 # include "mm/boehm-gc/include/gc.h"
109 #endif
110
111
112 #if defined(__DARWIN__)
113 /* Darwin has no working semaphore implementation.  This one is taken
114    from Boehm-GC. */
115
116 /*
117    This is a very simple semaphore implementation for Darwin. It
118    is implemented in terms of pthreads calls so it isn't async signal
119    safe. This isn't a problem because signals aren't used to
120    suspend threads on Darwin.
121 */
122    
123 static int sem_init(sem_t *sem, int pshared, int value)
124 {
125         if (pshared)
126                 assert(0);
127
128         sem->mutex = new Mutex();
129         sem->cond  = new Condition();
130         sem->value = value;
131
132         return 0;
133 }
134
135 static int sem_post(sem_t *sem)
136 {
137         sem->mutex->lock();
138         sem->value++;
139         sem->cond->signal();
140         sem->mutex->unlock();
141
142         return 0;
143 }
144
145 static int sem_wait(sem_t *sem)
146 {
147         sem->mutex->lock();
148
149         while (sem->value == 0) {
150                 sem->cond->wait(sem->mutex);
151         }
152
153         sem->value--;
154         sem->mutex->unlock();
155
156         return 0;
157 }
158
159 static int sem_destroy(sem_t *sem)
160 {
161         delete sem->cond;
162         delete sem->mutex;
163
164         return 0;
165 }
166 #endif /* defined(__DARWIN__) */
167
168
169 /* startupinfo *****************************************************************
170
171    Struct used to pass info from threads_start_thread to 
172    threads_startup_thread.
173
174 ******************************************************************************/
175
176 typedef struct {
177         threadobject *thread;      /* threadobject for this thread             */
178         functionptr   function;    /* function to run in the new thread        */
179         sem_t        *psem;        /* signals when thread has been entered     */
180                                    /* in the thread list                       */
181         sem_t        *psem_first;  /* signals when pthread_create has returned */
182 } startupinfo;
183
184
185 /* prototypes *****************************************************************/
186
187 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
188
189
190 /******************************************************************************/
191 /* GLOBAL VARIABLES                                                           */
192 /******************************************************************************/
193
194 /* the thread object of the current thread                                    */
195 /* This is either a thread-local variable defined with __thread, or           */
196 /* a thread-specific value stored with key threads_current_threadobject_key.  */
197 #if defined(HAVE___THREAD)
198 __thread threadobject *thread_current;
199 #else
200 pthread_key_t thread_current_key;
201 #endif
202
203 /* global mutex for stop-the-world                                            */
204 static Mutex* stopworldlock;
205
206 #if defined(ENABLE_GC_CACAO)
207 /* global mutex for the GC */
208 static Mutex* mutex_gc;
209 #endif
210
211 /* global mutex and condition for joining threads on exit */
212 static Mutex* mutex_join;
213 static Condition* cond_join;
214
215 #if defined(ENABLE_GC_CACAO)
216 /* semaphore used for acknowleding thread suspension                          */
217 static sem_t suspend_ack;
218 #endif
219
220
221 /* threads_sem_init ************************************************************
222  
223    Initialize a semaphore. Checks against errors and interruptions.
224
225    IN:
226        sem..............the semaphore to initialize
227            shared...........true if this semaphore will be shared between processes
228            value............the initial value for the semaphore
229    
230 *******************************************************************************/
231
232 void threads_sem_init(sem_t *sem, bool shared, int value)
233 {
234         int r;
235
236         assert(sem);
237
238         do {
239                 r = sem_init(sem, shared, value);
240                 if (r == 0)
241                         return;
242         } while (errno == EINTR);
243
244         vm_abort("sem_init failed: %s", strerror(errno));
245 }
246
247
248 /* threads_sem_wait ************************************************************
249  
250    Wait for a semaphore, non-interruptible.
251
252    IMPORTANT: Always use this function instead of `sem_wait` directly, as
253               `sem_wait` may be interrupted by signals!
254   
255    IN:
256        sem..............the semaphore to wait on
257    
258 *******************************************************************************/
259
260 void threads_sem_wait(sem_t *sem)
261 {
262         int r;
263
264         assert(sem);
265
266         do {
267                 r = sem_wait(sem);
268                 if (r == 0)
269                         return;
270         } while (errno == EINTR);
271
272         vm_abort("sem_wait failed: %s", strerror(errno));
273 }
274
275
276 /* threads_sem_post ************************************************************
277  
278    Increase the count of a semaphore. Checks for errors.
279
280    IN:
281        sem..............the semaphore to increase the count of
282    
283 *******************************************************************************/
284
285 void threads_sem_post(sem_t *sem)
286 {
287         int r;
288
289         assert(sem);
290
291         /* unlike sem_wait, sem_post is not interruptible */
292
293         r = sem_post(sem);
294         if (r == 0)
295                 return;
296
297         vm_abort("sem_post failed: %s", strerror(errno));
298 }
299
300
301 /* threads_stopworld ***********************************************************
302
303    Stops the world from turning. All threads except the calling one
304    are suspended. The function returns as soon as all threads have
305    acknowledged their suspension.
306
307 *******************************************************************************/
308
309 #if defined(ENABLE_GC_CACAO)
310 void threads_stopworld(void)
311 {
312 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
313         threadobject *t;
314         threadobject *self;
315         bool result;
316         s4 count, i;
317 #endif
318
319         stopworldlock->lock();
320
321         /* lock the threads lists */
322
323         threadlist_lock();
324
325 #if defined(__DARWIN__)
326         /*threads_cast_darwinstop();*/
327         assert(0);
328 #elif defined(__CYGWIN__)
329         /* TODO */
330         assert(0);
331 #else
332         self = THREADOBJECT;
333
334         DEBUGTHREADS("stops World", self);
335
336         count = 0;
337
338         /* suspend all running threads */
339         for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
340                 /* don't send the signal to ourself */
341
342                 if (t == self)
343                         continue;
344
345                 /* don't send the signal to NEW threads (because they are not
346                    completely initialized) */
347
348                 if (t->state == THREAD_STATE_NEW)
349                         continue;
350
351                 /* send the signal */
352
353                 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
354                 assert(result);
355
356                 /* increase threads count */
357
358                 count++;
359         }
360
361         /* wait for all threads signaled to suspend */
362         for (i = 0; i < count; i++)
363                 threads_sem_wait(&suspend_ack);
364 #endif
365
366         /* ATTENTION: Don't unlock the threads-lists here so that
367            non-signaled NEW threads can't change their state and execute
368            code. */
369 }
370 #endif
371
372
373 /* threads_startworld **********************************************************
374
375    Starts the world again after it has previously been stopped. 
376
377 *******************************************************************************/
378
379 #if defined(ENABLE_GC_CACAO)
380 void threads_startworld(void)
381 {
382 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
383         threadobject *t;
384         threadobject *self;
385         bool result;
386         s4 count, i;
387 #endif
388
389 #if defined(__DARWIN__)
390         /*threads_cast_darwinresume();*/
391         assert(0);
392 #elif defined(__IRIX__)
393         threads_cast_irixresume();
394 #elif defined(__CYGWIN__)
395         /* TODO */
396         assert(0);
397 #else
398         self = THREADOBJECT;
399
400         DEBUGTHREADS("starts World", self);
401
402         count = 0;
403
404         /* resume all thread we haltet */
405         for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
406                 /* don't send the signal to ourself */
407
408                 if (t == self)
409                         continue;
410
411                 /* don't send the signal to NEW threads (because they are not
412                    completely initialized) */
413
414                 if (t->state == THREAD_STATE_NEW)
415                         continue;
416
417                 /* send the signal */
418
419                 result = threads_resume_thread(t);
420                 assert(result);
421
422                 /* increase threads count */
423
424                 count++;
425         }
426
427         /* wait for all threads signaled to suspend */
428         for (i = 0; i < count; i++)
429                 threads_sem_wait(&suspend_ack);
430
431 #endif
432
433         /* unlock the threads lists */
434
435         threadlist_unlock();
436
437         stopworldlock->unlock();
438 }
439 #endif
440
441
442 /* threads_impl_thread_clear ***************************************************
443
444    Clears all fields in threadobject the way an MZERO would have
445    done. MZERO cannot be used anymore because it would mess up the
446    pthread_* bits.
447
448    IN:
449       t....the threadobject
450
451 *******************************************************************************/
452
453 void threads_impl_thread_clear(threadobject *t)
454 {
455         t->object = NULL;
456
457         t->thinlock = 0;
458
459         t->index = 0;
460         t->flags = 0;
461         t->state = 0;
462         t->is_in_active_list = false;
463
464         t->tid = 0;
465
466 #if defined(__DARWIN__)
467         t->mach_thread = 0;
468 #endif
469
470         t->interrupted = false;
471         t->signaled = false;
472
473         t->suspended = false;
474         t->suspend_reason = 0;
475
476         t->pc = NULL;
477
478         t->_exceptionptr = NULL;
479         t->_stackframeinfo = NULL;
480         t->_localref_table = NULL;
481
482 #if defined(ENABLE_INTRP)
483         t->_global_sp = NULL;
484 #endif
485
486 #if defined(ENABLE_GC_CACAO)
487         t->gc_critical = false;
488
489         t->ss = NULL;
490         t->es = NULL;
491 #endif
492
493         // Simply reuse the existing dump memory.
494 }
495
496 /* threads_impl_thread_reuse ***************************************************
497
498    Resets some implementation fields in threadobject. This was
499    previously done in threads_impl_thread_new.
500
501    IN:
502       t....the threadobject
503
504 *******************************************************************************/
505
506 void threads_impl_thread_reuse(threadobject *t)
507 {
508         /* get the pthread id */
509
510         t->tid = pthread_self();
511
512 #if defined(ENABLE_DEBUG_FILTER)
513         /* Initialize filter counters */
514         t->filterverbosecallctr[0] = 0;
515         t->filterverbosecallctr[1] = 0;
516 #endif
517
518 #if !defined(NDEBUG)
519         t->tracejavacallindent = 0;
520         t->tracejavacallcount = 0;
521 #endif
522
523         t->flc_bit = false;
524         t->flc_next = NULL;
525         t->flc_list = NULL;
526
527 /*      not really needed */
528         t->flc_object = NULL;
529
530 #if defined(ENABLE_TLH)
531         tlh_destroy(&(t->tlh));
532         tlh_init(&(t->tlh));
533 #endif
534 }
535
536 void threads_impl_clear_heap_pointers(threadobject *t)
537 {
538         t->object = 0;
539         t->flc_object = 0;
540 }
541
542 /* threads_impl_preinit ********************************************************
543
544    Do some early initialization of stuff required.
545
546    ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
547    is called AFTER this function!
548
549 *******************************************************************************/
550
551 void threads_impl_preinit(void)
552 {
553         stopworldlock = new Mutex();
554
555         /* initialize exit mutex and condition (on exit we join all
556            threads) */
557
558         mutex_join = new Mutex();
559         cond_join = new Condition();
560
561 #if defined(ENABLE_GC_CACAO)
562         /* initialize the GC mutex & suspend semaphore */
563
564         mutex_gc = new Mutex();
565         threads_sem_init(&suspend_ack, 0, 0);
566 #endif
567
568 #if !defined(HAVE___THREAD)
569         int result = pthread_key_create(&thread_current_key, NULL);
570         if (result != 0)
571                 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
572 #endif
573 }
574
575
576 /* threads_mutex_gc_lock *******************************************************
577
578    Enter the global GC mutex.
579
580 *******************************************************************************/
581
582 #if defined(ENABLE_GC_CACAO)
583 void threads_mutex_gc_lock(void)
584 {
585         mutex_gc->lock();
586 }
587 #endif
588
589
590 /* threads_mutex_gc_unlock *****************************************************
591
592    Leave the global GC mutex.
593
594 *******************************************************************************/
595
596 #if defined(ENABLE_GC_CACAO)
597 void threads_mutex_gc_unlock(void)
598 {
599         mutex_gc->unlock();
600 }
601 #endif
602
603 /* threads_mutex_join_lock *****************************************************
604
605    Enter the join mutex.
606
607 *******************************************************************************/
608
609 void threads_mutex_join_lock(void)
610 {
611         mutex_join->lock();
612 }
613
614
615 /* threads_mutex_join_unlock ***************************************************
616
617    Leave the join mutex.
618
619 *******************************************************************************/
620
621 void threads_mutex_join_unlock(void)
622 {
623         mutex_join->unlock();
624 }
625
626
627 /* threads_impl_init ***********************************************************
628
629    Initializes the implementation specific bits.
630
631 *******************************************************************************/
632
633 void threads_impl_init(void)
634 {
635         pthread_attr_t attr;
636         int            result;
637
638         threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
639
640         /* Initialize the thread attribute object. */
641
642         result = pthread_attr_init(&attr);
643
644         if (result != 0)
645                 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
646
647         result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
648
649         if (result != 0)
650                 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
651 }
652
653
654 /* threads_startup_thread ******************************************************
655
656    Thread startup function called by pthread_create.
657
658    Thread which have a startup.function != NULL are marked as internal
659    threads. All other threads are threated as normal Java threads.
660
661    NOTE: This function is not called directly by pthread_create. The Boehm GC
662          inserts its own GC_start_routine in between, which then calls
663                  threads_startup.
664
665    IN:
666       arg..........the argument passed to pthread_create, ie. a pointer to
667                        a startupinfo struct. CAUTION: When the `psem` semaphore
668                                    is posted, the startupinfo struct becomes invalid! (It
669                                    is allocated on the stack of threads_start_thread.)
670
671 ******************************************************************************/
672
673 static void *threads_startup_thread(void *arg)
674 {
675         startupinfo  *startup;
676         threadobject *t;
677         sem_t        *psem;
678         classinfo    *c;
679         methodinfo   *m;
680         functionptr   function;
681
682 #if defined(ENABLE_GC_BOEHM)
683 # if !defined(__DARWIN__)
684         struct GC_stack_base sb;
685         int result;
686 # endif
687 #endif
688
689 #if defined(ENABLE_INTRP)
690         u1 *intrp_thread_stack;
691 #endif
692
693 #if defined(ENABLE_INTRP)
694         /* create interpreter stack */
695
696         if (opt_intrp) {
697                 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
698                 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
699         }
700         else
701                 intrp_thread_stack = NULL;
702 #endif
703
704         /* get passed startupinfo structure and the values in there */
705
706         startup = (startupinfo*) arg;
707
708         t        = startup->thread;
709         function = startup->function;
710         psem     = startup->psem;
711
712         /* Seems like we've encountered a situation where thread->tid was
713            not set by pthread_create. We alleviate this problem by waiting
714            for pthread_create to return. */
715
716         threads_sem_wait(startup->psem_first);
717
718 #if defined(__DARWIN__)
719         t->mach_thread = mach_thread_self();
720 #endif
721
722         /* Now that we are in the new thread, we can store the internal
723            thread data-structure in the TSD. */
724
725         thread_set_current(t);
726
727 #if defined(ENABLE_GC_BOEHM)
728 # if defined(__DARWIN__)
729         // This is currently not implemented in Boehm-GC.  Just fail silently.
730 # else
731         /* Register the thread with Boehm-GC.  This must happen before the
732            thread allocates any memory from the GC heap.*/
733
734         result = GC_get_stack_base(&sb);
735
736         if (result != 0)
737                 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
738
739         GC_register_my_thread(&sb);
740 # endif
741 #endif
742
743         // Get the java.lang.Thread object for this thread.
744         java_handle_t* object = LLNI_WRAP(t->object);
745         java_lang_Thread jlt(object);
746
747         /* set our priority */
748
749         threads_set_thread_priority(t->tid, jlt.get_priority());
750
751         /* Thread is completely initialized. */
752
753         thread_set_state_runnable(t);
754
755         /* tell threads_startup_thread that we registered ourselves */
756         /* CAUTION: *startup becomes invalid with this!             */
757
758         startup = NULL;
759         threads_sem_post(psem);
760
761 #if defined(ENABLE_INTRP)
762         /* set interpreter stack */
763
764         if (opt_intrp)
765                 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
766 #endif
767
768         // Hook point just before the threads initial method is executed.
769         Hook::thread_start(t);
770
771         DEBUGTHREADS("starting", t);
772
773         /* find and run the Thread.run()V method if no other function was passed */
774
775         if (function == NULL) {
776                 c = ThreadRuntime::get_thread_class_from_object(object);
777
778                 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
779
780                 if (m == NULL)
781                         vm_abort("threads_startup_thread: run() method not found in class");
782
783                 java_handle_t *h = ThreadRuntime::get_vmthread_handle(jlt);
784
785                 /* Run the thread. */
786
787                 (void) vm_call_method(m, h);
788         }
789         else {
790                 /* call passed function, e.g. finalizer_thread */
791
792                 (function)();
793         }
794
795         DEBUGTHREADS("stopping", t);
796
797         // Hook point just after the threads initial method returned.
798         Hook::thread_end(t);
799
800         /* We ignore the return value. */
801
802         (void) thread_detach_current_thread();
803
804         return NULL;
805 }
806
807
808 /* threads_impl_thread_start ***************************************************
809
810    Start a thread in the JVM.  Both (vm internal and java) thread
811    objects exist.
812
813    IN:
814       thread....the thread object
815           f.........function to run in the new thread. NULL means that the
816                     "run" method of the object `t` should be called
817
818 ******************************************************************************/
819
820 void threads_impl_thread_start(threadobject *thread, functionptr f)
821 {
822         sem_t          sem;
823         sem_t          sem_first;
824         pthread_attr_t attr;
825         startupinfo    startup;
826         int            result;
827
828         /* fill startupinfo structure passed by pthread_create to
829          * threads_startup_thread */
830
831         startup.thread     = thread;
832         startup.function   = f;              /* maybe we don't call Thread.run()V */
833         startup.psem       = &sem;
834         startup.psem_first = &sem_first;
835
836         threads_sem_init(&sem, 0, 0);
837         threads_sem_init(&sem_first, 0, 0);
838
839         /* Initialize thread attributes. */
840
841         result = pthread_attr_init(&attr);
842
843         if (result != 0)
844                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
845
846     result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
847
848     if (result != 0)
849                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
850
851         /* initialize thread stacksize */
852
853         result = pthread_attr_setstacksize(&attr, opt_stacksize);
854
855         if (result != 0)
856                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
857
858         /* create the thread */
859
860         result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
861
862         if (result != 0)
863                 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
864
865         /* destroy the thread attributes */
866
867         result = pthread_attr_destroy(&attr);
868
869         if (result != 0)
870                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
871
872         /* signal that pthread_create has returned, so thread->tid is valid */
873
874         threads_sem_post(&sem_first);
875
876         /* wait here until the thread has entered itself into the thread list */
877
878         threads_sem_wait(&sem);
879
880         /* cleanup */
881
882         sem_destroy(&sem);
883         sem_destroy(&sem_first);
884 }
885
886
887 /* threads_set_thread_priority *************************************************
888
889    Set the priority of the given thread.
890
891    IN:
892       tid..........thread id
893           priority.....priority to set
894
895 ******************************************************************************/
896
897 void threads_set_thread_priority(pthread_t tid, int priority)
898 {
899         struct sched_param schedp;
900         int policy;
901
902         pthread_getschedparam(tid, &policy, &schedp);
903         schedp.sched_priority = priority;
904         pthread_setschedparam(tid, policy, &schedp);
905 }
906
907
908 /**
909  * Detaches the current thread from the VM.
910  *
911  * @return true on success, false otherwise
912  */
913 bool thread_detach_current_thread(void)
914 {
915         threadobject* t = thread_get_current();
916
917         /* Sanity check. */
918
919         assert(t != NULL);
920
921     /* If the given thread has already been detached, this operation
922            is a no-op. */
923
924         if (thread_is_attached(t) == false)
925                 return true;
926
927         DEBUGTHREADS("detaching", t);
928
929         java_handle_t* object = LLNI_WRAP(t->object);
930         java_lang_Thread jlt(object);
931
932 #if defined(ENABLE_JAVASE)
933         java_handle_t* group = jlt.get_group();
934
935     /* If there's an uncaught exception, call uncaughtException on the
936        thread's exception handler, or the thread's group if this is
937        unset. */
938
939         java_handle_t* e = exceptions_get_and_clear_exception();
940
941     if (e != NULL) {
942                 /* We use the type void* for handler here, as it's not trivial
943                    to build the java_lang_Thread_UncaughtExceptionHandler
944                    header file with cacaoh. */
945
946                 java_handle_t *handler = ThreadRuntime::get_thread_exception_handler(jlt);
947
948                 classinfo*     c;
949                 java_handle_t* h;
950
951                 if (handler != NULL) {
952                         LLNI_class_get(handler, c);
953                         h = (java_handle_t *) handler;
954                 }
955                 else {
956                         LLNI_class_get(group, c);
957                         h = (java_handle_t *) group;
958                 }
959
960                 methodinfo* m = class_resolveclassmethod(c,
961                                                                                                  utf_uncaughtException,
962                                                                                                  utf_java_lang_Thread_java_lang_Throwable__V,
963                                                                                                  NULL,
964                                                                                                  true);
965
966                 if (m == NULL)
967                         return false;
968
969                 (void) vm_call_method(m, h, object, e);
970
971                 if (exceptions_get_exception())
972                         return false;
973     }
974
975         /* XXX TWISTI: should all threads be in a ThreadGroup? */
976
977         /* Remove thread from the thread group. */
978
979         if (group != NULL) {
980                 classinfo* c;
981                 LLNI_class_get(group, c);
982
983                 methodinfo *m = ThreadRuntime::get_threadgroup_remove_method(c);
984
985                 if (m == NULL)
986                         return false;
987
988                 (void) vm_call_method(m, group, object);
989
990                 if (exceptions_get_exception())
991                         return false;
992
993                 // Clear the ThreadGroup in the Java thread object (Mauve
994                 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
995                 jlt.set_group(NULL);
996         }
997 #endif
998
999         /* Thread has terminated. */
1000
1001         thread_set_state_terminated(t);
1002
1003         /* Notify all threads waiting on this thread.  These are joining
1004            this thread. */
1005
1006         /* XXX Care about exceptions? */
1007         (void) lock_monitor_enter(jlt.get_handle());
1008         
1009         lock_notify_all_object(jlt.get_handle());
1010
1011         /* XXX Care about exceptions? */
1012         (void) lock_monitor_exit(jlt.get_handle());
1013
1014         t->waitmutex->lock();
1015         t->tid = 0;
1016         t->waitmutex->unlock();
1017
1018         /* Enter the join-mutex before calling thread_free, so
1019            threads_join_all_threads gets the correct number of non-daemon
1020            threads. */
1021
1022         threads_mutex_join_lock();
1023
1024         /* Free the internal thread data-structure. */
1025
1026         thread_free(t);
1027
1028         /* Signal that this thread has finished and leave the mutex. */
1029
1030         cond_join->signal();
1031         threads_mutex_join_unlock();
1032
1033         t->suspendmutex->lock();
1034         t->suspendmutex->unlock();
1035
1036         return true;
1037 }
1038
1039
1040 /**
1041  * Internal helper function which suspends the current thread. This is
1042  * the core method of the suspension mechanism actually blocking the
1043  * execution until the suspension reason is cleared again. Note that
1044  * the current thread needs to hold the suspension mutex while calling
1045  * this function.
1046  */
1047 static void threads_suspend_self()
1048 {
1049         threadobject* thread = THREADOBJECT;
1050
1051         DEBUGTHREADS("suspending", thread);
1052
1053         // Mark thread as suspended.
1054         assert(!thread->suspended);
1055         assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1056         thread->suspended = true;
1057
1058         // Acknowledge the suspension.
1059         thread->suspendcond->broadcast();
1060
1061 #if defined(ENABLE_GC_CACAO)
1062         // If we are stopping the world, we should send a global ack.
1063         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1064                 threads_sem_post(&suspend_ack);
1065 #endif
1066
1067         // Release the suspension mutex and wait till we are resumed.
1068         while (thread->suspend_reason != SUSPEND_REASON_NONE)
1069                 thread->suspendcond->wait(thread->suspendmutex);
1070
1071 #if defined(ENABLE_GC_CACAO)
1072         // XXX This is propably not ok!
1073         // If we are starting the world, we should send a global ack.
1074         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1075                 threads_sem_post(&suspend_ack);
1076 #endif
1077
1078         // Mark thread as not suspended.
1079         assert(thread->suspended);
1080         assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1081         thread->suspended = false;
1082
1083         DEBUGTHREADS("resuming", thread);
1084 }
1085
1086
1087 /**
1088  * Suspend the passed thread. Execution of that thread stops until the thread
1089  * is explicitly resumed again.
1090  *
1091  * @param thread The thread to be suspended.
1092  * @param reason Reason for suspending the given thread.
1093  * @return True of operation was successful, false otherwise.
1094  */
1095 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1096 {
1097         // Sanity check.
1098         assert(reason != SUSPEND_REASON_NONE);
1099
1100         // Guard this with the suspension mutex.
1101         MutexLocker ml(*thread->suspendmutex);
1102
1103         // Check if thread is already suspended.
1104         if (thread->suspended)
1105                 return false;
1106
1107         // Check if thread is in the process of suspending.
1108         if (thread->suspend_reason != SUSPEND_REASON_NONE)
1109                 return false;
1110
1111         // Set the reason for suspending the thread.
1112         thread->suspend_reason = reason;
1113
1114         if (thread == THREADOBJECT) {
1115                 // We already hold the suspension mutex and can suspend ourselves
1116                 // immediately without using signals at all.
1117                 threads_suspend_self();
1118         }
1119         else {
1120                 // Send the suspend signal to the other thread.
1121                 if (!thread->tid)
1122                         return false;
1123                 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1124                         os::abort_errno("threads_suspend_thread: pthread_kill failed");
1125
1126                 // Wait for the thread to acknowledge the suspension.
1127                 while (!thread->suspended)
1128                         thread->suspendcond->wait(thread->suspendmutex);
1129         }
1130
1131         return true;
1132 }
1133
1134
1135 /**
1136  * Resumes execution of the passed thread.
1137  *
1138  * @param thread The thread to be resumed.
1139  * @param reason Reason for suspending the given thread.
1140  * @return True of operation was successful, false otherwise.
1141  */
1142 bool threads_resume_thread(threadobject *thread, int32_t reason)
1143 {
1144         // Sanity check.
1145         assert(thread != THREADOBJECT);
1146         assert(reason != SUSPEND_REASON_NONE);
1147
1148         // Guard this with the suspension mutex.
1149         MutexLocker ml(*thread->suspendmutex);
1150
1151         // Check if thread really is suspended.
1152         if (!thread->suspended)
1153                 return false;
1154
1155         // Threads can only be resumed for the same reason they were suspended.
1156         if (thread->suspend_reason != reason)
1157                 return false;
1158
1159         // Clear the reason for suspending the thread.
1160         thread->suspend_reason = SUSPEND_REASON_NONE;
1161
1162         // Tell everyone that the thread should resume.
1163         thread->suspendcond->broadcast();
1164
1165         return true;
1166 }
1167
1168
1169 /**
1170  * Acknowledges the suspension of the current thread.
1171  */
1172 void threads_suspend_ack()
1173 {
1174         threadobject* thread = THREADOBJECT;
1175
1176         // Guard this with the suspension mutex.
1177         MutexLocker ml(*thread->suspendmutex);
1178
1179         // Suspend ourselves while holding the suspension mutex.
1180         threads_suspend_self();
1181 }
1182
1183
1184 /* threads_join_all_threads ****************************************************
1185
1186    Join all non-daemon threads.
1187
1188 *******************************************************************************/
1189
1190 void threads_join_all_threads(void)
1191 {
1192         threadobject *t;
1193
1194         /* get current thread */
1195
1196         t = THREADOBJECT;
1197
1198         /* This thread is waiting for all non-daemon threads to exit. */
1199
1200         thread_set_state_waiting(t);
1201
1202         /* enter join mutex */
1203
1204         threads_mutex_join_lock();
1205
1206         /* Wait for condition as long as we have non-daemon threads.  We
1207            compare against 1 because the current (main thread) is also a
1208            non-daemon thread. */
1209
1210         while (ThreadList::get_number_of_non_daemon_threads() > 1)
1211                 cond_join->wait(mutex_join);
1212
1213         /* leave join mutex */
1214
1215         threads_mutex_join_unlock();
1216 }
1217
1218
1219 /* threads_timespec_earlier ****************************************************
1220
1221    Return true if timespec tv1 is earlier than timespec tv2.
1222
1223    IN:
1224       tv1..........first timespec
1225           tv2..........second timespec
1226
1227    RETURN VALUE:
1228       true, if the first timespec is earlier
1229
1230 *******************************************************************************/
1231
1232 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1233                                                                                         const struct timespec *tv2)
1234 {
1235         return (tv1->tv_sec < tv2->tv_sec)
1236                                 ||
1237                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1238 }
1239
1240
1241 /* threads_current_time_is_earlier_than ****************************************
1242
1243    Check if the current time is earlier than the given timespec.
1244
1245    IN:
1246       tv...........the timespec to compare against
1247
1248    RETURN VALUE:
1249       true, if the current time is earlier
1250
1251 *******************************************************************************/
1252
1253 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1254 {
1255         struct timeval tvnow;
1256         struct timespec tsnow;
1257
1258         /* get current time */
1259
1260         if (gettimeofday(&tvnow, NULL) != 0)
1261                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1262
1263         /* convert it to a timespec */
1264
1265         tsnow.tv_sec = tvnow.tv_sec;
1266         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1267
1268         /* compare current time with the given timespec */
1269
1270         return threads_timespec_earlier(&tsnow, tv);
1271 }
1272
1273
1274 /* threads_wait_with_timeout ***************************************************
1275
1276    Wait until the given point in time on a monitor until either
1277    we are notified, we are interrupted, or the time is up.
1278
1279    IN:
1280       t............the current thread
1281           wakeupTime...absolute (latest) wakeup time
1282                            If both tv_sec and tv_nsec are zero, this function
1283                                            waits for an unlimited amount of time.
1284
1285 *******************************************************************************/
1286
1287 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1288 {
1289         // Acquire the waitmutex.
1290         t->waitmutex->lock();
1291
1292         /* wait on waitcond */
1293
1294         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1295                 /* with timeout */
1296                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1297                            && threads_current_time_is_earlier_than(wakeupTime))
1298                 {
1299                         if (parking)
1300                                 thread_set_state_timed_parked(t);
1301                         else
1302                                 thread_set_state_timed_waiting(t);
1303
1304                         t->waitcond->timedwait(t->waitmutex, wakeupTime);
1305
1306                         thread_set_state_runnable(t);
1307                 }
1308         }
1309         else {
1310                 /* no timeout */
1311                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1312                         if (parking)
1313                                 thread_set_state_parked(t);
1314                         else
1315                                 thread_set_state_waiting(t);
1316
1317                         t->waitcond->wait(t->waitmutex);
1318
1319                         thread_set_state_runnable(t);
1320                 }
1321         }
1322
1323         if (parking)
1324                 t->park_permit = false;
1325
1326         // Release the waitmutex.
1327         t->waitmutex->unlock();
1328 }
1329
1330
1331 /* threads_wait_with_timeout_relative ******************************************
1332
1333    Wait for the given maximum amount of time on a monitor until either
1334    we are notified, we are interrupted, or the time is up.
1335
1336    IN:
1337       t............the current thread
1338           millis.......milliseconds to wait
1339           nanos........nanoseconds to wait
1340
1341 *******************************************************************************/
1342
1343 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1344                                                                                 s4 nanos)
1345 {
1346         struct timespec wakeupTime;
1347
1348         /* calculate the the (latest) wakeup time */
1349
1350         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1351
1352         /* wait */
1353
1354         threads_wait_with_timeout(thread, &wakeupTime, false);
1355 }
1356
1357
1358 /* threads_calc_absolute_time **************************************************
1359
1360    Calculate the absolute point in time a given number of ms and ns from now.
1361
1362    IN:
1363       millis............milliseconds from now
1364           nanos.............nanoseconds from now
1365
1366    OUT:
1367       *tm...............receives the timespec of the absolute point in time
1368
1369 *******************************************************************************/
1370
1371 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1372 {
1373         // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1374         do {
1375                 if (!millis && !nanos)
1376                         break;
1377                 struct timeval tv;
1378                 gettimeofday(&tv, NULL);
1379                 s8 secs = tv.tv_sec + millis / 1000;
1380                 if (secs > INT32_MAX)   // integer overflow
1381                         break;
1382                 tv.tv_sec = secs;
1383                 millis %= 1000;
1384                 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1385                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1386                 if (tm->tv_sec < tv.tv_sec) // integer overflow
1387                         break;
1388                 tm->tv_nsec = nsec % 1000000000;
1389                 return;
1390         } while (0);
1391         tm->tv_sec = 0;
1392         tm->tv_nsec = 0;
1393 }
1394
1395
1396 /* threads_thread_interrupt ****************************************************
1397
1398    Interrupt the given thread.
1399
1400    The thread gets the "waitcond" signal and 
1401    its interrupted flag is set to true.
1402
1403    IN:
1404       thread............the thread to interrupt
1405
1406 *******************************************************************************/
1407
1408 void threads_thread_interrupt(threadobject *t)
1409 {
1410         /* Signal the thread a "waitcond" and tell it that it has been
1411            interrupted. */
1412
1413         t->waitmutex->lock();
1414
1415         DEBUGTHREADS("interrupted", t);
1416
1417         /* Interrupt blocking system call using a signal. */
1418
1419         if (t->tid)
1420                 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1421
1422         t->waitcond->signal();
1423
1424         t->interrupted = true;
1425
1426         t->waitmutex->unlock();
1427 }
1428
1429
1430 /**
1431  * Sleep the current thread for the specified amount of time.
1432  *
1433  * @param millis Milliseconds to sleep.
1434  * @param nanos  Nanoseconds to sleep.
1435  */
1436 void threads_sleep(int64_t millis, int32_t nanos)
1437 {
1438         threadobject    *t;
1439         struct timespec  wakeupTime;
1440         bool             interrupted;
1441
1442         if (millis < 0) {
1443 /*              exceptions_throw_illegalargumentexception("timeout value is negative"); */
1444                 exceptions_throw_illegalargumentexception();
1445                 return;
1446         }
1447
1448         t = thread_get_current();
1449
1450         if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1451                 /* Clear interrupted flag (Mauve test:
1452                    gnu/testlet/java/lang/Thread/interrupt). */
1453
1454                 thread_set_interrupted(t, false);
1455
1456 /*              exceptions_throw_interruptedexception("sleep interrupted"); */
1457                 exceptions_throw_interruptedexception();
1458                 return;
1459         }
1460
1461         // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1462         // Note: JDK treats a zero length sleep is like Thread.yield(),
1463         // without checking the interrupted status of the thread.  It's
1464         // unclear if this is a bug in the implementation or the spec.
1465         // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1466         if (millis == 0 && nanos == 0) {
1467                 threads_yield();
1468         }
1469         else {
1470                 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1471
1472                 threads_wait_with_timeout(t, &wakeupTime, false);
1473
1474                 interrupted = thread_is_interrupted(t);
1475
1476                 if (interrupted) {
1477                         thread_set_interrupted(t, false);
1478
1479                         // An other exception could have been thrown
1480                         // (e.g. ThreadDeathException).
1481                         if (!exceptions_get_exception())
1482                                 exceptions_throw_interruptedexception();
1483                 }
1484         }
1485 }
1486
1487 /**
1488  * Park the current thread for the specified amount of time or until a
1489  * specified deadline.
1490  *
1491  * @param absolute Is the time in nanos a deadline or a duration?
1492  * @param nanos    Nanoseconds to park (absolute=false)
1493  *                 or deadline in milliseconds (absolute=true)
1494  */
1495 void threads_park(bool absolute, int64_t nanos)
1496 {
1497         threadobject    *t;
1498         struct timespec  wakeupTime;
1499
1500         t = thread_get_current();
1501
1502         if (absolute) {
1503                 wakeupTime.tv_nsec = 0;
1504                 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1505         }
1506         else
1507                 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1508
1509         threads_wait_with_timeout(t, &wakeupTime, true);
1510 }
1511
1512 /**
1513  * Unpark the specified thread.
1514  *
1515  * @param t The thread to unpark.
1516  */
1517 void threads_unpark(threadobject *t)
1518 {
1519         t->waitmutex->lock();
1520
1521         t->waitcond->signal();
1522
1523         t->park_permit = true;
1524
1525         t->waitmutex->unlock();
1526 }
1527
1528
1529 /* threads_yield ***************************************************************
1530
1531    Yield to the scheduler.
1532
1533 *******************************************************************************/
1534
1535 void threads_yield(void)
1536 {
1537         sched_yield();
1538 }
1539
1540 #if defined(ENABLE_TLH)
1541
1542 void threads_tlh_add_frame() {
1543         tlh_add_frame(&(THREADOBJECT->tlh));
1544 }
1545
1546 void threads_tlh_remove_frame() {
1547         tlh_remove_frame(&(THREADOBJECT->tlh));
1548 }
1549
1550 #endif
1551
1552
1553 /*
1554  * These are local overrides for various environment variables in Emacs.
1555  * Please do not remove this and leave it at the end of the file, where
1556  * Emacs will automagically detect them.
1557  * ---------------------------------------------------------------------
1558  * Local variables:
1559  * mode: c++
1560  * indent-tabs-mode: t
1561  * c-basic-offset: 4
1562  * tab-width: 4
1563  * End:
1564  * vim:noexpandtab:sw=4:ts=4:
1565  */