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