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