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