1d9b3881e5e326abbae18f81cdf761610f595a08
[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
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
536 /* threads_impl_preinit ********************************************************
537
538    Do some early initialization of stuff required.
539
540    ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
541    is called AFTER this function!
542
543 *******************************************************************************/
544
545 void threads_impl_preinit(void)
546 {
547         stopworldlock = new Mutex();
548
549         /* initialize exit mutex and condition (on exit we join all
550            threads) */
551
552         mutex_join = new Mutex();
553         cond_join = new Condition();
554
555 #if defined(ENABLE_GC_CACAO)
556         /* initialize the GC mutex & suspend semaphore */
557
558         mutex_gc = new Mutex();
559         threads_sem_init(&suspend_ack, 0, 0);
560 #endif
561
562 #if !defined(HAVE___THREAD)
563         int result = pthread_key_create(&thread_current_key, NULL);
564         if (result != 0)
565                 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
566 #endif
567 }
568
569
570 /* threads_mutex_gc_lock *******************************************************
571
572    Enter the global GC mutex.
573
574 *******************************************************************************/
575
576 #if defined(ENABLE_GC_CACAO)
577 void threads_mutex_gc_lock(void)
578 {
579         mutex_gc->lock();
580 }
581 #endif
582
583
584 /* threads_mutex_gc_unlock *****************************************************
585
586    Leave the global GC mutex.
587
588 *******************************************************************************/
589
590 #if defined(ENABLE_GC_CACAO)
591 void threads_mutex_gc_unlock(void)
592 {
593         mutex_gc->unlock();
594 }
595 #endif
596
597 /* threads_mutex_join_lock *****************************************************
598
599    Enter the join mutex.
600
601 *******************************************************************************/
602
603 void threads_mutex_join_lock(void)
604 {
605         mutex_join->lock();
606 }
607
608
609 /* threads_mutex_join_unlock ***************************************************
610
611    Leave the join mutex.
612
613 *******************************************************************************/
614
615 void threads_mutex_join_unlock(void)
616 {
617         mutex_join->unlock();
618 }
619
620
621 /* threads_impl_init ***********************************************************
622
623    Initializes the implementation specific bits.
624
625 *******************************************************************************/
626
627 void threads_impl_init(void)
628 {
629         pthread_attr_t attr;
630         int            result;
631
632         threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
633
634         /* Initialize the thread attribute object. */
635
636         result = pthread_attr_init(&attr);
637
638         if (result != 0)
639                 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
640
641         result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
642
643         if (result != 0)
644                 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
645 }
646
647
648 /* threads_startup_thread ******************************************************
649
650    Thread startup function called by pthread_create.
651
652    Thread which have a startup.function != NULL are marked as internal
653    threads. All other threads are threated as normal Java threads.
654
655    NOTE: This function is not called directly by pthread_create. The Boehm GC
656          inserts its own GC_start_routine in between, which then calls
657                  threads_startup.
658
659    IN:
660       arg..........the argument passed to pthread_create, ie. a pointer to
661                        a startupinfo struct. CAUTION: When the `psem` semaphore
662                                    is posted, the startupinfo struct becomes invalid! (It
663                                    is allocated on the stack of threads_start_thread.)
664
665 ******************************************************************************/
666
667 static void *threads_startup_thread(void *arg)
668 {
669         startupinfo  *startup;
670         threadobject *t;
671         sem_t        *psem;
672         classinfo    *c;
673         methodinfo   *m;
674         functionptr   function;
675
676 #if defined(ENABLE_GC_BOEHM)
677 # if !defined(__DARWIN__)
678         struct GC_stack_base sb;
679         int result;
680 # endif
681 #endif
682
683 #if defined(ENABLE_INTRP)
684         u1 *intrp_thread_stack;
685 #endif
686
687 #if defined(ENABLE_INTRP)
688         /* create interpreter stack */
689
690         if (opt_intrp) {
691                 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
692                 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
693         }
694         else
695                 intrp_thread_stack = NULL;
696 #endif
697
698         /* get passed startupinfo structure and the values in there */
699
700         startup = (startupinfo*) arg;
701
702         t        = startup->thread;
703         function = startup->function;
704         psem     = startup->psem;
705
706         /* Seems like we've encountered a situation where thread->tid was
707            not set by pthread_create. We alleviate this problem by waiting
708            for pthread_create to return. */
709
710         threads_sem_wait(startup->psem_first);
711
712 #if defined(__DARWIN__)
713         t->mach_thread = mach_thread_self();
714 #endif
715
716         /* Now that we are in the new thread, we can store the internal
717            thread data-structure in the TSD. */
718
719         thread_set_current(t);
720
721 #if defined(ENABLE_GC_BOEHM)
722 # if defined(__DARWIN__)
723         // This is currently not implemented in Boehm-GC.  Just fail silently.
724 # else
725         /* Register the thread with Boehm-GC.  This must happen before the
726            thread allocates any memory from the GC heap.*/
727
728         result = GC_get_stack_base(&sb);
729
730         if (result != 0)
731                 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
732
733         GC_register_my_thread(&sb);
734 # endif
735 #endif
736
737         // Get the java.lang.Thread object for this thread.
738         java_handle_t* object = thread_get_object(t);
739         java_lang_Thread jlt(object);
740
741         /* set our priority */
742
743         threads_set_thread_priority(t->tid, jlt.get_priority());
744
745         /* Thread is completely initialized. */
746
747         thread_set_state_runnable(t);
748
749         /* tell threads_startup_thread that we registered ourselves */
750         /* CAUTION: *startup becomes invalid with this!             */
751
752         startup = NULL;
753         threads_sem_post(psem);
754
755 #if defined(ENABLE_INTRP)
756         /* set interpreter stack */
757
758         if (opt_intrp)
759                 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
760 #endif
761
762         // Hook point just before the threads initial method is executed.
763         Hook::thread_start(t);
764
765         DEBUGTHREADS("starting", t);
766
767         /* find and run the Thread.run()V method if no other function was passed */
768
769         if (function == NULL) {
770                 c = ThreadRuntime::get_thread_class_from_object(object);
771
772                 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
773
774                 if (m == NULL)
775                         vm_abort("threads_startup_thread: run() method not found in class");
776
777                 java_handle_t *h = ThreadRuntime::get_vmthread_handle(jlt);
778
779                 /* Run the thread. */
780
781                 (void) vm_call_method(m, h);
782         }
783         else {
784                 /* call passed function, e.g. finalizer_thread */
785
786                 (function)();
787         }
788
789         DEBUGTHREADS("stopping", t);
790
791         // Hook point just after the threads initial method returned.
792         Hook::thread_end(t);
793
794         /* We ignore the return value. */
795
796         (void) thread_detach_current_thread();
797
798         return NULL;
799 }
800
801
802 /* threads_impl_thread_start ***************************************************
803
804    Start a thread in the JVM.  Both (vm internal and java) thread
805    objects exist.
806
807    IN:
808       thread....the thread object
809           f.........function to run in the new thread. NULL means that the
810                     "run" method of the object `t` should be called
811
812 ******************************************************************************/
813
814 void threads_impl_thread_start(threadobject *thread, functionptr f)
815 {
816         sem_t          sem;
817         sem_t          sem_first;
818         pthread_attr_t attr;
819         startupinfo    startup;
820         int            result;
821
822         /* fill startupinfo structure passed by pthread_create to
823          * threads_startup_thread */
824
825         startup.thread     = thread;
826         startup.function   = f;              /* maybe we don't call Thread.run()V */
827         startup.psem       = &sem;
828         startup.psem_first = &sem_first;
829
830         threads_sem_init(&sem, 0, 0);
831         threads_sem_init(&sem_first, 0, 0);
832
833         /* Initialize thread attributes. */
834
835         result = pthread_attr_init(&attr);
836
837         if (result != 0)
838                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
839
840     result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
841
842     if (result != 0)
843                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
844
845         /* initialize thread stacksize */
846
847         result = pthread_attr_setstacksize(&attr, opt_stacksize);
848
849         if (result != 0)
850                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
851
852         /* create the thread */
853
854         result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
855
856         if (result != 0)
857                 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
858
859         /* destroy the thread attributes */
860
861         result = pthread_attr_destroy(&attr);
862
863         if (result != 0)
864                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
865
866         /* signal that pthread_create has returned, so thread->tid is valid */
867
868         threads_sem_post(&sem_first);
869
870         /* wait here until the thread has entered itself into the thread list */
871
872         threads_sem_wait(&sem);
873
874         /* cleanup */
875
876         sem_destroy(&sem);
877         sem_destroy(&sem_first);
878 }
879
880
881 /* threads_set_thread_priority *************************************************
882
883    Set the priority of the given thread.
884
885    IN:
886       tid..........thread id
887           priority.....priority to set
888
889 ******************************************************************************/
890
891 void threads_set_thread_priority(pthread_t tid, int priority)
892 {
893         struct sched_param schedp;
894         int policy;
895
896         pthread_getschedparam(tid, &policy, &schedp);
897         schedp.sched_priority = priority;
898         pthread_setschedparam(tid, policy, &schedp);
899 }
900
901
902 /**
903  * Detaches the current thread from the VM.
904  *
905  * @return true on success, false otherwise
906  */
907 bool thread_detach_current_thread(void)
908 {
909         threadobject* t = thread_get_current();
910
911         /* Sanity check. */
912
913         assert(t != NULL);
914
915     /* If the given thread has already been detached, this operation
916            is a no-op. */
917
918         if (thread_is_attached(t) == false)
919                 return true;
920
921         DEBUGTHREADS("detaching", t);
922
923         java_handle_t* object = thread_get_object(t);
924         java_lang_Thread jlt(object);
925
926 #if defined(ENABLE_JAVASE)
927         java_handle_t* group = jlt.get_group();
928
929     /* If there's an uncaught exception, call uncaughtException on the
930        thread's exception handler, or the thread's group if this is
931        unset. */
932
933         java_handle_t* e = exceptions_get_and_clear_exception();
934
935     if (e != NULL) {
936                 /* We use the type void* for handler here, as it's not trivial
937                    to build the java_lang_Thread_UncaughtExceptionHandler
938                    header file with cacaoh. */
939
940                 java_handle_t *handler = ThreadRuntime::get_thread_exception_handler(jlt);
941
942                 classinfo*     c;
943                 java_handle_t* h;
944
945                 if (handler != NULL) {
946                         LLNI_class_get(handler, c);
947                         h = (java_handle_t *) handler;
948                 }
949                 else {
950                         LLNI_class_get(group, c);
951                         h = (java_handle_t *) group;
952                 }
953
954                 methodinfo* m = class_resolveclassmethod(c,
955                                                                                                  utf_uncaughtException,
956                                                                                                  utf_java_lang_Thread_java_lang_Throwable__V,
957                                                                                                  NULL,
958                                                                                                  true);
959
960                 if (m == NULL)
961                         return false;
962
963                 (void) vm_call_method(m, h, object, e);
964
965                 if (exceptions_get_exception())
966                         return false;
967     }
968
969         /* XXX TWISTI: should all threads be in a ThreadGroup? */
970
971         /* Remove thread from the thread group. */
972
973         if (group != NULL) {
974                 classinfo* c;
975                 LLNI_class_get(group, c);
976
977                 methodinfo *m = ThreadRuntime::get_threadgroup_remove_method(c);
978
979                 if (m == NULL)
980                         return false;
981
982                 (void) vm_call_method(m, group, object);
983
984                 if (exceptions_get_exception())
985                         return false;
986
987                 // Clear the ThreadGroup in the Java thread object (Mauve
988                 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
989                 jlt.set_group(NULL);
990         }
991 #endif
992
993         /* Thread has terminated. */
994
995         thread_set_state_terminated(t);
996
997         /* Notify all threads waiting on this thread.  These are joining
998            this thread. */
999
1000         /* XXX Care about exceptions? */
1001         (void) lock_monitor_enter(jlt.get_handle());
1002         
1003         lock_notify_all_object(jlt.get_handle());
1004
1005         /* XXX Care about exceptions? */
1006         (void) lock_monitor_exit(jlt.get_handle());
1007
1008         /* Enter the join-mutex before calling thread_free, so
1009            threads_join_all_threads gets the correct number of non-daemon
1010            threads. */
1011
1012         threads_mutex_join_lock();
1013
1014         /* Free the internal thread data-structure. */
1015
1016         thread_free(t);
1017
1018         /* Signal that this thread has finished and leave the mutex. */
1019
1020         cond_join->signal();
1021         threads_mutex_join_unlock();
1022
1023         return true;
1024 }
1025
1026
1027 /**
1028  * Internal helper function which suspends the current thread. This is
1029  * the core method of the suspension mechanism actually blocking the
1030  * execution until the suspension reason is cleared again. Note that
1031  * the current thread needs to hold the suspension mutex while calling
1032  * this function.
1033  */
1034 static void threads_suspend_self()
1035 {
1036         threadobject* thread = THREADOBJECT;
1037
1038         DEBUGTHREADS("suspending", thread);
1039
1040         // Mark thread as suspended.
1041         assert(!thread->suspended);
1042         assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1043         thread->suspended = true;
1044
1045         // Acknowledge the suspension.
1046         thread->suspendcond->broadcast();
1047
1048 #if defined(ENABLE_GC_CACAO)
1049         // If we are stopping the world, we should send a global ack.
1050         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1051                 threads_sem_post(&suspend_ack);
1052 #endif
1053
1054         // Release the suspension mutex and wait till we are resumed.
1055         thread->suspendcond->wait(thread->suspendmutex);
1056
1057 #if defined(ENABLE_GC_CACAO)
1058         // XXX This is propably not ok!
1059         // If we are starting the world, we should send a global ack.
1060         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1061                 threads_sem_post(&suspend_ack);
1062 #endif
1063
1064         // Mark thread as not suspended.
1065         assert(thread->suspended);
1066         assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1067         thread->suspended = false;
1068
1069         DEBUGTHREADS("resuming", thread);
1070 }
1071
1072
1073 /**
1074  * Suspend the passed thread. Execution of that thread stops until the thread
1075  * is explicitly resumend again.
1076  *
1077  * @param thread The thread to be suspended.
1078  * @param reason Reason for suspending the given thread.
1079  * @return True of operation was successful, false otherwise.
1080  */
1081 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1082 {
1083         // Sanity check.
1084         assert(reason != SUSPEND_REASON_NONE);
1085
1086         // Guard this with the suspension mutex.
1087         MutexLocker ml(*thread->suspendmutex);
1088
1089         // Check if thread is already suspended.
1090         if (thread->suspended)
1091                 return false;
1092
1093         // Check if thread is in the process of suspending.
1094         if (thread->suspend_reason != SUSPEND_REASON_NONE)
1095                 return false;
1096
1097         // Set the reason for suspending the thread.
1098         thread->suspend_reason = reason;
1099
1100         if (thread == THREADOBJECT) {
1101                 // We already hold the suspension mutex and can suspend ourselves
1102                 // immediately without using signals at all.
1103                 threads_suspend_self();
1104         }
1105         else {
1106                 // Send the suspend signal to the other thread.
1107                 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1108                         os::abort_errno("threads_suspend_thread: pthread_kill failed");
1109
1110                 // Wait for the thread to acknowledge the suspension.
1111                 // XXX A possible optimization would be to not wait here, but you
1112                 //     better think this through twice before trying it!
1113                 thread->suspendcond->wait(thread->suspendmutex);
1114         }
1115
1116         return true;
1117 }
1118
1119
1120 /**
1121  * Resumes execution of the passed thread.
1122  *
1123  * @param thread The thread to be resumed.
1124  * @param reason Reason for suspending the given thread.
1125  * @return True of operation was successful, false otherwise.
1126  */
1127 bool threads_resume_thread(threadobject *thread, int32_t reason)
1128 {
1129         // Sanity check.
1130         assert(thread != THREADOBJECT);
1131         assert(reason != SUSPEND_REASON_NONE);
1132
1133         // Guard this with the suspension mutex.
1134         MutexLocker ml(*thread->suspendmutex);
1135
1136         // Check if thread really is suspended.
1137         if (!thread->suspended)
1138                 return false;
1139
1140         // Threads can only be resumed for the same reason they were suspended.
1141         if (thread->suspend_reason != reason)
1142                 return false;
1143
1144         // Clear the reason for suspending the thread.
1145         thread->suspend_reason = SUSPEND_REASON_NONE;
1146
1147         // Tell everyone that the thread should resume.
1148         thread->suspendcond->broadcast();
1149
1150         return true;
1151 }
1152
1153
1154 /**
1155  * Acknowledges the suspension of the current thread.
1156  */
1157 void threads_suspend_ack()
1158 {
1159         threadobject* thread = THREADOBJECT;
1160
1161         // Guard this with the suspension mutex.
1162         MutexLocker ml(*thread->suspendmutex);
1163
1164         // Suspend ourselves while holding the suspension mutex.
1165         threads_suspend_self();
1166 }
1167
1168
1169 /* threads_join_all_threads ****************************************************
1170
1171    Join all non-daemon threads.
1172
1173 *******************************************************************************/
1174
1175 void threads_join_all_threads(void)
1176 {
1177         threadobject *t;
1178
1179         /* get current thread */
1180
1181         t = THREADOBJECT;
1182
1183         /* This thread is waiting for all non-daemon threads to exit. */
1184
1185         thread_set_state_waiting(t);
1186
1187         /* enter join mutex */
1188
1189         threads_mutex_join_lock();
1190
1191         /* Wait for condition as long as we have non-daemon threads.  We
1192            compare against 1 because the current (main thread) is also a
1193            non-daemon thread. */
1194
1195         while (ThreadList::get_number_of_non_daemon_threads() > 1)
1196                 cond_join->wait(mutex_join);
1197
1198         /* leave join mutex */
1199
1200         threads_mutex_join_unlock();
1201 }
1202
1203
1204 /* threads_timespec_earlier ****************************************************
1205
1206    Return true if timespec tv1 is earlier than timespec tv2.
1207
1208    IN:
1209       tv1..........first timespec
1210           tv2..........second timespec
1211
1212    RETURN VALUE:
1213       true, if the first timespec is earlier
1214
1215 *******************************************************************************/
1216
1217 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1218                                                                                         const struct timespec *tv2)
1219 {
1220         return (tv1->tv_sec < tv2->tv_sec)
1221                                 ||
1222                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1223 }
1224
1225
1226 /* threads_current_time_is_earlier_than ****************************************
1227
1228    Check if the current time is earlier than the given timespec.
1229
1230    IN:
1231       tv...........the timespec to compare against
1232
1233    RETURN VALUE:
1234       true, if the current time is earlier
1235
1236 *******************************************************************************/
1237
1238 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1239 {
1240         struct timeval tvnow;
1241         struct timespec tsnow;
1242
1243         /* get current time */
1244
1245         if (gettimeofday(&tvnow, NULL) != 0)
1246                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1247
1248         /* convert it to a timespec */
1249
1250         tsnow.tv_sec = tvnow.tv_sec;
1251         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1252
1253         /* compare current time with the given timespec */
1254
1255         return threads_timespec_earlier(&tsnow, tv);
1256 }
1257
1258
1259 /* threads_wait_with_timeout ***************************************************
1260
1261    Wait until the given point in time on a monitor until either
1262    we are notified, we are interrupted, or the time is up.
1263
1264    IN:
1265       t............the current thread
1266           wakeupTime...absolute (latest) wakeup time
1267                            If both tv_sec and tv_nsec are zero, this function
1268                                            waits for an unlimited amount of time.
1269
1270 *******************************************************************************/
1271
1272 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1273 {
1274         // Acquire the waitmutex.
1275         t->waitmutex->lock();
1276
1277         /* wait on waitcond */
1278
1279         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1280                 /* with timeout */
1281                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1282                            && threads_current_time_is_earlier_than(wakeupTime))
1283                 {
1284                         if (parking)
1285                                 thread_set_state_timed_parked(t);
1286                         else
1287                                 thread_set_state_timed_waiting(t);
1288
1289                         t->waitcond->timedwait(t->waitmutex, wakeupTime);
1290
1291                         thread_set_state_runnable(t);
1292                 }
1293         }
1294         else {
1295                 /* no timeout */
1296                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1297                         if (parking)
1298                                 thread_set_state_parked(t);
1299                         else
1300                                 thread_set_state_waiting(t);
1301
1302                         t->waitcond->wait(t->waitmutex);
1303
1304                         thread_set_state_runnable(t);
1305                 }
1306         }
1307
1308         if (parking)
1309                 t->park_permit = false;
1310
1311         // Release the waitmutex.
1312         t->waitmutex->unlock();
1313 }
1314
1315
1316 /* threads_wait_with_timeout_relative ******************************************
1317
1318    Wait for the given maximum amount of time on a monitor until either
1319    we are notified, we are interrupted, or the time is up.
1320
1321    IN:
1322       t............the current thread
1323           millis.......milliseconds to wait
1324           nanos........nanoseconds to wait
1325
1326 *******************************************************************************/
1327
1328 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1329                                                                                 s4 nanos)
1330 {
1331         struct timespec wakeupTime;
1332
1333         /* calculate the the (latest) wakeup time */
1334
1335         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1336
1337         /* wait */
1338
1339         threads_wait_with_timeout(thread, &wakeupTime, false);
1340 }
1341
1342
1343 /* threads_calc_absolute_time **************************************************
1344
1345    Calculate the absolute point in time a given number of ms and ns from now.
1346
1347    IN:
1348       millis............milliseconds from now
1349           nanos.............nanoseconds from now
1350
1351    OUT:
1352       *tm...............receives the timespec of the absolute point in time
1353
1354 *******************************************************************************/
1355
1356 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1357 {
1358         // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1359         do {
1360                 if (!millis && !nanos)
1361                         break;
1362                 struct timeval tv;
1363                 gettimeofday(&tv, NULL);
1364                 s8 secs = tv.tv_sec + millis / 1000;
1365                 if (secs > INT32_MAX)   // integer overflow
1366                         break;
1367                 tv.tv_sec = secs;
1368                 millis %= 1000;
1369                 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1370                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1371                 if (tm->tv_sec < tv.tv_sec) // integer overflow
1372                         break;
1373                 tm->tv_nsec = nsec % 1000000000;
1374                 return;
1375         } while (0);
1376         tm->tv_sec = 0;
1377         tm->tv_nsec = 0;
1378 }
1379
1380
1381 /* threads_thread_interrupt ****************************************************
1382
1383    Interrupt the given thread.
1384
1385    The thread gets the "waitcond" signal and 
1386    its interrupted flag is set to true.
1387
1388    IN:
1389       thread............the thread to interrupt
1390
1391 *******************************************************************************/
1392
1393 void threads_thread_interrupt(threadobject *t)
1394 {
1395         /* Signal the thread a "waitcond" and tell it that it has been
1396            interrupted. */
1397
1398         t->waitmutex->lock();
1399
1400         DEBUGTHREADS("interrupted", t);
1401
1402         /* Interrupt blocking system call using a signal. */
1403
1404         pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1405
1406         t->waitcond->signal();
1407
1408         t->interrupted = true;
1409
1410         t->waitmutex->unlock();
1411 }
1412
1413
1414 /**
1415  * Sleep the current thread for the specified amount of time.
1416  *
1417  * @param millis Milliseconds to sleep.
1418  * @param nanos  Nanoseconds to sleep.
1419  */
1420 void threads_sleep(int64_t millis, int32_t nanos)
1421 {
1422         threadobject    *t;
1423         struct timespec  wakeupTime;
1424         bool             interrupted;
1425
1426         if (millis < 0) {
1427 /*              exceptions_throw_illegalargumentexception("timeout value is negative"); */
1428                 exceptions_throw_illegalargumentexception();
1429                 return;
1430         }
1431
1432         t = thread_get_current();
1433
1434         if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1435                 /* Clear interrupted flag (Mauve test:
1436                    gnu/testlet/java/lang/Thread/interrupt). */
1437
1438                 thread_set_interrupted(t, false);
1439
1440 /*              exceptions_throw_interruptedexception("sleep interrupted"); */
1441                 exceptions_throw_interruptedexception();
1442                 return;
1443         }
1444
1445         // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1446         // Note: JDK treats a zero length sleep is like Thread.yield(),
1447         // without checking the interrupted status of the thread.  It's
1448         // unclear if this is a bug in the implementation or the spec.
1449         // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1450         if (millis == 0 && nanos == 0) {
1451                 threads_yield();
1452         }
1453         else {
1454                 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1455
1456                 threads_wait_with_timeout(t, &wakeupTime, false);
1457
1458                 interrupted = thread_is_interrupted(t);
1459
1460                 if (interrupted) {
1461                         thread_set_interrupted(t, false);
1462
1463                         // An other exception could have been thrown
1464                         // (e.g. ThreadDeathException).
1465                         if (!exceptions_get_exception())
1466                                 exceptions_throw_interruptedexception();
1467                 }
1468         }
1469 }
1470
1471 /**
1472  * Park the current thread for the specified amount of time or until a
1473  * specified deadline.
1474  *
1475  * @param absolute Is the time in nanos a deadline or a duration?
1476  * @param nanos    Nanoseconds to park (absolute=false)
1477  *                 or deadline in milliseconds (absolute=true)
1478  */
1479 void threads_park(bool absolute, int64_t nanos)
1480 {
1481         threadobject    *t;
1482         struct timespec  wakeupTime;
1483
1484         t = thread_get_current();
1485
1486         if (absolute) {
1487                 wakeupTime.tv_nsec = 0;
1488                 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1489         }
1490         else
1491                 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1492
1493         threads_wait_with_timeout(t, &wakeupTime, true);
1494 }
1495
1496 /**
1497  * Unpark the specified thread.
1498  *
1499  * @param t The thread to unpark.
1500  */
1501 void threads_unpark(threadobject *t)
1502 {
1503         t->waitmutex->lock();
1504
1505         t->waitcond->signal();
1506
1507         t->park_permit = true;
1508
1509         t->waitmutex->unlock();
1510 }
1511
1512
1513 /* threads_yield ***************************************************************
1514
1515    Yield to the scheduler.
1516
1517 *******************************************************************************/
1518
1519 void threads_yield(void)
1520 {
1521         sched_yield();
1522 }
1523
1524 #if defined(ENABLE_TLH)
1525
1526 void threads_tlh_add_frame() {
1527         tlh_add_frame(&(THREADOBJECT->tlh));
1528 }
1529
1530 void threads_tlh_remove_frame() {
1531         tlh_remove_frame(&(THREADOBJECT->tlh));
1532 }
1533
1534 #endif
1535
1536
1537 /*
1538  * These are local overrides for various environment variables in Emacs.
1539  * Please do not remove this and leave it at the end of the file, where
1540  * Emacs will automagically detect them.
1541  * ---------------------------------------------------------------------
1542  * Local variables:
1543  * mode: c++
1544  * indent-tabs-mode: t
1545  * c-basic-offset: 4
1546  * tab-width: 4
1547  * End:
1548  * vim:noexpandtab:sw=4:ts=4:
1549  */