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