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