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