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