Fix mysterious unremovable file part 2 ?
[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 #if defined(ENABLE_TLH)
691         tlh_init(&(t->tlh));
692 #endif
693 }
694
695 /* threads_impl_thread_clear ***************************************************
696
697    Clears all fields in threadobject the way an MZERO would have
698    done. MZERO cannot be used anymore because it would mess up the
699    pthread_* bits.
700
701    IN:
702       t....the threadobject
703
704 *******************************************************************************/
705
706 void threads_impl_thread_clear(threadobject *t)
707 {
708         t->object = NULL;
709
710         t->thinlock = 0;
711
712         t->index = 0;
713         t->flags = 0;
714         t->state = 0;
715
716         t->tid = 0;
717
718 #if defined(__DARWIN__)
719         t->mach_thread = 0;
720 #endif
721
722         t->interrupted = false;
723         t->signaled = false;
724         t->sleeping = false;
725
726         t->suspended = false;
727         t->suspend_reason = 0;
728
729         t->pc = NULL;
730
731         t->_exceptionptr = NULL;
732         t->_stackframeinfo = NULL;
733         t->_localref_table = NULL;
734
735 #if defined(ENABLE_INTRP)
736         t->_global_sp = NULL;
737 #endif
738
739 #if defined(ENABLE_GC_CACAO)
740         t->gc_critical = false;
741
742         t->ss = NULL;
743         t->es = NULL;
744 #endif
745
746         MZERO(&t->dumpinfo, dumpinfo_t, 1);
747 }
748
749 /* threads_impl_thread_reuse ***************************************************
750
751    Resets some implementation fields in threadobject. This was
752    previously done in threads_impl_thread_new.
753
754    IN:
755       t....the threadobject
756
757 *******************************************************************************/
758
759 void threads_impl_thread_reuse(threadobject *t)
760 {
761         /* get the pthread id */
762
763         t->tid = pthread_self();
764
765 #if defined(ENABLE_DEBUG_FILTER)
766         /* Initialize filter counters */
767         t->filterverbosecallctr[0] = 0;
768         t->filterverbosecallctr[1] = 0;
769 #endif
770
771 #if !defined(NDEBUG)
772         t->tracejavacallindent = 0;
773         t->tracejavacallcount = 0;
774 #endif
775
776         t->flc_bit = false;
777         t->flc_next = NULL;
778         t->flc_list = NULL;
779
780 /*      not really needed */
781         t->flc_object = NULL;
782
783 #if defined(ENABLE_TLH)
784         tlh_destroy(&(t->tlh));
785         tlh_init(&(t->tlh));
786 #endif
787 }
788
789
790 /* threads_impl_thread_free ****************************************************
791
792    Cleanup thread stuff.
793
794    IN:
795       t....the threadobject
796
797 *******************************************************************************/
798
799 #if 0
800 /* never used */
801 void threads_impl_thread_free(threadobject *t)
802 {
803         int result;
804
805         /* Destroy the mutex and the condition. */
806
807         mutex_destroy(&(t->flc_lock));
808
809         result = pthread_cond_destroy(&(t->flc_cond));
810
811         if (result != 0)
812                 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
813
814         mutex_destroy(&(t->waitmutex));
815
816         result = pthread_cond_destroy(&(t->waitcond));
817
818         if (result != 0)
819                 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
820
821         mutex_destroy(&(t->suspendmutex));
822
823         result = pthread_cond_destroy(&(t->suspendcond));
824
825         if (result != 0)
826                 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
827 }
828 #endif
829
830
831 /* threads_impl_preinit ********************************************************
832
833    Do some early initialization of stuff required.
834
835    ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
836    is called AFTER this function!
837
838 *******************************************************************************/
839
840 void threads_impl_preinit(void)
841 {
842         int result;
843
844         mutex_init(&stopworldlock);
845
846         /* initialize exit mutex and condition (on exit we join all
847            threads) */
848
849         mutex_init(&mutex_join);
850
851         result = pthread_cond_init(&cond_join, NULL);
852         if (result != 0)
853                 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
854
855 #if defined(ENABLE_GC_CACAO)
856         /* initialize the GC mutex & suspend semaphore */
857
858         mutex_init(&mutex_gc);
859         threads_sem_init(&suspend_ack, 0, 0);
860 #endif
861
862 #if !defined(HAVE___THREAD)
863         result = pthread_key_create(&thread_current_key, NULL);
864         if (result != 0)
865                 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
866 #endif
867 }
868
869
870 /* threads_mutex_gc_lock *******************************************************
871
872    Enter the global GC mutex.
873
874 *******************************************************************************/
875
876 #if defined(ENABLE_GC_CACAO)
877 void threads_mutex_gc_lock(void)
878 {
879         mutex_lock(&mutex_gc);
880 }
881 #endif
882
883
884 /* threads_mutex_gc_unlock *****************************************************
885
886    Leave the global GC mutex.
887
888 *******************************************************************************/
889
890 #if defined(ENABLE_GC_CACAO)
891 void threads_mutex_gc_unlock(void)
892 {
893         mutex_unlock(&mutex_gc);
894 }
895 #endif
896
897 /* threads_mutex_join_lock *****************************************************
898
899    Enter the join mutex.
900
901 *******************************************************************************/
902
903 void threads_mutex_join_lock(void)
904 {
905         mutex_lock(&mutex_join);
906 }
907
908
909 /* threads_mutex_join_unlock ***************************************************
910
911    Leave the join mutex.
912
913 *******************************************************************************/
914
915 void threads_mutex_join_unlock(void)
916 {
917         mutex_unlock(&mutex_join);
918 }
919
920
921 /* threads_impl_init ***********************************************************
922
923    Initializes the implementation specific bits.
924
925 *******************************************************************************/
926
927 void threads_impl_init(void)
928 {
929         pthread_attr_t attr;
930         int            result;
931
932         threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
933
934         /* Initialize the thread attribute object. */
935
936         result = pthread_attr_init(&attr);
937
938         if (result != 0)
939                 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
940
941         result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
942
943         if (result != 0)
944                 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
945 }
946
947
948 /* threads_startup_thread ******************************************************
949
950    Thread startup function called by pthread_create.
951
952    Thread which have a startup.function != NULL are marked as internal
953    threads. All other threads are threated as normal Java threads.
954
955    NOTE: This function is not called directly by pthread_create. The Boehm GC
956          inserts its own GC_start_routine in between, which then calls
957                  threads_startup.
958
959    IN:
960       arg..........the argument passed to pthread_create, ie. a pointer to
961                        a startupinfo struct. CAUTION: When the `psem` semaphore
962                                    is posted, the startupinfo struct becomes invalid! (It
963                                    is allocated on the stack of threads_start_thread.)
964
965 ******************************************************************************/
966
967 static void *threads_startup_thread(void *arg)
968 {
969         startupinfo        *startup;
970         threadobject       *t;
971         java_lang_Thread   *object;
972 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
973         java_lang_VMThread *vmt;
974 #endif
975         sem_t              *psem;
976         classinfo          *c;
977         methodinfo         *m;
978         java_handle_t      *o;
979         functionptr         function;
980
981 #if defined(ENABLE_INTRP)
982         u1 *intrp_thread_stack;
983
984         /* create interpreter stack */
985
986         if (opt_intrp) {
987                 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
988                 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
989         }
990         else
991                 intrp_thread_stack = NULL;
992 #endif
993
994         /* get passed startupinfo structure and the values in there */
995
996         startup = arg;
997
998         t        = startup->thread;
999         function = startup->function;
1000         psem     = startup->psem;
1001
1002         /* Seems like we've encountered a situation where thread->tid was
1003            not set by pthread_create. We alleviate this problem by waiting
1004            for pthread_create to return. */
1005
1006         threads_sem_wait(startup->psem_first);
1007
1008 #if defined(__DARWIN__)
1009         t->mach_thread = mach_thread_self();
1010 #endif
1011
1012         /* Now that we are in the new thread, we can store the internal
1013            thread data-structure in the TSD. */
1014
1015         thread_set_current(t);
1016
1017         /* get the java.lang.Thread object for this thread */
1018
1019         object = (java_lang_Thread *) thread_get_object(t);
1020
1021         /* set our priority */
1022
1023         threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
1024
1025         /* Thread is completely initialized. */
1026
1027         thread_set_state_runnable(t);
1028
1029         /* tell threads_startup_thread that we registered ourselves */
1030         /* CAUTION: *startup becomes invalid with this!             */
1031
1032         startup = NULL;
1033         threads_sem_post(psem);
1034
1035 #if defined(ENABLE_INTRP)
1036         /* set interpreter stack */
1037
1038         if (opt_intrp)
1039                 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1040 #endif
1041
1042 #if defined(ENABLE_JVMTI)
1043         /* fire thread start event */
1044
1045         if (jvmti) 
1046                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1047 #endif
1048
1049         DEBUGTHREADS("starting", t);
1050
1051         /* find and run the Thread.run()V method if no other function was passed */
1052
1053         if (function == NULL) {
1054 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1055                 /* We need to start the run method of
1056                    java.lang.VMThread. Since this is a final class, we can use
1057                    the class object directly. */
1058
1059                 c = class_java_lang_VMThread;
1060 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1061                 LLNI_class_get(object, c);
1062 #else
1063 # error unknown classpath configuration
1064 #endif
1065
1066                 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1067
1068                 if (m == NULL)
1069                         vm_abort("threads_startup_thread: run() method not found in class");
1070
1071                 /* set ThreadMXBean variables */
1072
1073                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1074                 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1075
1076                 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1077                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1078                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1079                                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1080
1081 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1082                 /* we need to start the run method of java.lang.VMThread */
1083
1084                 LLNI_field_get_ref(object, vmThread, vmt);
1085                 o = (java_handle_t *) vmt;
1086
1087 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1088                 o = (java_handle_t *) object;
1089 #else
1090 # error unknown classpath configuration
1091 #endif
1092
1093                 /* Run the thread. */
1094
1095                 (void) vm_call_method(m, o);
1096         }
1097         else {
1098                 /* set ThreadMXBean variables */
1099
1100                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1101                 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1102
1103                 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1104                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1105                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1106                                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1107
1108                 /* call passed function, e.g. finalizer_thread */
1109
1110                 (function)();
1111         }
1112
1113         DEBUGTHREADS("stopping", t);
1114
1115 #if defined(ENABLE_JVMTI)
1116         /* fire thread end event */
1117
1118         if (jvmti)
1119                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1120 #endif
1121
1122         /* We ignore the return value. */
1123
1124         (void) threads_detach_thread(t);
1125
1126         /* set ThreadMXBean variables */
1127
1128         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1129
1130         return NULL;
1131 }
1132
1133
1134 /* threads_impl_thread_start ***************************************************
1135
1136    Start a thread in the JVM.  Both (vm internal and java) thread
1137    objects exist.
1138
1139    IN:
1140       thread....the thread object
1141           f.........function to run in the new thread. NULL means that the
1142                     "run" method of the object `t` should be called
1143
1144 ******************************************************************************/
1145
1146 void threads_impl_thread_start(threadobject *thread, functionptr f)
1147 {
1148         sem_t          sem;
1149         sem_t          sem_first;
1150         pthread_attr_t attr;
1151         startupinfo    startup;
1152         int            result;
1153
1154         /* fill startupinfo structure passed by pthread_create to
1155          * threads_startup_thread */
1156
1157         startup.thread     = thread;
1158         startup.function   = f;              /* maybe we don't call Thread.run()V */
1159         startup.psem       = &sem;
1160         startup.psem_first = &sem_first;
1161
1162         threads_sem_init(&sem, 0, 0);
1163         threads_sem_init(&sem_first, 0, 0);
1164
1165         /* Initialize thread attributes. */
1166
1167         result = pthread_attr_init(&attr);
1168
1169         if (result != 0)
1170                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1171
1172     result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1173
1174     if (result != 0)
1175                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1176
1177         /* initialize thread stacksize */
1178
1179         result = pthread_attr_setstacksize(&attr, opt_stacksize);
1180
1181         if (result != 0)
1182                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1183
1184         /* create the thread */
1185
1186         result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1187
1188         if (result != 0)
1189                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1190
1191         /* destroy the thread attributes */
1192
1193         result = pthread_attr_destroy(&attr);
1194
1195         if (result != 0)
1196                 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1197
1198         /* signal that pthread_create has returned, so thread->tid is valid */
1199
1200         threads_sem_post(&sem_first);
1201
1202         /* wait here until the thread has entered itself into the thread list */
1203
1204         threads_sem_wait(&sem);
1205
1206         /* cleanup */
1207
1208         sem_destroy(&sem);
1209         sem_destroy(&sem_first);
1210 }
1211
1212
1213 /* threads_set_thread_priority *************************************************
1214
1215    Set the priority of the given thread.
1216
1217    IN:
1218       tid..........thread id
1219           priority.....priority to set
1220
1221 ******************************************************************************/
1222
1223 void threads_set_thread_priority(pthread_t tid, int priority)
1224 {
1225         struct sched_param schedp;
1226         int policy;
1227
1228         pthread_getschedparam(tid, &policy, &schedp);
1229         schedp.sched_priority = priority;
1230         pthread_setschedparam(tid, policy, &schedp);
1231 }
1232
1233
1234 /* threads_detach_thread *******************************************************
1235
1236    Detaches the passed thread from the VM.  Used in JNI.
1237
1238 *******************************************************************************/
1239
1240 bool threads_detach_thread(threadobject *t)
1241 {
1242         bool                   result;
1243         java_lang_Thread      *object;
1244         java_handle_t         *o;
1245 #if defined(ENABLE_JAVASE)
1246         java_lang_ThreadGroup *group;
1247         java_handle_t         *e;
1248         void                  *handler;
1249         classinfo             *c;
1250         methodinfo            *m;
1251 #endif
1252
1253     /* If the given thread has already been detached, this operation
1254            is a no-op. */
1255
1256         result = thread_is_attached(t);
1257
1258         if (result == false)
1259                 return true;
1260
1261         DEBUGTHREADS("detaching", t);
1262
1263         object = (java_lang_Thread *) thread_get_object(t);
1264
1265 #if defined(ENABLE_JAVASE)
1266         LLNI_field_get_ref(object, group, group);
1267
1268     /* If there's an uncaught exception, call uncaughtException on the
1269        thread's exception handler, or the thread's group if this is
1270        unset. */
1271
1272         e = exceptions_get_and_clear_exception();
1273
1274     if (e != NULL) {
1275                 /* We use the type void* for handler here, as it's not trivial
1276                    to build the java_lang_Thread_UncaughtExceptionHandler
1277                    header file with cacaoh. */
1278
1279 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1280                 LLNI_field_get_ref(object, exceptionHandler, handler);
1281 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1282                 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1283 # endif
1284
1285                 if (handler != NULL) {
1286                         LLNI_class_get(handler, c);
1287                         o = (java_handle_t *) handler;
1288                 }
1289                 else {
1290                         LLNI_class_get(group, c);
1291                         o = (java_handle_t *) group;
1292                 }
1293
1294                 m = class_resolveclassmethod(c,
1295                                                                          utf_uncaughtException,
1296                                                                          utf_java_lang_Thread_java_lang_Throwable__V,
1297                                                                          NULL,
1298                                                                          true);
1299
1300                 if (m == NULL)
1301                         return false;
1302
1303                 (void) vm_call_method(m, o, object, e);
1304
1305                 if (exceptions_get_exception())
1306                         return false;
1307     }
1308
1309         /* XXX TWISTI: should all threads be in a ThreadGroup? */
1310
1311         /* Remove thread from the thread group. */
1312
1313         if (group != NULL) {
1314                 LLNI_class_get(group, c);
1315
1316 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1317                 m = class_resolveclassmethod(c,
1318                                                                          utf_removeThread,
1319                                                                          utf_java_lang_Thread__V,
1320                                                                          class_java_lang_ThreadGroup,
1321                                                                          true);
1322 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1323                 m = class_resolveclassmethod(c,
1324                                                                          utf_remove,
1325                                                                          utf_java_lang_Thread__V,
1326                                                                          class_java_lang_ThreadGroup,
1327                                                                          true);
1328 # else
1329 #  error unknown classpath configuration
1330 # endif
1331
1332                 if (m == NULL)
1333                         return false;
1334
1335                 o = (java_handle_t *) group;
1336
1337                 (void) vm_call_method(m, o, object);
1338
1339                 if (exceptions_get_exception())
1340                         return false;
1341
1342                 /* Reset the threadgroup in the Java thread object (Mauve
1343                    test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1344
1345                 LLNI_field_set_ref(object, group, NULL);
1346         }
1347 #endif
1348
1349         /* Thread has terminated. */
1350
1351         thread_set_state_terminated(t);
1352
1353         /* Notify all threads waiting on this thread.  These are joining
1354            this thread. */
1355
1356         o = (java_handle_t *) object;
1357
1358         /* XXX Care about exceptions? */
1359         (void) lock_monitor_enter(o);
1360         
1361         lock_notify_all_object(o);
1362
1363         /* XXX Care about exceptions? */
1364         (void) lock_monitor_exit(o);
1365
1366         /* Enter the join-mutex before calling thread_free, so
1367            threads_join_all_threads gets the correct number of non-daemon
1368            threads. */
1369
1370         threads_mutex_join_lock();
1371
1372         /* Free the internal thread data-structure. */
1373
1374         thread_free(t);
1375
1376         /* Signal that this thread has finished and leave the mutex. */
1377
1378         pthread_cond_signal(&cond_join);
1379         threads_mutex_join_unlock();
1380
1381         return true;
1382 }
1383
1384
1385 #if defined(ENABLE_GC_CACAO)
1386
1387 /* threads_suspend_thread ******************************************************
1388
1389    Suspend the passed thread. Execution stops until the thread
1390    is explicitly resumend again.
1391
1392    IN:
1393      reason.....Reason for suspending this thread.
1394
1395 *******************************************************************************/
1396
1397 bool threads_suspend_thread(threadobject *thread, s4 reason)
1398 {
1399         /* acquire the suspendmutex */
1400         mutex_lock(&(thread->suspendmutex));
1401
1402         if (thread->suspended) {
1403                 mutex_unlock(&(thread->suspendmutex));
1404                 return false;
1405         }
1406
1407         /* set the reason for the suspension */
1408         thread->suspend_reason = reason;
1409
1410         /* send the suspend signal to the thread */
1411         assert(thread != THREADOBJECT);
1412         if (pthread_kill(thread->tid, SIGUSR1) != 0)
1413                 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1414                                  strerror(errno));
1415
1416         /* REMEMBER: do not release the suspendmutex, this is done
1417            by the thread itself in threads_suspend_ack().  */
1418
1419         return true;
1420 }
1421
1422
1423 /* threads_suspend_ack *********************************************************
1424
1425    Acknowledges the suspension of the current thread.
1426
1427    IN:
1428      pc.....The PC where the thread suspended its execution.
1429      sp.....The SP before the thread suspended its execution.
1430
1431 *******************************************************************************/
1432
1433 void threads_suspend_ack(u1* pc, u1* sp)
1434 {
1435         threadobject *thread;
1436
1437         thread = THREADOBJECT;
1438
1439         assert(thread->suspend_reason != 0);
1440
1441         /* TODO: remember dump memory size */
1442
1443         /* inform the GC about the suspension */
1444         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1445
1446                 /* check if the GC wants to leave the thread running */
1447                 if (!gc_suspend(thread, pc, sp)) {
1448
1449                         /* REMEMBER: we do not unlock the suspendmutex because the thread
1450                            will suspend itself again at a later time */
1451                         return;
1452
1453                 }
1454         }
1455
1456         /* mark this thread as suspended and remember the PC */
1457         thread->pc        = pc;
1458         thread->suspended = true;
1459
1460         /* if we are stopping the world, we should send a global ack */
1461         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1462                 threads_sem_post(&suspend_ack);
1463         }
1464
1465         DEBUGTHREADS("suspending", thread);
1466
1467         /* release the suspension mutex and wait till we are resumed */
1468         pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1469
1470         DEBUGTHREADS("resuming", thread);
1471
1472         /* if we are stopping the world, we should send a global ack */
1473         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1474                 threads_sem_post(&suspend_ack);
1475         }
1476
1477         /* TODO: free dump memory */
1478
1479         /* release the suspendmutex */
1480         mutex_unlock(&(thread->suspendmutex));
1481 }
1482
1483
1484 /* threads_resume_thread *******************************************************
1485
1486    Resumes the execution of the passed thread.
1487
1488 *******************************************************************************/
1489
1490 bool threads_resume_thread(threadobject *thread)
1491 {
1492         /* acquire the suspendmutex */
1493         mutex_lock(&(thread->suspendmutex));
1494
1495         if (!thread->suspended) {
1496                 mutex_unlock(&(thread->suspendmutex));
1497                 return false;
1498         }
1499
1500         thread->suspended = false;
1501
1502         /* tell everyone that the thread should resume */
1503         assert(thread != THREADOBJECT);
1504         pthread_cond_broadcast(&(thread->suspendcond));
1505
1506         /* release the suspendmutex */
1507         mutex_unlock(&(thread->suspendmutex));
1508
1509         return true;
1510 }
1511
1512 #endif
1513
1514 /* threads_join_all_threads ****************************************************
1515
1516    Join all non-daemon threads.
1517
1518 *******************************************************************************/
1519
1520 void threads_join_all_threads(void)
1521 {
1522         threadobject *t;
1523
1524         /* get current thread */
1525
1526         t = THREADOBJECT;
1527
1528         /* This thread is waiting for all non-daemon threads to exit. */
1529
1530         thread_set_state_waiting(t);
1531
1532         /* enter join mutex */
1533
1534         threads_mutex_join_lock();
1535
1536         /* Wait for condition as long as we have non-daemon threads.  We
1537            compare against 1 because the current (main thread) is also a
1538            non-daemon thread. */
1539
1540         while (threadlist_get_non_daemons() > 1)
1541                 pthread_cond_wait(&cond_join, &mutex_join);
1542
1543         /* leave join mutex */
1544
1545         threads_mutex_join_unlock();
1546 }
1547
1548
1549 /* threads_timespec_earlier ****************************************************
1550
1551    Return true if timespec tv1 is earlier than timespec tv2.
1552
1553    IN:
1554       tv1..........first timespec
1555           tv2..........second timespec
1556
1557    RETURN VALUE:
1558       true, if the first timespec is earlier
1559
1560 *******************************************************************************/
1561
1562 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1563                                                                                         const struct timespec *tv2)
1564 {
1565         return (tv1->tv_sec < tv2->tv_sec)
1566                                 ||
1567                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1568 }
1569
1570
1571 /* threads_current_time_is_earlier_than ****************************************
1572
1573    Check if the current time is earlier than the given timespec.
1574
1575    IN:
1576       tv...........the timespec to compare against
1577
1578    RETURN VALUE:
1579       true, if the current time is earlier
1580
1581 *******************************************************************************/
1582
1583 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1584 {
1585         struct timeval tvnow;
1586         struct timespec tsnow;
1587
1588         /* get current time */
1589
1590         if (gettimeofday(&tvnow, NULL) != 0)
1591                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1592
1593         /* convert it to a timespec */
1594
1595         tsnow.tv_sec = tvnow.tv_sec;
1596         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1597
1598         /* compare current time with the given timespec */
1599
1600         return threads_timespec_earlier(&tsnow, tv);
1601 }
1602
1603
1604 /* threads_wait_with_timeout ***************************************************
1605
1606    Wait until the given point in time on a monitor until either
1607    we are notified, we are interrupted, or the time is up.
1608
1609    IN:
1610       t............the current thread
1611           wakeupTime...absolute (latest) wakeup time
1612                            If both tv_sec and tv_nsec are zero, this function
1613                                            waits for an unlimited amount of time.
1614
1615 *******************************************************************************/
1616
1617 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1618 {
1619         /* acquire the waitmutex */
1620
1621         mutex_lock(&t->waitmutex);
1622
1623         /* mark us as sleeping */
1624
1625         t->sleeping = true;
1626
1627         /* wait on waitcond */
1628
1629         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1630                 /* with timeout */
1631                 while (!t->interrupted && !t->signaled
1632                            && threads_current_time_is_earlier_than(wakeupTime))
1633                 {
1634                         thread_set_state_timed_waiting(t);
1635
1636                         pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1637                                                                    wakeupTime);
1638
1639                         thread_set_state_runnable(t);
1640                 }
1641         }
1642         else {
1643                 /* no timeout */
1644                 while (!t->interrupted && !t->signaled) {
1645                         thread_set_state_waiting(t);
1646
1647                         pthread_cond_wait(&t->waitcond, &t->waitmutex);
1648
1649                         thread_set_state_runnable(t);
1650                 }
1651         }
1652
1653         t->sleeping    = false;
1654
1655         /* release the waitmutex */
1656
1657         mutex_unlock(&t->waitmutex);
1658 }
1659
1660
1661 /* threads_wait_with_timeout_relative ******************************************
1662
1663    Wait for the given maximum amount of time on a monitor until either
1664    we are notified, we are interrupted, or the time is up.
1665
1666    IN:
1667       t............the current thread
1668           millis.......milliseconds to wait
1669           nanos........nanoseconds to wait
1670
1671 *******************************************************************************/
1672
1673 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1674                                                                                 s4 nanos)
1675 {
1676         struct timespec wakeupTime;
1677
1678         /* calculate the the (latest) wakeup time */
1679
1680         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1681
1682         /* wait */
1683
1684         threads_wait_with_timeout(thread, &wakeupTime);
1685 }
1686
1687
1688 /* threads_calc_absolute_time **************************************************
1689
1690    Calculate the absolute point in time a given number of ms and ns from now.
1691
1692    IN:
1693       millis............milliseconds from now
1694           nanos.............nanoseconds from now
1695
1696    OUT:
1697       *tm...............receives the timespec of the absolute point in time
1698
1699 *******************************************************************************/
1700
1701 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1702 {
1703         if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1704                 struct timeval tv;
1705                 long nsec;
1706                 gettimeofday(&tv, NULL);
1707                 tv.tv_sec += millis / 1000;
1708                 millis %= 1000;
1709                 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1710                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1711                 tm->tv_nsec = nsec % 1000000000;
1712         }
1713         else {
1714                 tm->tv_sec = 0;
1715                 tm->tv_nsec = 0;
1716         }
1717 }
1718
1719
1720 /* threads_thread_interrupt ****************************************************
1721
1722    Interrupt the given thread.
1723
1724    The thread gets the "waitcond" signal and 
1725    its interrupted flag is set to true.
1726
1727    IN:
1728       thread............the thread to interrupt
1729
1730 *******************************************************************************/
1731
1732 void threads_thread_interrupt(threadobject *thread)
1733 {
1734         /* Signal the thread a "waitcond" and tell it that it has been
1735            interrupted. */
1736
1737         mutex_lock(&thread->waitmutex);
1738
1739         DEBUGTHREADS("interrupted", thread);
1740
1741         /* Interrupt blocking system call using a signal. */
1742
1743         pthread_kill(thread->tid, SIGHUP);
1744
1745         if (thread->sleeping)
1746                 pthread_cond_signal(&thread->waitcond);
1747
1748         thread->interrupted = true;
1749
1750         mutex_unlock(&thread->waitmutex);
1751 }
1752
1753
1754 /* threads_sleep ***************************************************************
1755
1756    Sleep the current thread for the specified amount of time.
1757
1758 *******************************************************************************/
1759
1760 void threads_sleep(int64_t millis, int32_t nanos)
1761 {
1762         threadobject    *t;
1763         struct timespec  wakeupTime;
1764         bool             interrupted;
1765
1766         if (millis < 0) {
1767 /*              exceptions_throw_illegalargumentexception("timeout value is negative"); */
1768                 exceptions_throw_illegalargumentexception();
1769                 return;
1770         }
1771
1772         t = thread_get_current();
1773
1774         if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1775                 /* Clear interrupted flag (Mauve test:
1776                    gnu/testlet/java/lang/Thread/interrupt). */
1777
1778                 thread_set_interrupted(t, false);
1779
1780 /*              exceptions_throw_interruptedexception("sleep interrupted"); */
1781                 exceptions_throw_interruptedexception();
1782                 return;
1783         }
1784
1785         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1786
1787         threads_wait_with_timeout(t, &wakeupTime);
1788
1789         interrupted = thread_is_interrupted(t);
1790
1791         if (interrupted) {
1792                 thread_set_interrupted(t, false);
1793
1794                 /* An other exception could have been thrown
1795                    (e.g. ThreadDeathException). */
1796
1797                 if (!exceptions_get_exception())
1798                         exceptions_throw_interruptedexception();
1799         }
1800 }
1801
1802
1803 /* threads_yield ***************************************************************
1804
1805    Yield to the scheduler.
1806
1807 *******************************************************************************/
1808
1809 void threads_yield(void)
1810 {
1811         sched_yield();
1812 }
1813
1814 #if defined(ENABLE_TLH)
1815
1816 void threads_tlh_add_frame() {
1817         tlh_add_frame(&(THREADOBJECT->tlh));
1818 }
1819
1820 void threads_tlh_remove_frame() {
1821         tlh_remove_frame(&(THREADOBJECT->tlh));
1822 }
1823
1824 #endif
1825
1826 /*
1827  * These are local overrides for various environment variables in Emacs.
1828  * Please do not remove this and leave it at the end of the file, where
1829  * Emacs will automagically detect them.
1830  * ---------------------------------------------------------------------
1831  * Local variables:
1832  * mode: c
1833  * indent-tabs-mode: t
1834  * c-basic-offset: 4
1835  * tab-width: 4
1836  * End:
1837  * vim:noexpandtab:sw=4:ts=4:
1838  */