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