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