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