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