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