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