* src/threads/posix/thread-posix.cpp, src/vm/jit/stacktrace.cpp: Sanitize
[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         t->waitmutex->lock();
1009         t->tid = 0;
1010         t->waitmutex->unlock();
1011
1012         /* Enter the join-mutex before calling thread_free, so
1013            threads_join_all_threads gets the correct number of non-daemon
1014            threads. */
1015
1016         threads_mutex_join_lock();
1017
1018         /* Free the internal thread data-structure. */
1019
1020         thread_free(t);
1021
1022         /* Signal that this thread has finished and leave the mutex. */
1023
1024         cond_join->signal();
1025         threads_mutex_join_unlock();
1026
1027         t->suspendmutex->lock();
1028         t->suspendmutex->unlock();
1029
1030         return true;
1031 }
1032
1033
1034 /**
1035  * Internal helper function which suspends the current thread. This is
1036  * the core method of the suspension mechanism actually blocking the
1037  * execution until the suspension reason is cleared again. Note that
1038  * the current thread needs to hold the suspension mutex while calling
1039  * this function.
1040  */
1041 static void threads_suspend_self()
1042 {
1043         threadobject* thread = THREADOBJECT;
1044
1045         DEBUGTHREADS("suspending", thread);
1046
1047         // Mark thread as suspended.
1048         assert(!thread->suspended);
1049         assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1050         thread->suspended = true;
1051
1052         // Acknowledge the suspension.
1053         thread->suspendcond->broadcast();
1054
1055 #if defined(ENABLE_GC_CACAO)
1056         // If we are stopping the world, we should send a global ack.
1057         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1058                 threads_sem_post(&suspend_ack);
1059 #endif
1060
1061         // Release the suspension mutex and wait till we are resumed.
1062         while (thread->suspend_reason != SUSPEND_REASON_NONE)
1063                 thread->suspendcond->wait(thread->suspendmutex);
1064
1065 #if defined(ENABLE_GC_CACAO)
1066         // XXX This is propably not ok!
1067         // If we are starting the world, we should send a global ack.
1068         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1069                 threads_sem_post(&suspend_ack);
1070 #endif
1071
1072         // Mark thread as not suspended.
1073         assert(thread->suspended);
1074         assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1075         thread->suspended = false;
1076
1077         DEBUGTHREADS("resuming", thread);
1078 }
1079
1080
1081 /**
1082  * Suspend the passed thread. Execution of that thread stops until the thread
1083  * is explicitly resumed again.
1084  *
1085  * @param thread The thread to be suspended.
1086  * @param reason Reason for suspending the given thread.
1087  * @return True of operation was successful, false otherwise.
1088  */
1089 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1090 {
1091         // Sanity check.
1092         assert(reason != SUSPEND_REASON_NONE);
1093
1094         // Guard this with the suspension mutex.
1095         MutexLocker ml(*thread->suspendmutex);
1096
1097         // Check if thread is already suspended.
1098         if (thread->suspended)
1099                 return false;
1100
1101         // Check if thread is in the process of suspending.
1102         if (thread->suspend_reason != SUSPEND_REASON_NONE)
1103                 return false;
1104
1105         // Set the reason for suspending the thread.
1106         thread->suspend_reason = reason;
1107
1108         if (thread == THREADOBJECT) {
1109                 // We already hold the suspension mutex and can suspend ourselves
1110                 // immediately without using signals at all.
1111                 threads_suspend_self();
1112         }
1113         else {
1114                 // Send the suspend signal to the other thread.
1115                 if (!thread->tid)
1116                         return false;
1117                 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1118                         os::abort_errno("threads_suspend_thread: pthread_kill failed");
1119
1120                 // Wait for the thread to acknowledge the suspension.
1121                 while (!thread->suspended)
1122                         thread->suspendcond->wait(thread->suspendmutex);
1123         }
1124
1125         return true;
1126 }
1127
1128
1129 /**
1130  * Resumes execution of the passed thread.
1131  *
1132  * @param thread The thread to be resumed.
1133  * @param reason Reason for suspending the given thread.
1134  * @return True of operation was successful, false otherwise.
1135  */
1136 bool threads_resume_thread(threadobject *thread, int32_t reason)
1137 {
1138         // Sanity check.
1139         assert(thread != THREADOBJECT);
1140         assert(reason != SUSPEND_REASON_NONE);
1141
1142         // Guard this with the suspension mutex.
1143         MutexLocker ml(*thread->suspendmutex);
1144
1145         // Check if thread really is suspended.
1146         if (!thread->suspended)
1147                 return false;
1148
1149         // Threads can only be resumed for the same reason they were suspended.
1150         if (thread->suspend_reason != reason)
1151                 return false;
1152
1153         // Clear the reason for suspending the thread.
1154         thread->suspend_reason = SUSPEND_REASON_NONE;
1155
1156         // Tell everyone that the thread should resume.
1157         thread->suspendcond->broadcast();
1158
1159         return true;
1160 }
1161
1162
1163 /**
1164  * Acknowledges the suspension of the current thread.
1165  */
1166 void threads_suspend_ack()
1167 {
1168         threadobject* thread = THREADOBJECT;
1169
1170         // Guard this with the suspension mutex.
1171         MutexLocker ml(*thread->suspendmutex);
1172
1173         // Suspend ourselves while holding the suspension mutex.
1174         threads_suspend_self();
1175 }
1176
1177
1178 /* threads_join_all_threads ****************************************************
1179
1180    Join all non-daemon threads.
1181
1182 *******************************************************************************/
1183
1184 void threads_join_all_threads(void)
1185 {
1186         threadobject *t;
1187
1188         /* get current thread */
1189
1190         t = THREADOBJECT;
1191
1192         /* This thread is waiting for all non-daemon threads to exit. */
1193
1194         thread_set_state_waiting(t);
1195
1196         /* enter join mutex */
1197
1198         threads_mutex_join_lock();
1199
1200         /* Wait for condition as long as we have non-daemon threads.  We
1201            compare against 1 because the current (main thread) is also a
1202            non-daemon thread. */
1203
1204         while (ThreadList::get_number_of_non_daemon_threads() > 1)
1205                 cond_join->wait(mutex_join);
1206
1207         /* leave join mutex */
1208
1209         threads_mutex_join_unlock();
1210 }
1211
1212
1213 /* threads_timespec_earlier ****************************************************
1214
1215    Return true if timespec tv1 is earlier than timespec tv2.
1216
1217    IN:
1218       tv1..........first timespec
1219           tv2..........second timespec
1220
1221    RETURN VALUE:
1222       true, if the first timespec is earlier
1223
1224 *******************************************************************************/
1225
1226 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1227                                                                                         const struct timespec *tv2)
1228 {
1229         return (tv1->tv_sec < tv2->tv_sec)
1230                                 ||
1231                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1232 }
1233
1234
1235 /* threads_current_time_is_earlier_than ****************************************
1236
1237    Check if the current time is earlier than the given timespec.
1238
1239    IN:
1240       tv...........the timespec to compare against
1241
1242    RETURN VALUE:
1243       true, if the current time is earlier
1244
1245 *******************************************************************************/
1246
1247 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1248 {
1249         struct timeval tvnow;
1250         struct timespec tsnow;
1251
1252         /* get current time */
1253
1254         if (gettimeofday(&tvnow, NULL) != 0)
1255                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1256
1257         /* convert it to a timespec */
1258
1259         tsnow.tv_sec = tvnow.tv_sec;
1260         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1261
1262         /* compare current time with the given timespec */
1263
1264         return threads_timespec_earlier(&tsnow, tv);
1265 }
1266
1267
1268 /* threads_wait_with_timeout ***************************************************
1269
1270    Wait until the given point in time on a monitor until either
1271    we are notified, we are interrupted, or the time is up.
1272
1273    IN:
1274       t............the current thread
1275           wakeupTime...absolute (latest) wakeup time
1276                            If both tv_sec and tv_nsec are zero, this function
1277                                            waits for an unlimited amount of time.
1278
1279 *******************************************************************************/
1280
1281 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1282 {
1283         // Acquire the waitmutex.
1284         t->waitmutex->lock();
1285
1286         /* wait on waitcond */
1287
1288         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1289                 /* with timeout */
1290                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1291                            && threads_current_time_is_earlier_than(wakeupTime))
1292                 {
1293                         if (parking)
1294                                 thread_set_state_timed_parked(t);
1295                         else
1296                                 thread_set_state_timed_waiting(t);
1297
1298                         t->waitcond->timedwait(t->waitmutex, wakeupTime);
1299
1300                         thread_set_state_runnable(t);
1301                 }
1302         }
1303         else {
1304                 /* no timeout */
1305                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1306                         if (parking)
1307                                 thread_set_state_parked(t);
1308                         else
1309                                 thread_set_state_waiting(t);
1310
1311                         t->waitcond->wait(t->waitmutex);
1312
1313                         thread_set_state_runnable(t);
1314                 }
1315         }
1316
1317         if (parking)
1318                 t->park_permit = false;
1319
1320         // Release the waitmutex.
1321         t->waitmutex->unlock();
1322 }
1323
1324
1325 /* threads_wait_with_timeout_relative ******************************************
1326
1327    Wait for the given maximum amount of time on a monitor until either
1328    we are notified, we are interrupted, or the time is up.
1329
1330    IN:
1331       t............the current thread
1332           millis.......milliseconds to wait
1333           nanos........nanoseconds to wait
1334
1335 *******************************************************************************/
1336
1337 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1338                                                                                 s4 nanos)
1339 {
1340         struct timespec wakeupTime;
1341
1342         /* calculate the the (latest) wakeup time */
1343
1344         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1345
1346         /* wait */
1347
1348         threads_wait_with_timeout(thread, &wakeupTime, false);
1349 }
1350
1351
1352 /* threads_calc_absolute_time **************************************************
1353
1354    Calculate the absolute point in time a given number of ms and ns from now.
1355
1356    IN:
1357       millis............milliseconds from now
1358           nanos.............nanoseconds from now
1359
1360    OUT:
1361       *tm...............receives the timespec of the absolute point in time
1362
1363 *******************************************************************************/
1364
1365 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1366 {
1367         // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1368         do {
1369                 if (!millis && !nanos)
1370                         break;
1371                 struct timeval tv;
1372                 gettimeofday(&tv, NULL);
1373                 s8 secs = tv.tv_sec + millis / 1000;
1374                 if (secs > INT32_MAX)   // integer overflow
1375                         break;
1376                 tv.tv_sec = secs;
1377                 millis %= 1000;
1378                 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1379                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1380                 if (tm->tv_sec < tv.tv_sec) // integer overflow
1381                         break;
1382                 tm->tv_nsec = nsec % 1000000000;
1383                 return;
1384         } while (0);
1385         tm->tv_sec = 0;
1386         tm->tv_nsec = 0;
1387 }
1388
1389
1390 /* threads_thread_interrupt ****************************************************
1391
1392    Interrupt the given thread.
1393
1394    The thread gets the "waitcond" signal and 
1395    its interrupted flag is set to true.
1396
1397    IN:
1398       thread............the thread to interrupt
1399
1400 *******************************************************************************/
1401
1402 void threads_thread_interrupt(threadobject *t)
1403 {
1404         /* Signal the thread a "waitcond" and tell it that it has been
1405            interrupted. */
1406
1407         t->waitmutex->lock();
1408
1409         DEBUGTHREADS("interrupted", t);
1410
1411         /* Interrupt blocking system call using a signal. */
1412
1413         if (t->tid)
1414                 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1415
1416         t->waitcond->signal();
1417
1418         t->interrupted = true;
1419
1420         t->waitmutex->unlock();
1421 }
1422
1423
1424 /**
1425  * Sleep the current thread for the specified amount of time.
1426  *
1427  * @param millis Milliseconds to sleep.
1428  * @param nanos  Nanoseconds to sleep.
1429  */
1430 void threads_sleep(int64_t millis, int32_t nanos)
1431 {
1432         threadobject    *t;
1433         struct timespec  wakeupTime;
1434         bool             interrupted;
1435
1436         if (millis < 0) {
1437 /*              exceptions_throw_illegalargumentexception("timeout value is negative"); */
1438                 exceptions_throw_illegalargumentexception();
1439                 return;
1440         }
1441
1442         t = thread_get_current();
1443
1444         if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1445                 /* Clear interrupted flag (Mauve test:
1446                    gnu/testlet/java/lang/Thread/interrupt). */
1447
1448                 thread_set_interrupted(t, false);
1449
1450 /*              exceptions_throw_interruptedexception("sleep interrupted"); */
1451                 exceptions_throw_interruptedexception();
1452                 return;
1453         }
1454
1455         // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1456         // Note: JDK treats a zero length sleep is like Thread.yield(),
1457         // without checking the interrupted status of the thread.  It's
1458         // unclear if this is a bug in the implementation or the spec.
1459         // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1460         if (millis == 0 && nanos == 0) {
1461                 threads_yield();
1462         }
1463         else {
1464                 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1465
1466                 threads_wait_with_timeout(t, &wakeupTime, false);
1467
1468                 interrupted = thread_is_interrupted(t);
1469
1470                 if (interrupted) {
1471                         thread_set_interrupted(t, false);
1472
1473                         // An other exception could have been thrown
1474                         // (e.g. ThreadDeathException).
1475                         if (!exceptions_get_exception())
1476                                 exceptions_throw_interruptedexception();
1477                 }
1478         }
1479 }
1480
1481 /**
1482  * Park the current thread for the specified amount of time or until a
1483  * specified deadline.
1484  *
1485  * @param absolute Is the time in nanos a deadline or a duration?
1486  * @param nanos    Nanoseconds to park (absolute=false)
1487  *                 or deadline in milliseconds (absolute=true)
1488  */
1489 void threads_park(bool absolute, int64_t nanos)
1490 {
1491         threadobject    *t;
1492         struct timespec  wakeupTime;
1493
1494         t = thread_get_current();
1495
1496         if (absolute) {
1497                 wakeupTime.tv_nsec = 0;
1498                 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1499         }
1500         else
1501                 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1502
1503         threads_wait_with_timeout(t, &wakeupTime, true);
1504 }
1505
1506 /**
1507  * Unpark the specified thread.
1508  *
1509  * @param t The thread to unpark.
1510  */
1511 void threads_unpark(threadobject *t)
1512 {
1513         t->waitmutex->lock();
1514
1515         t->waitcond->signal();
1516
1517         t->park_permit = true;
1518
1519         t->waitmutex->unlock();
1520 }
1521
1522
1523 /* threads_yield ***************************************************************
1524
1525    Yield to the scheduler.
1526
1527 *******************************************************************************/
1528
1529 void threads_yield(void)
1530 {
1531         sched_yield();
1532 }
1533
1534 #if defined(ENABLE_TLH)
1535
1536 void threads_tlh_add_frame() {
1537         tlh_add_frame(&(THREADOBJECT->tlh));
1538 }
1539
1540 void threads_tlh_remove_frame() {
1541         tlh_remove_frame(&(THREADOBJECT->tlh));
1542 }
1543
1544 #endif
1545
1546
1547 /*
1548  * These are local overrides for various environment variables in Emacs.
1549  * Please do not remove this and leave it at the end of the file, where
1550  * Emacs will automagically detect them.
1551  * ---------------------------------------------------------------------
1552  * Local variables:
1553  * mode: c++
1554  * indent-tabs-mode: t
1555  * c-basic-offset: 4
1556  * tab-width: 4
1557  * End:
1558  * vim:noexpandtab:sw=4:ts=4:
1559  */