* Commited 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, NULL)
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       *thread;
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         thread   = 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         thread->mach_thread = mach_thread_self();
1008 #endif
1009
1010         /* Store the internal thread data-structure in the TSD. */
1011
1012         thread_set_current(thread);
1013
1014         /* get the java.lang.Thread object for this thread */
1015
1016         object = (java_lang_Thread *) thread_get_object(thread);
1017
1018         /* set our priority */
1019
1020         threads_set_thread_priority(thread->tid, LLNI_field_direct(object, priority));
1021
1022         /* thread is completely initialized */
1023
1024         threads_thread_state_runnable(thread);
1025
1026         /* tell threads_startup_thread that we registered ourselves */
1027         /* CAUTION: *startup becomes invalid with this!             */
1028
1029         startup = NULL;
1030         threads_sem_post(psem);
1031
1032 #if defined(ENABLE_INTRP)
1033         /* set interpreter stack */
1034
1035         if (opt_intrp)
1036                 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1037 #endif
1038
1039 #if defined(ENABLE_JVMTI)
1040         /* fire thread start event */
1041
1042         if (jvmti) 
1043                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1044 #endif
1045
1046         DEBUGTHREADS("starting", thread);
1047
1048         /* find and run the Thread.run()V method if no other function was passed */
1049
1050         if (function == NULL) {
1051 #if defined(WITH_CLASSPATH_GNU)
1052                 /* We need to start the run method of
1053                    java.lang.VMThread. Since this is a final class, we can use
1054                    the class object directly. */
1055
1056                 c = class_java_lang_VMThread;
1057 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1058                 LLNI_class_get(object, c);
1059 #else
1060 # error unknown classpath configuration
1061 #endif
1062
1063                 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1064
1065                 if (m == NULL)
1066                         vm_abort("threads_startup_thread: run() method not found in class");
1067
1068                 /* set ThreadMXBean variables */
1069
1070                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1071                 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1072
1073                 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1074                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1075                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1076                                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1077
1078 #if defined(WITH_CLASSPATH_GNU)
1079                 /* we need to start the run method of java.lang.VMThread */
1080
1081                 LLNI_field_get_ref(object, vmThread, vmt);
1082                 o   = (java_handle_t *) vmt;
1083
1084 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1085                 o   = (java_handle_t *) object;
1086 #else
1087 # error unknown classpath configuration
1088 #endif
1089
1090                 /* run the thread */
1091
1092                 (void) vm_call_method(m, o);
1093         }
1094         else {
1095                 /* set ThreadMXBean variables */
1096
1097                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1098                 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1099
1100                 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1101                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1102                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1103                                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1104
1105                 /* call passed function, e.g. finalizer_thread */
1106
1107                 (function)();
1108         }
1109
1110         DEBUGTHREADS("stopping", thread);
1111
1112 #if defined(ENABLE_JVMTI)
1113         /* fire thread end event */
1114
1115         if (jvmti)
1116                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1117 #endif
1118
1119         /* We ignore the return value. */
1120
1121         (void) threads_detach_thread(thread);
1122
1123         /* set ThreadMXBean variables */
1124
1125         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1126
1127         return NULL;
1128 }
1129
1130
1131 /* threads_impl_thread_start ***************************************************
1132
1133    Start a thread in the JVM.  Both (vm internal and java) thread
1134    objects exist.
1135
1136    IN:
1137       thread....the thread object
1138           f.........function to run in the new thread. NULL means that the
1139                     "run" method of the object `t` should be called
1140
1141 ******************************************************************************/
1142
1143 void threads_impl_thread_start(threadobject *thread, functionptr f)
1144 {
1145         sem_t          sem;
1146         sem_t          sem_first;
1147         pthread_attr_t attr;
1148         startupinfo    startup;
1149         int            result;
1150
1151         /* fill startupinfo structure passed by pthread_create to
1152          * threads_startup_thread */
1153
1154         startup.thread     = thread;
1155         startup.function   = f;              /* maybe we don't call Thread.run()V */
1156         startup.psem       = &sem;
1157         startup.psem_first = &sem_first;
1158
1159         threads_sem_init(&sem, 0, 0);
1160         threads_sem_init(&sem_first, 0, 0);
1161
1162         /* Initialize thread attributes. */
1163
1164         result = pthread_attr_init(&attr);
1165
1166         if (result != 0)
1167                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1168
1169     result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1170
1171     if (result != 0)
1172                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1173
1174         /* initialize thread stacksize */
1175
1176         result = pthread_attr_setstacksize(&attr, opt_stacksize);
1177
1178         if (result != 0)
1179                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1180
1181         /* create the thread */
1182
1183         result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1184
1185         if (result != 0)
1186                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1187
1188         /* destroy the thread attributes */
1189
1190         result = pthread_attr_destroy(&attr);
1191
1192         if (result != 0)
1193                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1194
1195         /* signal that pthread_create has returned, so thread->tid is valid */
1196
1197         threads_sem_post(&sem_first);
1198
1199         /* wait here until the thread has entered itself into the thread list */
1200
1201         threads_sem_wait(&sem);
1202
1203         /* cleanup */
1204
1205         sem_destroy(&sem);
1206         sem_destroy(&sem_first);
1207 }
1208
1209
1210 /* threads_set_thread_priority *************************************************
1211
1212    Set the priority of the given thread.
1213
1214    IN:
1215       tid..........thread id
1216           priority.....priority to set
1217
1218 ******************************************************************************/
1219
1220 void threads_set_thread_priority(pthread_t tid, int priority)
1221 {
1222         struct sched_param schedp;
1223         int policy;
1224
1225         pthread_getschedparam(tid, &policy, &schedp);
1226         schedp.sched_priority = priority;
1227         pthread_setschedparam(tid, policy, &schedp);
1228 }
1229
1230
1231 /* threads_detach_thread *******************************************************
1232
1233    Detaches the passed thread from the VM.  Used in JNI.
1234
1235 *******************************************************************************/
1236
1237 bool threads_detach_thread(threadobject *t)
1238 {
1239         bool                   result;
1240         java_lang_Thread      *object;
1241         java_handle_t         *o;
1242 #if defined(ENABLE_JAVASE)
1243         java_lang_ThreadGroup *group;
1244         java_handle_t         *e;
1245         void                  *handler;
1246         classinfo             *c;
1247         methodinfo            *m;
1248 #endif
1249
1250     /* If the given thread has already been detached, this operation
1251            is a no-op. */
1252
1253         result = thread_is_attached(t);
1254
1255         if (result == false)
1256                 return true;
1257
1258         DEBUGTHREADS("detaching", t);
1259
1260         object = (java_lang_Thread *) thread_get_object(t);
1261
1262 #if defined(ENABLE_JAVASE)
1263         LLNI_field_get_ref(object, group, group);
1264
1265     /* If there's an uncaught exception, call uncaughtException on the
1266        thread's exception handler, or the thread's group if this is
1267        unset. */
1268
1269         e = exceptions_get_and_clear_exception();
1270
1271     if (e != NULL) {
1272                 /* We use the type void* for handler here, as it's not trivial
1273                    to build the java_lang_Thread_UncaughtExceptionHandler
1274                    header file with cacaoh. */
1275
1276 # if defined(WITH_CLASSPATH_GNU)
1277                 LLNI_field_get_ref(object, exceptionHandler, handler);
1278 # elif defined(WITH_CLASSPATH_SUN)
1279                 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1280 # endif
1281
1282                 if (handler != NULL) {
1283                         LLNI_class_get(handler, c);
1284                         o = (java_handle_t *) handler;
1285                 }
1286                 else {
1287                         LLNI_class_get(group, c);
1288                         o = (java_handle_t *) group;
1289                 }
1290
1291                 m = class_resolveclassmethod(c,
1292                                                                          utf_uncaughtException,
1293                                                                          utf_java_lang_Thread_java_lang_Throwable__V,
1294                                                                          NULL,
1295                                                                          true);
1296
1297                 if (m == NULL)
1298                         return false;
1299
1300                 (void) vm_call_method(m, o, object, e);
1301
1302                 if (exceptions_get_exception())
1303                         return false;
1304     }
1305
1306         /* XXX TWISTI: should all threads be in a ThreadGroup? */
1307
1308         /* Remove thread from the thread group. */
1309
1310         if (group != NULL) {
1311                 LLNI_class_get(group, c);
1312
1313 # if defined(WITH_CLASSPATH_GNU)
1314                 m = class_resolveclassmethod(c,
1315                                                                          utf_removeThread,
1316                                                                          utf_java_lang_Thread__V,
1317                                                                          class_java_lang_ThreadGroup,
1318                                                                          true);
1319 # elif defined(WITH_CLASSPATH_SUN)
1320                 m = class_resolveclassmethod(c,
1321                                                                          utf_remove,
1322                                                                          utf_java_lang_Thread__V,
1323                                                                          class_java_lang_ThreadGroup,
1324                                                                          true);
1325 # else
1326 #  error unknown classpath configuration
1327 # endif
1328
1329                 if (m == NULL)
1330                         return false;
1331
1332                 o = (java_handle_t *) group;
1333
1334                 (void) vm_call_method(m, o, object);
1335
1336                 if (exceptions_get_exception())
1337                         return false;
1338         }
1339 #endif
1340
1341         /* Thread has terminated. */
1342
1343         threads_thread_state_terminated(t);
1344
1345         /* Notify all threads waiting on this thread.  These are joining
1346            this thread. */
1347
1348         o = (java_handle_t *) object;
1349
1350         /* XXX Care about exceptions? */
1351         (void) lock_monitor_enter(o);
1352         
1353         lock_notify_all_object(o);
1354
1355         /* XXX Care about exceptions? */
1356         (void) lock_monitor_exit(o);
1357
1358         /* Enter the join-mutex before calling thread_free, so
1359            threads_join_all_threads gets the correct number of non-daemon
1360            threads. */
1361
1362         threads_mutex_join_lock();
1363
1364         /* Free the internal thread data-structure. */
1365
1366         thread_free(t);
1367
1368         /* Signal that this thread has finished and leave the mutex. */
1369
1370         pthread_cond_signal(&cond_join);
1371         threads_mutex_join_unlock();
1372
1373         return true;
1374 }
1375
1376
1377 /* threads_suspend_thread ******************************************************
1378
1379    Suspend the passed thread. Execution stops until the thread
1380    is explicitly resumend again.
1381
1382    IN:
1383      reason.....Reason for suspending this thread.
1384
1385 *******************************************************************************/
1386
1387 bool threads_suspend_thread(threadobject *thread, s4 reason)
1388 {
1389         /* acquire the suspendmutex */
1390         mutex_lock(&(thread->suspendmutex));
1391
1392         if (thread->suspended) {
1393                 mutex_unlock(&(thread->suspendmutex));
1394                 return false;
1395         }
1396
1397         /* set the reason for the suspension */
1398         thread->suspend_reason = reason;
1399
1400         /* send the suspend signal to the thread */
1401         assert(thread != THREADOBJECT);
1402         if (pthread_kill(thread->tid, SIGUSR1) != 0)
1403                 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1404                                  strerror(errno));
1405
1406         /* REMEMBER: do not release the suspendmutex, this is done
1407            by the thread itself in threads_suspend_ack().  */
1408
1409         return true;
1410 }
1411
1412
1413 /* threads_suspend_ack *********************************************************
1414
1415    Acknowledges the suspension of the current thread.
1416
1417    IN:
1418      pc.....The PC where the thread suspended its execution.
1419      sp.....The SP before the thread suspended its execution.
1420
1421 *******************************************************************************/
1422
1423 void threads_suspend_ack(u1* pc, u1* sp)
1424 {
1425         threadobject *thread;
1426
1427         thread = THREADOBJECT;
1428
1429         assert(thread->suspend_reason != 0);
1430
1431         /* TODO: remember dump memory size */
1432
1433 #if defined(ENABLE_GC_CACAO)
1434         /* inform the GC about the suspension */
1435         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1436
1437                 /* check if the GC wants to leave the thread running */
1438                 if (!gc_suspend(thread, pc, sp)) {
1439
1440                         /* REMEMBER: we do not unlock the suspendmutex because the thread
1441                            will suspend itself again at a later time */
1442                         return;
1443
1444                 }
1445         }
1446 #endif
1447
1448         /* mark this thread as suspended and remember the PC */
1449         thread->pc        = pc;
1450         thread->suspended = true;
1451
1452         /* if we are stopping the world, we should send a global ack */
1453         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1454                 threads_sem_post(&suspend_ack);
1455         }
1456
1457         DEBUGTHREADS("suspending", thread);
1458
1459         /* release the suspension mutex and wait till we are resumed */
1460         pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1461
1462         DEBUGTHREADS("resuming", thread);
1463
1464         /* if we are stopping the world, we should send a global ack */
1465         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1466                 threads_sem_post(&suspend_ack);
1467         }
1468
1469         /* TODO: free dump memory */
1470
1471         /* release the suspendmutex */
1472         mutex_unlock(&(thread->suspendmutex));
1473 }
1474
1475
1476 /* threads_resume_thread *******************************************************
1477
1478    Resumes the execution of the passed thread.
1479
1480 *******************************************************************************/
1481
1482 bool threads_resume_thread(threadobject *thread)
1483 {
1484         /* acquire the suspendmutex */
1485         mutex_lock(&(thread->suspendmutex));
1486
1487         if (!thread->suspended) {
1488                 mutex_unlock(&(thread->suspendmutex));
1489                 return false;
1490         }
1491
1492         thread->suspended = false;
1493
1494         /* tell everyone that the thread should resume */
1495         assert(thread != THREADOBJECT);
1496         pthread_cond_broadcast(&(thread->suspendcond));
1497
1498         /* release the suspendmutex */
1499         mutex_unlock(&(thread->suspendmutex));
1500
1501         return true;
1502 }
1503
1504
1505 /* threads_join_all_threads ****************************************************
1506
1507    Join all non-daemon threads.
1508
1509 *******************************************************************************/
1510
1511 void threads_join_all_threads(void)
1512 {
1513         threadobject *t;
1514
1515         /* get current thread */
1516
1517         t = THREADOBJECT;
1518
1519         /* this thread is waiting for all non-daemon threads to exit */
1520
1521         threads_thread_state_waiting(t);
1522
1523         /* enter join mutex */
1524
1525         threads_mutex_join_lock();
1526
1527         /* Wait for condition as long as we have non-daemon threads.  We
1528            compare against 1 because the current (main thread) is also a
1529            non-daemon thread. */
1530
1531         while (threadlist_get_non_daemons() > 1)
1532                 pthread_cond_wait(&cond_join, &mutex_join);
1533
1534         /* leave join mutex */
1535
1536         threads_mutex_join_unlock();
1537 }
1538
1539
1540 /* threads_timespec_earlier ****************************************************
1541
1542    Return true if timespec tv1 is earlier than timespec tv2.
1543
1544    IN:
1545       tv1..........first timespec
1546           tv2..........second timespec
1547
1548    RETURN VALUE:
1549       true, if the first timespec is earlier
1550
1551 *******************************************************************************/
1552
1553 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1554                                                                                         const struct timespec *tv2)
1555 {
1556         return (tv1->tv_sec < tv2->tv_sec)
1557                                 ||
1558                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1559 }
1560
1561
1562 /* threads_current_time_is_earlier_than ****************************************
1563
1564    Check if the current time is earlier than the given timespec.
1565
1566    IN:
1567       tv...........the timespec to compare against
1568
1569    RETURN VALUE:
1570       true, if the current time is earlier
1571
1572 *******************************************************************************/
1573
1574 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1575 {
1576         struct timeval tvnow;
1577         struct timespec tsnow;
1578
1579         /* get current time */
1580
1581         if (gettimeofday(&tvnow, NULL) != 0)
1582                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1583
1584         /* convert it to a timespec */
1585
1586         tsnow.tv_sec = tvnow.tv_sec;
1587         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1588
1589         /* compare current time with the given timespec */
1590
1591         return threads_timespec_earlier(&tsnow, tv);
1592 }
1593
1594
1595 /* threads_wait_with_timeout ***************************************************
1596
1597    Wait until the given point in time on a monitor until either
1598    we are notified, we are interrupted, or the time is up.
1599
1600    IN:
1601       t............the current thread
1602           wakeupTime...absolute (latest) wakeup time
1603                            If both tv_sec and tv_nsec are zero, this function
1604                                            waits for an unlimited amount of time.
1605
1606 *******************************************************************************/
1607
1608 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1609 {
1610         /* acquire the waitmutex */
1611
1612         mutex_lock(&t->waitmutex);
1613
1614         /* mark us as sleeping */
1615
1616         t->sleeping = true;
1617
1618         /* wait on waitcond */
1619
1620         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1621                 /* with timeout */
1622                 while (!t->interrupted && !t->signaled
1623                            && threads_current_time_is_earlier_than(wakeupTime))
1624                 {
1625                         threads_thread_state_timed_waiting(t);
1626
1627                         pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1628                                                                    wakeupTime);
1629
1630                         threads_thread_state_runnable(t);
1631                 }
1632         }
1633         else {
1634                 /* no timeout */
1635                 while (!t->interrupted && !t->signaled) {
1636                         threads_thread_state_waiting(t);
1637
1638                         pthread_cond_wait(&t->waitcond, &t->waitmutex);
1639
1640                         threads_thread_state_runnable(t);
1641                 }
1642         }
1643
1644         t->sleeping    = false;
1645
1646         /* release the waitmutex */
1647
1648         mutex_unlock(&t->waitmutex);
1649 }
1650
1651
1652 /* threads_wait_with_timeout_relative ******************************************
1653
1654    Wait for the given maximum amount of time on a monitor until either
1655    we are notified, we are interrupted, or the time is up.
1656
1657    IN:
1658       t............the current thread
1659           millis.......milliseconds to wait
1660           nanos........nanoseconds to wait
1661
1662 *******************************************************************************/
1663
1664 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1665                                                                                 s4 nanos)
1666 {
1667         struct timespec wakeupTime;
1668
1669         /* calculate the the (latest) wakeup time */
1670
1671         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1672
1673         /* wait */
1674
1675         threads_wait_with_timeout(thread, &wakeupTime);
1676 }
1677
1678
1679 /* threads_calc_absolute_time **************************************************
1680
1681    Calculate the absolute point in time a given number of ms and ns from now.
1682
1683    IN:
1684       millis............milliseconds from now
1685           nanos.............nanoseconds from now
1686
1687    OUT:
1688       *tm...............receives the timespec of the absolute point in time
1689
1690 *******************************************************************************/
1691
1692 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1693 {
1694         if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1695                 struct timeval tv;
1696                 long nsec;
1697                 gettimeofday(&tv, NULL);
1698                 tv.tv_sec += millis / 1000;
1699                 millis %= 1000;
1700                 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1701                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1702                 tm->tv_nsec = nsec % 1000000000;
1703         }
1704         else {
1705                 tm->tv_sec = 0;
1706                 tm->tv_nsec = 0;
1707         }
1708 }
1709
1710
1711 /* threads_thread_interrupt ****************************************************
1712
1713    Interrupt the given thread.
1714
1715    The thread gets the "waitcond" signal and 
1716    its interrupted flag is set to true.
1717
1718    IN:
1719       thread............the thread to interrupt
1720
1721 *******************************************************************************/
1722
1723 void threads_thread_interrupt(threadobject *thread)
1724 {
1725         /* Signal the thread a "waitcond" and tell it that it has been
1726            interrupted. */
1727
1728         mutex_lock(&thread->waitmutex);
1729
1730         DEBUGTHREADS("interrupted", thread);
1731
1732         /* Interrupt blocking system call using a signal. */
1733
1734         pthread_kill(thread->tid, SIGHUP);
1735
1736         if (thread->sleeping)
1737                 pthread_cond_signal(&thread->waitcond);
1738
1739         thread->interrupted = true;
1740
1741         mutex_unlock(&thread->waitmutex);
1742 }
1743
1744
1745 /* threads_sleep ***************************************************************
1746
1747    Sleep the current thread for the specified amount of time.
1748
1749 *******************************************************************************/
1750
1751 void threads_sleep(s8 millis, s4 nanos)
1752 {
1753         threadobject    *t;
1754         struct timespec  wakeupTime;
1755         bool             interrupted;
1756
1757         t = THREADOBJECT;
1758
1759         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1760
1761         threads_wait_with_timeout(t, &wakeupTime);
1762
1763         interrupted = thread_is_interrupted(t);
1764
1765         thread_set_interrupted(t, false);
1766
1767         if (interrupted)
1768                 exceptions_throw_interruptedexception();
1769 }
1770
1771
1772 /* threads_yield ***************************************************************
1773
1774    Yield to the scheduler.
1775
1776 *******************************************************************************/
1777
1778 void threads_yield(void)
1779 {
1780         sched_yield();
1781 }
1782
1783
1784 /*
1785  * These are local overrides for various environment variables in Emacs.
1786  * Please do not remove this and leave it at the end of the file, where
1787  * Emacs will automagically detect them.
1788  * ---------------------------------------------------------------------
1789  * Local variables:
1790  * mode: c
1791  * indent-tabs-mode: t
1792  * c-basic-offset: 4
1793  * tab-width: 4
1794  * End:
1795  * vim:noexpandtab:sw=4:ts=4:
1796  */