* src/threads/posix/thread-posix.c (threads_startup_thread): Compile fix.
[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       *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         threads_thread_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 #endif
1341
1342         /* Thread has terminated. */
1343
1344         threads_thread_state_terminated(t);
1345
1346         /* Notify all threads waiting on this thread.  These are joining
1347            this thread. */
1348
1349         o = (java_handle_t *) object;
1350
1351         /* XXX Care about exceptions? */
1352         (void) lock_monitor_enter(o);
1353         
1354         lock_notify_all_object(o);
1355
1356         /* XXX Care about exceptions? */
1357         (void) lock_monitor_exit(o);
1358
1359         /* Enter the join-mutex before calling thread_free, so
1360            threads_join_all_threads gets the correct number of non-daemon
1361            threads. */
1362
1363         threads_mutex_join_lock();
1364
1365         /* Free the internal thread data-structure. */
1366
1367         thread_free(t);
1368
1369         /* Signal that this thread has finished and leave the mutex. */
1370
1371         pthread_cond_signal(&cond_join);
1372         threads_mutex_join_unlock();
1373
1374         return true;
1375 }
1376
1377
1378 /* threads_suspend_thread ******************************************************
1379
1380    Suspend the passed thread. Execution stops until the thread
1381    is explicitly resumend again.
1382
1383    IN:
1384      reason.....Reason for suspending this thread.
1385
1386 *******************************************************************************/
1387
1388 bool threads_suspend_thread(threadobject *thread, s4 reason)
1389 {
1390         /* acquire the suspendmutex */
1391         mutex_lock(&(thread->suspendmutex));
1392
1393         if (thread->suspended) {
1394                 mutex_unlock(&(thread->suspendmutex));
1395                 return false;
1396         }
1397
1398         /* set the reason for the suspension */
1399         thread->suspend_reason = reason;
1400
1401         /* send the suspend signal to the thread */
1402         assert(thread != THREADOBJECT);
1403         if (pthread_kill(thread->tid, SIGUSR1) != 0)
1404                 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1405                                  strerror(errno));
1406
1407         /* REMEMBER: do not release the suspendmutex, this is done
1408            by the thread itself in threads_suspend_ack().  */
1409
1410         return true;
1411 }
1412
1413
1414 /* threads_suspend_ack *********************************************************
1415
1416    Acknowledges the suspension of the current thread.
1417
1418    IN:
1419      pc.....The PC where the thread suspended its execution.
1420      sp.....The SP before the thread suspended its execution.
1421
1422 *******************************************************************************/
1423
1424 void threads_suspend_ack(u1* pc, u1* sp)
1425 {
1426         threadobject *thread;
1427
1428         thread = THREADOBJECT;
1429
1430         assert(thread->suspend_reason != 0);
1431
1432         /* TODO: remember dump memory size */
1433
1434 #if defined(ENABLE_GC_CACAO)
1435         /* inform the GC about the suspension */
1436         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1437
1438                 /* check if the GC wants to leave the thread running */
1439                 if (!gc_suspend(thread, pc, sp)) {
1440
1441                         /* REMEMBER: we do not unlock the suspendmutex because the thread
1442                            will suspend itself again at a later time */
1443                         return;
1444
1445                 }
1446         }
1447 #endif
1448
1449         /* mark this thread as suspended and remember the PC */
1450         thread->pc        = pc;
1451         thread->suspended = true;
1452
1453         /* if we are stopping the world, we should send a global ack */
1454         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1455                 threads_sem_post(&suspend_ack);
1456         }
1457
1458         DEBUGTHREADS("suspending", thread);
1459
1460         /* release the suspension mutex and wait till we are resumed */
1461         pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1462
1463         DEBUGTHREADS("resuming", thread);
1464
1465         /* if we are stopping the world, we should send a global ack */
1466         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1467                 threads_sem_post(&suspend_ack);
1468         }
1469
1470         /* TODO: free dump memory */
1471
1472         /* release the suspendmutex */
1473         mutex_unlock(&(thread->suspendmutex));
1474 }
1475
1476
1477 /* threads_resume_thread *******************************************************
1478
1479    Resumes the execution of the passed thread.
1480
1481 *******************************************************************************/
1482
1483 bool threads_resume_thread(threadobject *thread)
1484 {
1485         /* acquire the suspendmutex */
1486         mutex_lock(&(thread->suspendmutex));
1487
1488         if (!thread->suspended) {
1489                 mutex_unlock(&(thread->suspendmutex));
1490                 return false;
1491         }
1492
1493         thread->suspended = false;
1494
1495         /* tell everyone that the thread should resume */
1496         assert(thread != THREADOBJECT);
1497         pthread_cond_broadcast(&(thread->suspendcond));
1498
1499         /* release the suspendmutex */
1500         mutex_unlock(&(thread->suspendmutex));
1501
1502         return true;
1503 }
1504
1505
1506 /* threads_join_all_threads ****************************************************
1507
1508    Join all non-daemon threads.
1509
1510 *******************************************************************************/
1511
1512 void threads_join_all_threads(void)
1513 {
1514         threadobject *t;
1515
1516         /* get current thread */
1517
1518         t = THREADOBJECT;
1519
1520         /* this thread is waiting for all non-daemon threads to exit */
1521
1522         threads_thread_state_waiting(t);
1523
1524         /* enter join mutex */
1525
1526         threads_mutex_join_lock();
1527
1528         /* Wait for condition as long as we have non-daemon threads.  We
1529            compare against 1 because the current (main thread) is also a
1530            non-daemon thread. */
1531
1532         while (threadlist_get_non_daemons() > 1)
1533                 pthread_cond_wait(&cond_join, &mutex_join);
1534
1535         /* leave join mutex */
1536
1537         threads_mutex_join_unlock();
1538 }
1539
1540
1541 /* threads_timespec_earlier ****************************************************
1542
1543    Return true if timespec tv1 is earlier than timespec tv2.
1544
1545    IN:
1546       tv1..........first timespec
1547           tv2..........second timespec
1548
1549    RETURN VALUE:
1550       true, if the first timespec is earlier
1551
1552 *******************************************************************************/
1553
1554 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1555                                                                                         const struct timespec *tv2)
1556 {
1557         return (tv1->tv_sec < tv2->tv_sec)
1558                                 ||
1559                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1560 }
1561
1562
1563 /* threads_current_time_is_earlier_than ****************************************
1564
1565    Check if the current time is earlier than the given timespec.
1566
1567    IN:
1568       tv...........the timespec to compare against
1569
1570    RETURN VALUE:
1571       true, if the current time is earlier
1572
1573 *******************************************************************************/
1574
1575 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1576 {
1577         struct timeval tvnow;
1578         struct timespec tsnow;
1579
1580         /* get current time */
1581
1582         if (gettimeofday(&tvnow, NULL) != 0)
1583                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1584
1585         /* convert it to a timespec */
1586
1587         tsnow.tv_sec = tvnow.tv_sec;
1588         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1589
1590         /* compare current time with the given timespec */
1591
1592         return threads_timespec_earlier(&tsnow, tv);
1593 }
1594
1595
1596 /* threads_wait_with_timeout ***************************************************
1597
1598    Wait until the given point in time on a monitor until either
1599    we are notified, we are interrupted, or the time is up.
1600
1601    IN:
1602       t............the current thread
1603           wakeupTime...absolute (latest) wakeup time
1604                            If both tv_sec and tv_nsec are zero, this function
1605                                            waits for an unlimited amount of time.
1606
1607 *******************************************************************************/
1608
1609 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1610 {
1611         /* acquire the waitmutex */
1612
1613         mutex_lock(&t->waitmutex);
1614
1615         /* mark us as sleeping */
1616
1617         t->sleeping = true;
1618
1619         /* wait on waitcond */
1620
1621         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1622                 /* with timeout */
1623                 while (!t->interrupted && !t->signaled
1624                            && threads_current_time_is_earlier_than(wakeupTime))
1625                 {
1626                         threads_thread_state_timed_waiting(t);
1627
1628                         pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1629                                                                    wakeupTime);
1630
1631                         threads_thread_state_runnable(t);
1632                 }
1633         }
1634         else {
1635                 /* no timeout */
1636                 while (!t->interrupted && !t->signaled) {
1637                         threads_thread_state_waiting(t);
1638
1639                         pthread_cond_wait(&t->waitcond, &t->waitmutex);
1640
1641                         threads_thread_state_runnable(t);
1642                 }
1643         }
1644
1645         t->sleeping    = false;
1646
1647         /* release the waitmutex */
1648
1649         mutex_unlock(&t->waitmutex);
1650 }
1651
1652
1653 /* threads_wait_with_timeout_relative ******************************************
1654
1655    Wait for the given maximum amount of time on a monitor until either
1656    we are notified, we are interrupted, or the time is up.
1657
1658    IN:
1659       t............the current thread
1660           millis.......milliseconds to wait
1661           nanos........nanoseconds to wait
1662
1663 *******************************************************************************/
1664
1665 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1666                                                                                 s4 nanos)
1667 {
1668         struct timespec wakeupTime;
1669
1670         /* calculate the the (latest) wakeup time */
1671
1672         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1673
1674         /* wait */
1675
1676         threads_wait_with_timeout(thread, &wakeupTime);
1677 }
1678
1679
1680 /* threads_calc_absolute_time **************************************************
1681
1682    Calculate the absolute point in time a given number of ms and ns from now.
1683
1684    IN:
1685       millis............milliseconds from now
1686           nanos.............nanoseconds from now
1687
1688    OUT:
1689       *tm...............receives the timespec of the absolute point in time
1690
1691 *******************************************************************************/
1692
1693 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1694 {
1695         if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1696                 struct timeval tv;
1697                 long nsec;
1698                 gettimeofday(&tv, NULL);
1699                 tv.tv_sec += millis / 1000;
1700                 millis %= 1000;
1701                 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1702                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1703                 tm->tv_nsec = nsec % 1000000000;
1704         }
1705         else {
1706                 tm->tv_sec = 0;
1707                 tm->tv_nsec = 0;
1708         }
1709 }
1710
1711
1712 /* threads_thread_interrupt ****************************************************
1713
1714    Interrupt the given thread.
1715
1716    The thread gets the "waitcond" signal and 
1717    its interrupted flag is set to true.
1718
1719    IN:
1720       thread............the thread to interrupt
1721
1722 *******************************************************************************/
1723
1724 void threads_thread_interrupt(threadobject *thread)
1725 {
1726         /* Signal the thread a "waitcond" and tell it that it has been
1727            interrupted. */
1728
1729         mutex_lock(&thread->waitmutex);
1730
1731         DEBUGTHREADS("interrupted", thread);
1732
1733         /* Interrupt blocking system call using a signal. */
1734
1735         pthread_kill(thread->tid, SIGHUP);
1736
1737         if (thread->sleeping)
1738                 pthread_cond_signal(&thread->waitcond);
1739
1740         thread->interrupted = true;
1741
1742         mutex_unlock(&thread->waitmutex);
1743 }
1744
1745
1746 /* threads_sleep ***************************************************************
1747
1748    Sleep the current thread for the specified amount of time.
1749
1750 *******************************************************************************/
1751
1752 void threads_sleep(s8 millis, s4 nanos)
1753 {
1754         threadobject    *t;
1755         struct timespec  wakeupTime;
1756         bool             interrupted;
1757
1758         t = THREADOBJECT;
1759
1760         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1761
1762         threads_wait_with_timeout(t, &wakeupTime);
1763
1764         interrupted = thread_is_interrupted(t);
1765
1766         thread_set_interrupted(t, false);
1767
1768         if (interrupted)
1769                 exceptions_throw_interruptedexception();
1770 }
1771
1772
1773 /* threads_yield ***************************************************************
1774
1775    Yield to the scheduler.
1776
1777 *******************************************************************************/
1778
1779 void threads_yield(void)
1780 {
1781         sched_yield();
1782 }
1783
1784
1785 /*
1786  * These are local overrides for various environment variables in Emacs.
1787  * Please do not remove this and leave it at the end of the file, where
1788  * Emacs will automagically detect them.
1789  * ---------------------------------------------------------------------
1790  * Local variables:
1791  * mode: c
1792  * indent-tabs-mode: t
1793  * c-basic-offset: 4
1794  * tab-width: 4
1795  * End:
1796  * vim:noexpandtab:sw=4:ts=4:
1797  */