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