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