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