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