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