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