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