* src/threads/posix/thread-posix.cpp: Implemented thread suspension mechanism.
[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 /**
1105  * Internal helper function which suspends the current thread. This is
1106  * the core method of the suspension mechanism actually blocking the
1107  * execution until the suspension reason is cleared again. Note that
1108  * the current thread needs to hold the suspension mutex while calling
1109  * this function.
1110  */
1111 static void threads_suspend_self()
1112 {
1113         threadobject* thread = THREADOBJECT;
1114
1115         DEBUGTHREADS("suspending", thread);
1116
1117         // Mark thread as suspended.
1118         assert(!thread->suspended);
1119         assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1120         thread->suspended = true;
1121
1122         // Acknowledge the suspension.
1123         thread->suspendcond->broadcast();
1124
1125 #if defined(ENABLE_GC_CACAO)
1126         // If we are stopping the world, we should send a global ack.
1127         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1128                 threads_sem_post(&suspend_ack);
1129 #endif
1130
1131         // Release the suspension mutex and wait till we are resumed.
1132         thread->suspendcond->wait(thread->suspendmutex);
1133
1134 #if defined(ENABLE_GC_CACAO)
1135         // XXX This is propably not ok!
1136         // If we are starting the world, we should send a global ack.
1137         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1138                 threads_sem_post(&suspend_ack);
1139 #endif
1140
1141         // Mark thread as not suspended.
1142         assert(thread->suspended);
1143         assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1144         thread->suspended = false;
1145
1146         DEBUGTHREADS("resuming", thread);
1147 }
1148
1149
1150 /**
1151  * Suspend the passed thread. Execution of that thread stops until the thread
1152  * is explicitly resumend again.
1153  *
1154  * @param thread The thread to be suspended.
1155  * @param reason Reason for suspending the given thread.
1156  * @return True of operation was successful, false otherwise.
1157  */
1158 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1159 {
1160         // Sanity check.
1161         assert(reason != SUSPEND_REASON_NONE);
1162
1163         // Guard this with the suspension mutex.
1164         MutexLocker ml(*thread->suspendmutex);
1165
1166         // Check if thread is already suspended.
1167         if (thread->suspended)
1168                 return false;
1169
1170         // Check if thread is in the process of suspending.
1171         if (thread->suspend_reason != SUSPEND_REASON_NONE)
1172                 return false;
1173
1174         // Set the reason for suspending the thread.
1175         thread->suspend_reason = reason;
1176
1177         if (thread == THREADOBJECT) {
1178                 // We already hold the suspension mutex and can suspend ourselves
1179                 // immediately without using signals at all.
1180                 threads_suspend_self();
1181         }
1182         else {
1183                 // Send the suspend signal to the other thread.
1184                 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1185                         os::abort_errno("threads_suspend_thread: pthread_kill failed");
1186
1187                 // Wait for the thread to acknowledge the suspension.
1188                 // XXX A possible optimization would be to not wait here, but you
1189                 //     better think this through twice before trying it!
1190                 thread->suspendcond->wait(thread->suspendmutex);
1191         }
1192
1193         return true;
1194 }
1195
1196
1197 /**
1198  * Resumes execution of the passed thread.
1199  *
1200  * @param thread The thread to be resumed.
1201  * @param reason Reason for suspending the given thread.
1202  * @return True of operation was successful, false otherwise.
1203  */
1204 bool threads_resume_thread(threadobject *thread, int32_t reason)
1205 {
1206         // Sanity check.
1207         assert(thread != THREADOBJECT);
1208         assert(reason != SUSPEND_REASON_NONE);
1209
1210         // Guard this with the suspension mutex.
1211         MutexLocker ml(*thread->suspendmutex);
1212
1213         // Check if thread really is suspended.
1214         if (!thread->suspended)
1215                 return false;
1216
1217         // Threads can only be resumed for the same reason they were suspended.
1218         if (thread->suspend_reason != reason)
1219                 return false;
1220
1221         // Clear the reason for suspending the thread.
1222         thread->suspend_reason = SUSPEND_REASON_NONE;
1223
1224         // Tell everyone that the thread should resume.
1225         thread->suspendcond->broadcast();
1226
1227         return true;
1228 }
1229
1230
1231 /**
1232  * Acknowledges the suspension of the current thread.
1233  */
1234 void threads_suspend_ack()
1235 {
1236         threadobject* thread = THREADOBJECT;
1237
1238         // Guard this with the suspension mutex.
1239         MutexLocker ml(*thread->suspendmutex);
1240
1241         // Suspend ourselves while holding the suspension mutex.
1242         threads_suspend_self();
1243 }
1244
1245
1246 /* threads_join_all_threads ****************************************************
1247
1248    Join all non-daemon threads.
1249
1250 *******************************************************************************/
1251
1252 void threads_join_all_threads(void)
1253 {
1254         threadobject *t;
1255
1256         /* get current thread */
1257
1258         t = THREADOBJECT;
1259
1260         /* This thread is waiting for all non-daemon threads to exit. */
1261
1262         thread_set_state_waiting(t);
1263
1264         /* enter join mutex */
1265
1266         threads_mutex_join_lock();
1267
1268         /* Wait for condition as long as we have non-daemon threads.  We
1269            compare against 1 because the current (main thread) is also a
1270            non-daemon thread. */
1271
1272         while (ThreadList::get_number_of_non_daemon_threads() > 1)
1273                 cond_join->wait(mutex_join);
1274
1275         /* leave join mutex */
1276
1277         threads_mutex_join_unlock();
1278 }
1279
1280
1281 /* threads_timespec_earlier ****************************************************
1282
1283    Return true if timespec tv1 is earlier than timespec tv2.
1284
1285    IN:
1286       tv1..........first timespec
1287           tv2..........second timespec
1288
1289    RETURN VALUE:
1290       true, if the first timespec is earlier
1291
1292 *******************************************************************************/
1293
1294 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1295                                                                                         const struct timespec *tv2)
1296 {
1297         return (tv1->tv_sec < tv2->tv_sec)
1298                                 ||
1299                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1300 }
1301
1302
1303 /* threads_current_time_is_earlier_than ****************************************
1304
1305    Check if the current time is earlier than the given timespec.
1306
1307    IN:
1308       tv...........the timespec to compare against
1309
1310    RETURN VALUE:
1311       true, if the current time is earlier
1312
1313 *******************************************************************************/
1314
1315 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1316 {
1317         struct timeval tvnow;
1318         struct timespec tsnow;
1319
1320         /* get current time */
1321
1322         if (gettimeofday(&tvnow, NULL) != 0)
1323                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1324
1325         /* convert it to a timespec */
1326
1327         tsnow.tv_sec = tvnow.tv_sec;
1328         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1329
1330         /* compare current time with the given timespec */
1331
1332         return threads_timespec_earlier(&tsnow, tv);
1333 }
1334
1335
1336 /* threads_wait_with_timeout ***************************************************
1337
1338    Wait until the given point in time on a monitor until either
1339    we are notified, we are interrupted, or the time is up.
1340
1341    IN:
1342       t............the current thread
1343           wakeupTime...absolute (latest) wakeup time
1344                            If both tv_sec and tv_nsec are zero, this function
1345                                            waits for an unlimited amount of time.
1346
1347 *******************************************************************************/
1348
1349 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1350 {
1351         // Acquire the waitmutex.
1352         t->waitmutex->lock();
1353
1354         /* wait on waitcond */
1355
1356         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1357                 /* with timeout */
1358                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1359                            && threads_current_time_is_earlier_than(wakeupTime))
1360                 {
1361                         if (parking)
1362                                 thread_set_state_timed_parked(t);
1363                         else
1364                                 thread_set_state_timed_waiting(t);
1365
1366                         t->waitcond->timedwait(t->waitmutex, wakeupTime);
1367
1368                         thread_set_state_runnable(t);
1369                 }
1370         }
1371         else {
1372                 /* no timeout */
1373                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1374                         if (parking)
1375                                 thread_set_state_parked(t);
1376                         else
1377                                 thread_set_state_waiting(t);
1378
1379                         t->waitcond->wait(t->waitmutex);
1380
1381                         thread_set_state_runnable(t);
1382                 }
1383         }
1384
1385         if (parking)
1386                 t->park_permit = false;
1387
1388         // Release the waitmutex.
1389         t->waitmutex->unlock();
1390 }
1391
1392
1393 /* threads_wait_with_timeout_relative ******************************************
1394
1395    Wait for the given maximum amount of time on a monitor until either
1396    we are notified, we are interrupted, or the time is up.
1397
1398    IN:
1399       t............the current thread
1400           millis.......milliseconds to wait
1401           nanos........nanoseconds to wait
1402
1403 *******************************************************************************/
1404
1405 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1406                                                                                 s4 nanos)
1407 {
1408         struct timespec wakeupTime;
1409
1410         /* calculate the the (latest) wakeup time */
1411
1412         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1413
1414         /* wait */
1415
1416         threads_wait_with_timeout(thread, &wakeupTime, false);
1417 }
1418
1419
1420 /* threads_calc_absolute_time **************************************************
1421
1422    Calculate the absolute point in time a given number of ms and ns from now.
1423
1424    IN:
1425       millis............milliseconds from now
1426           nanos.............nanoseconds from now
1427
1428    OUT:
1429       *tm...............receives the timespec of the absolute point in time
1430
1431 *******************************************************************************/
1432
1433 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1434 {
1435         // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1436         do {
1437                 if (!millis && !nanos)
1438                         break;
1439                 struct timeval tv;
1440                 gettimeofday(&tv, NULL);
1441                 s8 secs = tv.tv_sec + millis / 1000;
1442                 if (secs > INT32_MAX)   // integer overflow
1443                         break;
1444                 tv.tv_sec = secs;
1445                 millis %= 1000;
1446                 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1447                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1448                 if (tm->tv_sec < tv.tv_sec) // integer overflow
1449                         break;
1450                 tm->tv_nsec = nsec % 1000000000;
1451                 return;
1452         } while (0);
1453         tm->tv_sec = 0;
1454         tm->tv_nsec = 0;
1455 }
1456
1457
1458 /* threads_thread_interrupt ****************************************************
1459
1460    Interrupt the given thread.
1461
1462    The thread gets the "waitcond" signal and 
1463    its interrupted flag is set to true.
1464
1465    IN:
1466       thread............the thread to interrupt
1467
1468 *******************************************************************************/
1469
1470 void threads_thread_interrupt(threadobject *t)
1471 {
1472         /* Signal the thread a "waitcond" and tell it that it has been
1473            interrupted. */
1474
1475         t->waitmutex->lock();
1476
1477         DEBUGTHREADS("interrupted", t);
1478
1479         /* Interrupt blocking system call using a signal. */
1480
1481         pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1482
1483         t->waitcond->signal();
1484
1485         t->interrupted = true;
1486
1487         t->waitmutex->unlock();
1488 }
1489
1490
1491 /**
1492  * Sleep the current thread for the specified amount of time.
1493  *
1494  * @param millis Milliseconds to sleep.
1495  * @param nanos  Nanoseconds to sleep.
1496  */
1497 void threads_sleep(int64_t millis, int32_t nanos)
1498 {
1499         threadobject    *t;
1500         struct timespec  wakeupTime;
1501         bool             interrupted;
1502
1503         if (millis < 0) {
1504 /*              exceptions_throw_illegalargumentexception("timeout value is negative"); */
1505                 exceptions_throw_illegalargumentexception();
1506                 return;
1507         }
1508
1509         t = thread_get_current();
1510
1511         if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1512                 /* Clear interrupted flag (Mauve test:
1513                    gnu/testlet/java/lang/Thread/interrupt). */
1514
1515                 thread_set_interrupted(t, false);
1516
1517 /*              exceptions_throw_interruptedexception("sleep interrupted"); */
1518                 exceptions_throw_interruptedexception();
1519                 return;
1520         }
1521
1522         // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1523         // Note: JDK treats a zero length sleep is like Thread.yield(),
1524         // without checking the interrupted status of the thread.  It's
1525         // unclear if this is a bug in the implementation or the spec.
1526         // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1527         if (millis == 0 && nanos == 0) {
1528                 threads_yield();
1529         }
1530         else {
1531                 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1532
1533                 threads_wait_with_timeout(t, &wakeupTime, false);
1534
1535                 interrupted = thread_is_interrupted(t);
1536
1537                 if (interrupted) {
1538                         thread_set_interrupted(t, false);
1539
1540                         // An other exception could have been thrown
1541                         // (e.g. ThreadDeathException).
1542                         if (!exceptions_get_exception())
1543                                 exceptions_throw_interruptedexception();
1544                 }
1545         }
1546 }
1547
1548 /**
1549  * Park the current thread for the specified amount of time or until a
1550  * specified deadline.
1551  *
1552  * @param absolute Is the time in nanos a deadline or a duration?
1553  * @param nanos    Nanoseconds to park (absolute=false)
1554  *                 or deadline in milliseconds (absolute=true)
1555  */
1556 void threads_park(bool absolute, int64_t nanos)
1557 {
1558         threadobject    *t;
1559         struct timespec  wakeupTime;
1560
1561         t = thread_get_current();
1562
1563         if (absolute) {
1564                 wakeupTime.tv_nsec = 0;
1565                 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1566         }
1567         else
1568                 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1569
1570         threads_wait_with_timeout(t, &wakeupTime, true);
1571 }
1572
1573 /**
1574  * Unpark the specified thread.
1575  *
1576  * @param t The thread to unpark.
1577  */
1578 void threads_unpark(threadobject *t)
1579 {
1580         t->waitmutex->lock();
1581
1582         t->waitcond->signal();
1583
1584         t->park_permit = true;
1585
1586         t->waitmutex->unlock();
1587 }
1588
1589
1590 /* threads_yield ***************************************************************
1591
1592    Yield to the scheduler.
1593
1594 *******************************************************************************/
1595
1596 void threads_yield(void)
1597 {
1598         sched_yield();
1599 }
1600
1601 #if defined(ENABLE_TLH)
1602
1603 void threads_tlh_add_frame() {
1604         tlh_add_frame(&(THREADOBJECT->tlh));
1605 }
1606
1607 void threads_tlh_remove_frame() {
1608         tlh_remove_frame(&(THREADOBJECT->tlh));
1609 }
1610
1611 #endif
1612
1613
1614 /*
1615  * These are local overrides for various environment variables in Emacs.
1616  * Please do not remove this and leave it at the end of the file, where
1617  * Emacs will automagically detect them.
1618  * ---------------------------------------------------------------------
1619  * Local variables:
1620  * mode: c++
1621  * indent-tabs-mode: t
1622  * c-basic-offset: 4
1623  * tab-width: 4
1624  * End:
1625  * vim:noexpandtab:sw=4:ts=4:
1626  */