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