6a6244a18efcfdbba399761fd988b208ce95f7e9
[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 7766 2007-04-19 13:24:48Z michi $
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 void threads_cast_darwinstop(void)
386 {
387         threadobject *tobj = mainthreadobj;
388         threadobject *self = THREADOBJECT;
389
390         do {
391                 if (tobj != self)
392                 {
393                         thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
394                         mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
395 #if defined(__I386__)
396                         i386_thread_state_t thread_state;
397 #else
398                         ppc_thread_state_t thread_state;
399 #endif
400                         mach_port_t thread = tobj->mach_thread;
401                         kern_return_t r;
402
403                         r = thread_suspend(thread);
404
405                         if (r != KERN_SUCCESS)
406                                 vm_abort("thread_suspend failed");
407
408                         r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
409                                                                  &thread_state_count);
410
411                         if (r != KERN_SUCCESS)
412                                 vm_abort("thread_get_state failed");
413
414                         thread_restartcriticalsection((ucontext_t *) &thread_state);
415
416                         r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
417                                                                  thread_state_count);
418
419                         if (r != KERN_SUCCESS)
420                                 vm_abort("thread_set_state failed");
421                 }
422
423                 tobj = tobj->next;
424         } while (tobj != mainthreadobj);
425 }
426
427 static void threads_cast_darwinresume(void)
428 {
429         threadobject *tobj = mainthreadobj;
430         threadobject *self = THREADOBJECT;
431
432         do {
433                 if (tobj != self)
434                 {
435                         mach_port_t thread = tobj->mach_thread;
436                         kern_return_t r;
437
438                         r = thread_resume(thread);
439
440                         if (r != KERN_SUCCESS)
441                                 vm_abort("thread_resume failed");
442                 }
443
444                 tobj = tobj->next;
445         } while (tobj != mainthreadobj);
446 }
447
448 #endif
449
450 #if defined(__MIPS__)
451 static void threads_cast_irixresume(void)
452 {
453         pthread_mutex_lock(&suspend_ack_lock);
454         pthread_cond_broadcast(&suspend_cond);
455         pthread_mutex_unlock(&suspend_ack_lock);
456 }
457 #endif
458
459 #if 0
460 #if !defined(__DARWIN__)
461 static void threads_sigsuspend_handler(ucontext_t *ctx)
462 {
463         int sig;
464         sigset_t sigs;
465
466         /* XXX TWISTI: this is just a quick hack */
467 #if defined(ENABLE_JIT)
468         thread_restartcriticalsection(ctx);
469 #endif
470
471         /* Do as Boehm does. On IRIX a condition variable is used for wake-up
472            (not POSIX async-safe). */
473 #if defined(__IRIX__)
474         pthread_mutex_lock(&suspend_ack_lock);
475         threads_sem_post(&suspend_ack);
476         pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
477         pthread_mutex_unlock(&suspend_ack_lock);
478 #elif defined(__CYGWIN__)
479         /* TODO */
480         assert(0);
481 #else
482         threads_sem_post(&suspend_ack);
483
484         sig = GC_signum2();
485         sigfillset(&sigs);
486         sigdelset(&sigs, sig);
487         sigsuspend(&sigs);
488 #endif
489 }
490 #endif
491 #endif
492
493
494 /* threads_stopworld ***********************************************************
495
496    Stops the world from turning. All threads except the calling one
497    are suspended. The function returns as soon as all threads have
498    acknowledged their suspension.
499
500 *******************************************************************************/
501
502 #if !defined(DISABLE_GC)
503 void threads_stopworld(void)
504 {
505 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
506         threadobject *tobj = mainthreadobj;
507         threadobject *self = THREADOBJECT;
508         bool result;
509         int count, i;
510 #endif
511
512         lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
513         pthread_mutex_lock(&threadlistlock);
514
515 #if defined(__DARWIN__)
516         threads_cast_darwinstop();
517 #elif defined(__CYGWIN__)
518         /* TODO */
519         assert(0);
520 #else
521         /* count how many threads we suspended */
522         count = 0;
523
524         /* suspend all running threads */
525         do {
526                 if (tobj != self) {
527                         result = threads_suspend_thread(tobj, SUSPEND_REASON_STOPWORLD);
528                         assert(result);
529                         count++;
530                 }
531                 tobj = tobj->next;
532         } while (tobj != mainthreadobj);
533
534         /* wait till all threads are suspended */
535         for (i = 0; i < count; i++)
536                 threads_sem_wait(&suspend_ack);
537 #endif
538
539         pthread_mutex_unlock(&threadlistlock);
540 }
541 #endif /* !defined(DISABLE_GC) */
542
543
544 /* threads_startworld **********************************************************
545
546    Starts the world again after it has previously been stopped. 
547
548 *******************************************************************************/
549
550 #if !defined(DISABLE_GC)
551 void threads_startworld(void)
552 {
553 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
554         threadobject *tobj = mainthreadobj;
555         threadobject *self = THREADOBJECT;
556         bool result;
557 #endif
558
559         pthread_mutex_lock(&threadlistlock);
560
561 #if defined(__DARWIN__)
562         threads_cast_darwinresume();
563 #elif defined(__MIPS__)
564         threads_cast_irixresume();
565 #elif defined(__CYGWIN__)
566         /* TODO */
567         assert(0);
568 #else
569         /* resume all thread we haltet */
570         do {
571                 if (tobj != self) {
572                         result = threads_resume_thread(tobj);
573                         assert(result);
574                 }
575                 tobj = tobj->next;
576         } while (tobj != mainthreadobj);
577 #endif
578
579         pthread_mutex_unlock(&threadlistlock);
580         unlock_stopworld();
581 }
582 #endif /* DISABLE_GC */
583
584
585 /* threads_set_current_threadobject ********************************************
586
587    Set the current thread object.
588    
589    IN:
590       thread.......the thread object to set
591
592 *******************************************************************************/
593
594 static void threads_set_current_threadobject(threadobject *thread)
595 {
596 #if !defined(HAVE___THREAD)
597         pthread_setspecific(threads_current_threadobject_key, thread);
598 #else
599         threads_current_threadobject = thread;
600 #endif
601 }
602
603
604 /* threads_init_threadobject **************************************************
605
606    Initialize implementation fields of a threadobject.
607
608    IN:
609       thread............the threadobject
610
611 ******************************************************************************/
612
613 static void threads_init_threadobject(threadobject *thread)
614 {
615         /* get the pthread id */
616
617         thread->tid = pthread_self();
618
619         thread->index = 0;
620
621 #if defined(ENABLE_GC_CACAO)
622         thread->flags       |= THREAD_FLAG_IN_NATIVE;
623         thread->gc_critical  = false;
624 #endif
625
626         /* TODO destroy all those things */
627
628         pthread_mutex_init(&(thread->waitmutex), NULL);
629         pthread_cond_init(&(thread->waitcond), NULL);
630
631         thread->interrupted = false;
632         thread->signaled    = false;
633         thread->sleeping    = false;
634 }
635
636
637 /* threads_get_current_threadobject ********************************************
638
639    Return the threadobject of the current thread.
640    
641    RETURN VALUE:
642        the current threadobject *
643
644 *******************************************************************************/
645
646 threadobject *threads_get_current_threadobject(void)
647 {
648         return THREADOBJECT;
649 }
650
651
652 /* threads_preinit *************************************************************
653
654    Do some early initialization of stuff required.
655
656    ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
657    is called AFTER this function!
658
659 *******************************************************************************/
660
661 void threads_preinit(void)
662 {
663         pthread_mutex_init(&threadlistlock, NULL);
664         pthread_mutex_init(&stopworldlock, NULL);
665
666         /* initialize exit mutex and condition (on exit we join all
667            threads) */
668
669         pthread_mutex_init(&mutex_join, NULL);
670         pthread_cond_init(&cond_join, NULL);
671
672         mainthreadobj = NEW(threadobject);
673
674 #if defined(ENABLE_STATISTICS)
675         if (opt_stat)
676                 size_threadobject += sizeof(threadobject);
677 #endif
678
679         mainthreadobj->object   = NULL;
680         mainthreadobj->tid      = pthread_self();
681         mainthreadobj->index    = 1;
682         mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
683         
684 #if !defined(HAVE___THREAD)
685         pthread_key_create(&threads_current_threadobject_key, NULL);
686 #endif
687         threads_set_current_threadobject(mainthreadobj);
688
689         threads_sem_init(&suspend_ack, 0, 0);
690
691         /* initialize the threads table */
692
693         threads_table_init();
694
695         /* initialize subsystems */
696
697         lock_init();
698
699         critical_init();
700 }
701
702
703 /* threads_init ****************************************************************
704
705    Initializes the threads required by the JVM: main, finalizer.
706
707 *******************************************************************************/
708
709 bool threads_init(void)
710 {
711         java_objectheader     *threadname;
712         threadobject          *tempthread;
713         java_objectheader     *o;
714
715 #if defined(ENABLE_JAVASE)
716         java_lang_ThreadGroup *threadgroup;
717         methodinfo            *m;
718         java_lang_Thread      *t;
719 #endif
720
721 #if defined(WITH_CLASSPATH_GNU)
722         java_lang_VMThread    *vmt;
723 #endif
724
725         tempthread = mainthreadobj;
726
727         /* XXX We have to find a new way to free lock records */
728         /*     with the new locking algorithm.                */
729         /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
730
731 #if 0
732         /* This is kinda tricky, we grow the java.lang.Thread object so we
733            can keep the execution environment there. No Thread object must
734            have been created at an earlier time. */
735
736         class_java_lang_Thread->instancesize = sizeof(threadobject);
737 #endif
738
739         /* get methods we need in this file */
740
741 #if defined(WITH_CLASSPATH_GNU)
742         method_thread_init =
743                 class_resolveclassmethod(class_java_lang_Thread,
744                                                                  utf_init,
745                                                                  utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
746                                                                  class_java_lang_Thread,
747                                                                  true);
748 #else
749         method_thread_init =
750                 class_resolveclassmethod(class_java_lang_Thread,
751                                                                  utf_init,
752                                                                  utf_new_char("(Ljava/lang/String;)V"),
753                                                                  class_java_lang_Thread,
754                                                                  true);
755 #endif
756
757         if (method_thread_init == NULL)
758                 return false;
759
760         /* create a vm internal thread object for the main thread */
761         /* XXX Michi: we do not need to do this here, we could use the one
762                created by threads_preinit() */
763
764 #if defined(ENABLE_GC_CACAO)
765         mainthreadobj = NEW(threadobject);
766
767 # if defined(ENABLE_STATISTICS)
768         if (opt_stat)
769                 size_threadobject += sizeof(threadobject);
770 # endif
771 #else
772         mainthreadobj = GCNEW(threadobject);
773 #endif
774
775         if (mainthreadobj == NULL)
776                 return false;
777
778         /* create a java.lang.Thread for the main thread */
779
780         mainthreadobj->object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
781
782         if (mainthreadobj->object == NULL)
783                 return false;
784
785         FREE(tempthread, threadobject);
786
787         threads_init_threadobject(mainthreadobj);
788         threads_set_current_threadobject(mainthreadobj);
789         lock_init_execution_env(mainthreadobj);
790
791         /* thread is running */
792
793         mainthreadobj->state = THREAD_STATE_RUNNABLE;
794
795         mainthreadobj->next = mainthreadobj;
796         mainthreadobj->prev = mainthreadobj;
797
798         threads_table_add(mainthreadobj);
799
800         /* mark main thread as Java thread */
801
802         mainthreadobj->flags = THREAD_FLAG_JAVA;
803
804 #if defined(ENABLE_INTRP)
805         /* create interpreter stack */
806
807         if (opt_intrp) {
808                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
809                 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
810         }
811 #endif
812
813         threadname = javastring_new(utf_new_char("main"));
814
815 #if defined(ENABLE_JAVASE)
816         /* allocate and init ThreadGroup */
817
818         threadgroup = (java_lang_ThreadGroup *)
819                 native_new_and_init(class_java_lang_ThreadGroup);
820
821         if (threadgroup == NULL)
822                 return false;
823 #endif
824
825 #if defined(WITH_CLASSPATH_GNU)
826         /* create a java.lang.VMThread for the main thread */
827
828         vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
829
830         if (vmt == NULL)
831                 return false;
832
833         /* set the thread */
834
835         vmt->thread = mainthreadobj->object;
836         vmt->vmdata = (java_lang_Object *) mainthreadobj;
837
838         /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
839         o = (java_objectheader *) mainthreadobj->object;
840
841         (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
842                                                   false);
843 #elif defined(WITH_CLASSPATH_CLDC1_1)
844         /* set the thread */
845
846         mainthreadobj->object->vm_thread = (java_lang_Object *) mainthreadobj;
847
848         /* call public Thread(String name) */
849
850         o = (java_objectheader *) mainthreadobj->object;
851
852         (void) vm_call_method(method_thread_init, o, threadname);
853 #endif
854
855         if (*exceptionptr)
856                 return false;
857
858 #if defined(ENABLE_JAVASE)
859         mainthreadobj->object->group = threadgroup;
860
861         /* add main thread to java.lang.ThreadGroup */
862
863         m = class_resolveclassmethod(class_java_lang_ThreadGroup,
864                                                                  utf_addThread,
865                                                                  utf_java_lang_Thread__V,
866                                                                  class_java_lang_ThreadGroup,
867                                                                  true);
868
869         o = (java_objectheader *) threadgroup;
870         t = mainthreadobj->object;
871
872         (void) vm_call_method(m, o, t);
873
874         if (*exceptionptr)
875                 return false;
876
877 #endif
878
879         threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
880
881         /* initialize the thread attribute object */
882
883         if (pthread_attr_init(&threadattr)) {
884                 log_println("pthread_attr_init failed: %s", strerror(errno));
885                 return false;
886         }
887
888         pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
889
890         /* everything's ok */
891
892         return true;
893 }
894
895
896 /* threads_table_init *********************************************************
897
898    Initialize the global threads table.
899
900 ******************************************************************************/
901
902 static void threads_table_init(void)
903 {
904         s4 size;
905         s4 i;
906
907         size = THREADS_INITIAL_TABLE_SIZE;
908
909         threads_table.size = size;
910         threads_table.table = MNEW(threads_table_entry_t, size);
911
912         /* link the entries in a freelist */
913
914         for (i=0; i<size; ++i) {
915                 threads_table.table[i].nextfree = i+1;
916         }
917
918         /* terminate the freelist */
919
920         threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
921 }
922
923
924 /* threads_table_add **********************************************************
925
926    Add a thread to the global threads table. The index is entered in the
927    threadobject. The thinlock value for the thread is pre-computed.
928
929    IN:
930       thread............the thread to add
931
932    RETURN VALUE:
933       The table index for the newly added thread. This value has also been
934           entered in the threadobject.
935
936    PRE-CONDITION:
937       The caller must hold the threadlistlock!
938
939 ******************************************************************************/
940
941 static s4 threads_table_add(threadobject *thread)
942 {
943         s4 index;
944         s4 oldsize;
945         s4 newsize;
946         s4 i;
947
948         /* table[0] serves as the head of the freelist */
949
950         index = threads_table.table[0].nextfree;
951
952         /* if we got a free index, use it */
953
954         if (index) {
955 got_an_index:
956                 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
957                 threads_table.table[index].thread = thread;
958                 thread->index = index;
959                 thread->thinlock = lock_pre_compute_thinlock(index);
960                 return index;
961         }
962
963         /* we must grow the table */
964
965         oldsize = threads_table.size;
966         newsize = oldsize * 2;
967
968         threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
969                                                                    oldsize, newsize);
970         threads_table.size = newsize;
971
972         /* link the new entries to a free list */
973
974         for (i=oldsize; i<newsize; ++i) {
975                 threads_table.table[i].nextfree = i+1;
976         }
977
978         /* terminate the freelist */
979
980         threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
981
982         /* use the first of the new entries */
983
984         index = oldsize;
985         goto got_an_index;
986 }
987
988
989 /* threads_table_remove *******************************************************
990
991    Remove a thread from the global threads table.
992
993    IN:
994       thread............the thread to remove
995
996    PRE-CONDITION:
997       The caller must hold the threadlistlock!
998
999 ******************************************************************************/
1000
1001 static void threads_table_remove(threadobject *thread)
1002 {
1003         s4 index;
1004
1005         index = thread->index;
1006
1007         /* put the index into the freelist */
1008
1009         threads_table.table[index] = threads_table.table[0];
1010         threads_table.table[0].nextfree = index;
1011
1012         /* delete the index in the threadobject to discover bugs */
1013 #if !defined(NDEBUG)
1014         thread->index = 0;
1015 #endif
1016 }
1017
1018
1019 /* threads_startup_thread ******************************************************
1020
1021    Thread startup function called by pthread_create.
1022
1023    Thread which have a startup.function != NULL are marked as internal
1024    threads. All other threads are threated as normal Java threads.
1025
1026    NOTE: This function is not called directly by pthread_create. The Boehm GC
1027          inserts its own GC_start_routine in between, which then calls
1028                  threads_startup.
1029
1030    IN:
1031       t............the argument passed to pthread_create, ie. a pointer to
1032                        a startupinfo struct. CAUTION: When the `psem` semaphore
1033                                    is posted, the startupinfo struct becomes invalid! (It
1034                                    is allocated on the stack of threads_start_thread.)
1035
1036 ******************************************************************************/
1037
1038 static void *threads_startup_thread(void *t)
1039 {
1040         startupinfo        *startup;
1041         threadobject       *thread;
1042 #if defined(WITH_CLASSPATH_GNU)
1043         java_lang_VMThread *vmt;
1044 #endif
1045         sem_t              *psem;
1046         threadobject       *tnext;
1047         classinfo          *c;
1048         methodinfo         *m;
1049         java_objectheader  *o;
1050         functionptr         function;
1051
1052 #if defined(ENABLE_INTRP)
1053         u1 *intrp_thread_stack;
1054
1055         /* create interpreter stack */
1056
1057         if (opt_intrp) {
1058                 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1059                 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1060         }
1061         else
1062                 intrp_thread_stack = NULL;
1063 #endif
1064
1065         /* get passed startupinfo structure and the values in there */
1066
1067         startup = t;
1068         t = NULL; /* make sure it's not used wrongly */
1069
1070         thread   = startup->thread;
1071         function = startup->function;
1072         psem     = startup->psem;
1073
1074         /* Seems like we've encountered a situation where thread->tid was not set by
1075          * pthread_create. We alleviate this problem by waiting for pthread_create
1076          * to return. */
1077         threads_sem_wait(startup->psem_first);
1078
1079         /* set the thread object */
1080
1081 #if defined(__DARWIN__)
1082         thread->mach_thread = mach_thread_self();
1083 #endif
1084
1085         threads_init_threadobject(thread);
1086         threads_set_current_threadobject(thread);
1087
1088         /* thread is running */
1089
1090         thread->state = THREAD_STATE_RUNNABLE;
1091
1092         /* insert the thread into the threadlist and the threads table */
1093
1094         pthread_mutex_lock(&threadlistlock);
1095
1096         thread->prev = mainthreadobj;
1097         thread->next = tnext = mainthreadobj->next;
1098         mainthreadobj->next = thread;
1099         tnext->prev = thread;
1100
1101         threads_table_add(thread);
1102
1103         pthread_mutex_unlock(&threadlistlock);
1104
1105         /* init data structures of this thread */
1106
1107         lock_init_execution_env(thread);
1108
1109         /* tell threads_startup_thread that we registered ourselves */
1110         /* CAUTION: *startup becomes invalid with this!             */
1111
1112         startup = NULL;
1113         threads_sem_post(psem);
1114
1115         /* set our priority */
1116
1117         threads_set_thread_priority(thread->tid, thread->object->priority);
1118
1119 #if defined(ENABLE_INTRP)
1120         /* set interpreter stack */
1121
1122         if (opt_intrp)
1123                 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1124 #endif
1125
1126 #if defined(ENABLE_JVMTI)
1127         /* fire thread start event */
1128
1129         if (jvmti) 
1130                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1131 #endif
1132
1133         /* find and run the Thread.run()V method if no other function was passed */
1134
1135         if (function == NULL) {
1136                 /* this is a normal Java thread */
1137
1138                 thread->flags |= THREAD_FLAG_JAVA;
1139
1140 #if defined(WITH_CLASSPATH_GNU)
1141                 /* We need to start the run method of
1142                    java.lang.VMThread. Since this is a final class, we can use
1143                    the class object directly. */
1144
1145                 c   = class_java_lang_VMThread;
1146 #elif defined(WITH_CLASSPATH_CLDC1_1)
1147                 c   = thread->object->header.vftbl->class;
1148 #endif
1149
1150                 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1151
1152                 if (m == NULL)
1153                         vm_abort("threads_startup_thread: run() method not found in class");
1154
1155                 /* set ThreadMXBean variables */
1156
1157                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1158                 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1159
1160                 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1161                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1162                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1163                                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1164
1165 #if defined(WITH_CLASSPATH_GNU)
1166                 /* we need to start the run method of java.lang.VMThread */
1167
1168                 vmt = (java_lang_VMThread *) thread->object->vmThread;
1169                 o   = (java_objectheader *) vmt;
1170
1171 #elif defined(WITH_CLASSPATH_CLDC1_1)
1172                 o   = (java_objectheader *) thread->object;
1173 #endif
1174
1175                 /* run the thread */
1176
1177                 (void) vm_call_method(m, o);
1178         }
1179         else {
1180                 /* this is an internal thread */
1181
1182                 thread->flags |= THREAD_FLAG_INTERNAL;
1183
1184                 /* set ThreadMXBean variables */
1185
1186                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1187                 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1188
1189                 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1190                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1191                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1192                                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1193
1194                 /* call passed function, e.g. finalizer_thread */
1195
1196                 (function)();
1197         }
1198
1199 #if defined(ENABLE_JVMTI)
1200         /* fire thread end event */
1201
1202         if (jvmti)
1203                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1204 #endif
1205
1206         if (!threads_detach_thread(thread))
1207                 vm_abort("threads_startup_thread: threads_detach_thread failed");
1208
1209         /* set ThreadMXBean variables */
1210
1211         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1212
1213         return NULL;
1214 }
1215
1216
1217 /* threads_start_thread ********************************************************
1218
1219    Start a thread in the JVM. Both (vm internal and java) thread objects exist.
1220
1221    IN:
1222       thread.......the thread object
1223           function.....function to run in the new thread. NULL means that the
1224                        "run" method of the object `t` should be called
1225
1226 ******************************************************************************/
1227
1228 void threads_start_thread(threadobject *thread, functionptr function)
1229 {
1230         sem_t          sem;
1231         sem_t          sem_first;
1232         pthread_attr_t attr;
1233         startupinfo    startup;
1234
1235         /* fill startupinfo structure passed by pthread_create to
1236          * threads_startup_thread */
1237
1238         startup.thread     = thread;
1239         startup.function   = function;       /* maybe we don't call Thread.run()V */
1240         startup.psem       = &sem;
1241         startup.psem_first = &sem_first;
1242
1243         threads_sem_init(&sem, 0, 0);
1244         threads_sem_init(&sem_first, 0, 0);
1245
1246         /* initialize thread attribute object */
1247
1248         if (pthread_attr_init(&attr))
1249                 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1250
1251         /* initialize thread stacksize */
1252
1253         if (pthread_attr_setstacksize(&attr, opt_stacksize))
1254                 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1255
1256         /* create the thread */
1257
1258         if (pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup))
1259                 vm_abort("pthread_create failed: %s", strerror(errno));
1260
1261         /* signal that pthread_create has returned, so thread->tid is valid */
1262
1263         threads_sem_post(&sem_first);
1264
1265         /* wait here until the thread has entered itself into the thread list */
1266
1267         threads_sem_wait(&sem);
1268
1269         /* cleanup */
1270
1271         sem_destroy(&sem);
1272         sem_destroy(&sem_first);
1273 }
1274
1275
1276 /* threads_set_thread_priority *************************************************
1277
1278    Set the priority of the given thread.
1279
1280    IN:
1281       tid..........thread id
1282           priority.....priority to set
1283
1284 ******************************************************************************/
1285
1286 void threads_set_thread_priority(pthread_t tid, int priority)
1287 {
1288         struct sched_param schedp;
1289         int policy;
1290
1291         pthread_getschedparam(tid, &policy, &schedp);
1292         schedp.sched_priority = priority;
1293         pthread_setschedparam(tid, policy, &schedp);
1294 }
1295
1296
1297 /* threads_attach_current_thread ***********************************************
1298
1299    Attaches the current thread to the VM.  Used in JNI.
1300
1301 *******************************************************************************/
1302
1303 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1304 {
1305         threadobject          *thread;
1306         utf                   *u;
1307         java_objectheader     *s;
1308         java_objectheader     *o;
1309         java_lang_Thread      *t;
1310
1311 #if defined(ENABLE_JAVASE)
1312         java_lang_ThreadGroup *group;
1313         methodinfo            *m;
1314 #endif
1315
1316 #if defined(WITH_CLASSPATH_GNU)
1317         java_lang_VMThread    *vmt;
1318 #endif
1319
1320         /* create a vm internal thread object */
1321
1322         thread = NEW(threadobject);
1323
1324 #if defined(ENABLE_STATISTICS)
1325         if (opt_stat)
1326                 size_threadobject += sizeof(threadobject);
1327 #endif
1328
1329         if (thread == NULL)
1330                 return false;
1331
1332         /* create a java.lang.Thread object */
1333
1334         t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1335
1336         if (t == NULL)
1337                 return false;
1338
1339         thread->object = t;
1340
1341         threads_init_threadobject(thread);
1342         threads_set_current_threadobject(thread);
1343         lock_init_execution_env(thread);
1344
1345         /* thread is running */
1346
1347         thread->state = THREAD_STATE_RUNNABLE;
1348
1349         /* insert the thread into the threadlist and the threads table */
1350
1351         pthread_mutex_lock(&threadlistlock);
1352
1353         thread->prev        = mainthreadobj;
1354         thread->next        = mainthreadobj->next;
1355         mainthreadobj->next = thread;
1356         thread->next->prev  = thread;
1357
1358         threads_table_add(thread);
1359
1360         pthread_mutex_unlock(&threadlistlock);
1361
1362         /* mark thread as Java thread */
1363
1364         thread->flags = THREAD_FLAG_JAVA;
1365
1366         if (isdaemon)
1367                 thread->flags |= THREAD_FLAG_DAEMON;
1368
1369 #if defined(ENABLE_INTRP)
1370         /* create interpreter stack */
1371
1372         if (opt_intrp) {
1373                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1374                 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1375         }
1376 #endif
1377
1378 #if defined(WITH_CLASSPATH_GNU)
1379         /* create a java.lang.VMThread object */
1380
1381         vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1382
1383         if (vmt == NULL)
1384                 return false;
1385
1386         /* set the thread */
1387
1388         vmt->thread = t;
1389         vmt->vmdata = (java_lang_Object *) thread;
1390 #elif defined(WITH_CLASSPATH_CLDC1_1)
1391         t->vm_thread = (java_lang_Object *) thread;
1392 #endif
1393
1394         if (vm_aargs != NULL) {
1395                 u     = utf_new_char(vm_aargs->name);
1396 #if defined(ENABLE_JAVASE)
1397                 group = (java_lang_ThreadGroup *) vm_aargs->group;
1398 #endif
1399         }
1400         else {
1401                 u     = utf_null;
1402 #if defined(ENABLE_JAVASE)
1403                 group = mainthreadobj->object->group;
1404 #endif
1405         }
1406
1407         /* the the thread name */
1408
1409         s = javastring_new(u);
1410
1411         /* for convenience */
1412
1413         o = (java_objectheader *) thread->object;
1414
1415 #if defined(WITH_CLASSPATH_GNU)
1416         (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1417                                                   isdaemon);
1418 #elif defined(WITH_CLASSPATH_CLDC1_1)
1419         (void) vm_call_method(method_thread_init, o, s);
1420 #endif
1421
1422         if (*exceptionptr)
1423                 return false;
1424
1425 #if defined(ENABLE_JAVASE)
1426         /* store the thread group in the object */
1427
1428         thread->object->group = group;
1429
1430         /* add thread to given thread-group */
1431
1432         m = class_resolveclassmethod(group->header.vftbl->class,
1433                                                                  utf_addThread,
1434                                                                  utf_java_lang_Thread__V,
1435                                                                  class_java_lang_ThreadGroup,
1436                                                                  true);
1437
1438         o = (java_objectheader *) group;
1439
1440         (void) vm_call_method(m, o, t);
1441
1442         if (*exceptionptr)
1443                 return false;
1444 #endif
1445
1446         return true;
1447 }
1448
1449
1450 /* threads_detach_thread *******************************************************
1451
1452    Detaches the passed thread from the VM.  Used in JNI.
1453
1454 *******************************************************************************/
1455
1456 bool threads_detach_thread(threadobject *thread)
1457 {
1458 #if defined(ENABLE_JAVASE)
1459         java_lang_ThreadGroup *group;
1460         methodinfo            *m;
1461         java_objectheader     *o;
1462         java_lang_Thread      *t;
1463 #endif
1464
1465         /* Allow lock record pools to be used by other threads. They
1466            cannot be deleted so we'd better not waste them. */
1467
1468         /* XXX We have to find a new way to free lock records */
1469         /*     with the new locking algorithm.                */
1470         /* lock_record_free_pools(thread->ee.lockrecordpools); */
1471
1472         /* XXX implement uncaught exception stuff (like JamVM does) */
1473
1474 #if defined(ENABLE_JAVASE)
1475         /* remove thread from the thread group */
1476
1477         group = thread->object->group;
1478
1479         /* XXX TWISTI: should all threads be in a ThreadGroup? */
1480
1481         if (group != NULL) {
1482                 m = class_resolveclassmethod(group->header.vftbl->class,
1483                                                                          utf_removeThread,
1484                                                                          utf_java_lang_Thread__V,
1485                                                                          class_java_lang_ThreadGroup,
1486                                                                          true);
1487
1488                 if (m == NULL)
1489                         return false;
1490
1491                 o = (java_objectheader *) group;
1492                 t = thread->object;
1493
1494                 (void) vm_call_method(m, o, t);
1495
1496                 if (*exceptionptr)
1497                         return false;
1498         }
1499 #endif
1500
1501         /* thread is terminated */
1502
1503         thread->state = THREAD_STATE_TERMINATED;
1504
1505         /* lock thread list */
1506
1507         pthread_mutex_lock(&threadlistlock);
1508
1509         /* remove thread from thread list and threads table */
1510
1511         thread->next->prev = thread->prev;
1512         thread->prev->next = thread->next;
1513
1514         threads_table_remove(thread);
1515
1516         /* unlock thread list */
1517
1518         pthread_mutex_unlock(&threadlistlock);
1519
1520         /* signal that this thread has finished */
1521
1522         pthread_mutex_lock(&mutex_join);
1523         pthread_cond_signal(&cond_join);
1524         pthread_mutex_unlock(&mutex_join);
1525
1526         /* free the vm internal thread object */
1527
1528         FREE(thread, threadobject);
1529
1530 #if defined(ENABLE_STATISTICS)
1531         if (opt_stat)
1532                 size_threadobject -= sizeof(threadobject);
1533 #endif
1534
1535         return true;
1536 }
1537
1538
1539 /* threads_suspend_thread ******************************************************
1540
1541    Suspend the passed thread. Execution stops until the thread
1542    is explicitly resumend again.
1543
1544    IN:
1545      reason.....Reason for suspending this thread.
1546
1547 *******************************************************************************/
1548
1549 bool threads_suspend_thread(threadobject *thread, s4 reason)
1550 {
1551         /* acquire the suspendmutex */
1552         pthread_mutex_lock(&(thread->suspendmutex));
1553
1554         if (thread->suspended) {
1555                 pthread_mutex_unlock(&(thread->suspendmutex));
1556                 return false;
1557         }
1558
1559         /* set the reason for the suspension */
1560         thread->suspend_reason = reason;
1561
1562         /* send the suspend signal to the thread */
1563         assert(thread != THREADOBJECT);
1564         pthread_kill(thread->tid, SIGUSR1);
1565
1566         /* REMEMBER: do not release the suspendmutex, this is done
1567            by the thread itself in threads_suspend_ack().  */
1568
1569         return true;
1570 }
1571
1572
1573 /* threads_suspend_ack *********************************************************
1574
1575    Acknowledges the suspension of the current thread.
1576
1577    IN:
1578      pc.....The PC where the thread suspended its execution.
1579      sp.....The SP before the thread suspended its execution.
1580
1581 *******************************************************************************/
1582
1583 void threads_suspend_ack(u1* pc, u1* sp)
1584 {
1585         threadobject *thread;
1586
1587         thread = THREADOBJECT;
1588
1589         assert(thread->suspend_reason != 0);
1590
1591         /* TODO: remember dump memory size */
1592
1593 #if defined(ENABLE_GC_CACAO)
1594         /* inform the GC about the suspension */
1595         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1596
1597                 /* check if the GC wants to leave the thread running */
1598                 if (!gc_suspend(thread, pc, sp)) {
1599
1600                         /* REMEMBER: we do not unlock the suspendmutex because the thread
1601                            will suspend itself again at a later time */
1602                         return;
1603
1604                 }
1605         }
1606 #endif
1607
1608         /* mark this thread as suspended and remember the PC */
1609         thread->pc        = pc;
1610         thread->suspended = true;
1611
1612         /* if we are stopping the world, we should send a global ack */
1613         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1614                 threads_sem_post(&suspend_ack);
1615         }
1616
1617         /* release the suspension mutex and wait till we are resumed */
1618         pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1619
1620         /* TODO: free dump memory */
1621
1622         /* release the suspendmutex */
1623         pthread_mutex_unlock(&(thread->suspendmutex));
1624 }
1625
1626
1627 /* threads_resume_thread *******************************************************
1628
1629    Resumes the execution of the passed thread.
1630
1631 *******************************************************************************/
1632
1633 bool threads_resume_thread(threadobject *thread)
1634 {
1635         /* acquire the suspendmutex */
1636         pthread_mutex_lock(&(thread->suspendmutex));
1637
1638         if (!thread->suspended) {
1639                 pthread_mutex_unlock(&(thread->suspendmutex));
1640                 return false;
1641         }
1642
1643         thread->suspended = false;
1644
1645         /* tell everyone that the thread should resume */
1646         assert(thread != THREADOBJECT);
1647         pthread_cond_broadcast(&(thread->suspendcond));
1648
1649         /* release the suspendmutex */
1650         pthread_mutex_unlock(&(thread->suspendmutex));
1651
1652         return true;
1653 }
1654
1655 /* threads_find_non_daemon_thread **********************************************
1656
1657    Helper function used by threads_join_all_threads for finding
1658    non-daemon threads that are still running.
1659
1660 *******************************************************************************/
1661
1662 static threadobject *threads_find_non_daemon_thread(void)
1663 {
1664         threadobject *thread;
1665
1666         /* lock the thread list */
1667
1668         pthread_mutex_lock(&threadlistlock);
1669
1670         /* iterate over all threads */
1671
1672         thread = mainthreadobj->next;
1673
1674         while (thread != mainthreadobj) {
1675                 if (!(thread->flags & THREAD_FLAG_DAEMON)) {
1676                         /* unlock thread list */
1677
1678                         pthread_mutex_unlock(&threadlistlock);
1679
1680                         return thread;
1681                 }
1682
1683                 thread = thread->next;
1684         }
1685
1686         /* unlock thread list */
1687
1688         pthread_mutex_unlock(&threadlistlock);
1689
1690         return NULL;
1691 }
1692
1693
1694 /* threads_join_all_threads ****************************************************
1695
1696    Join all non-daemon threads.
1697
1698 *******************************************************************************/
1699
1700 void threads_join_all_threads(void)
1701 {
1702         threadobject *thread;
1703
1704         /* get current thread */
1705
1706         thread = THREADOBJECT;
1707
1708         /* this thread is waiting for all non-daemon threads to exit */
1709
1710         thread->state = THREAD_STATE_WAITING;
1711
1712         /* enter join mutex */
1713
1714         pthread_mutex_lock(&mutex_join);
1715
1716         /* wait for condition as long as we have non-daemon threads */
1717
1718         while (threads_find_non_daemon_thread() != NULL)
1719                 pthread_cond_wait(&cond_join, &mutex_join);
1720
1721         /* leave join mutex */
1722
1723         pthread_mutex_unlock(&mutex_join);
1724 }
1725
1726
1727 /* threads_timespec_earlier ****************************************************
1728
1729    Return true if timespec tv1 is earlier than timespec tv2.
1730
1731    IN:
1732       tv1..........first timespec
1733           tv2..........second timespec
1734
1735    RETURN VALUE:
1736       true, if the first timespec is earlier
1737
1738 *******************************************************************************/
1739
1740 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1741                                                                                         const struct timespec *tv2)
1742 {
1743         return (tv1->tv_sec < tv2->tv_sec)
1744                                 ||
1745                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1746 }
1747
1748
1749 /* threads_current_time_is_earlier_than ****************************************
1750
1751    Check if the current time is earlier than the given timespec.
1752
1753    IN:
1754       tv...........the timespec to compare against
1755
1756    RETURN VALUE:
1757       true, if the current time is earlier
1758
1759 *******************************************************************************/
1760
1761 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1762 {
1763         struct timeval tvnow;
1764         struct timespec tsnow;
1765
1766         /* get current time */
1767
1768         if (gettimeofday(&tvnow, NULL) != 0)
1769                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1770
1771         /* convert it to a timespec */
1772
1773         tsnow.tv_sec = tvnow.tv_sec;
1774         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1775
1776         /* compare current time with the given timespec */
1777
1778         return threads_timespec_earlier(&tsnow, tv);
1779 }
1780
1781
1782 /* threads_wait_with_timeout ***************************************************
1783
1784    Wait until the given point in time on a monitor until either
1785    we are notified, we are interrupted, or the time is up.
1786
1787    IN:
1788       t............the current thread
1789           wakeupTime...absolute (latest) wakeup time
1790                            If both tv_sec and tv_nsec are zero, this function
1791                                            waits for an unlimited amount of time.
1792
1793    RETURN VALUE:
1794       true.........if the wait has been interrupted,
1795           false........if the wait was ended by notification or timeout
1796
1797 *******************************************************************************/
1798
1799 static bool threads_wait_with_timeout(threadobject *thread,
1800                                                                           struct timespec *wakeupTime)
1801 {
1802         bool wasinterrupted;
1803
1804         /* acquire the waitmutex */
1805
1806         pthread_mutex_lock(&thread->waitmutex);
1807
1808         /* mark us as sleeping */
1809
1810         thread->sleeping = true;
1811
1812         /* wait on waitcond */
1813
1814         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1815                 /* with timeout */
1816                 while (!thread->interrupted && !thread->signaled
1817                            && threads_current_time_is_earlier_than(wakeupTime))
1818                 {
1819                         thread->state = THREAD_STATE_TIMED_WAITING;
1820
1821                         pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1822                                                                    wakeupTime);
1823
1824                         thread->state = THREAD_STATE_RUNNABLE;
1825                 }
1826         }
1827         else {
1828                 /* no timeout */
1829                 while (!thread->interrupted && !thread->signaled) {
1830                         thread->state = THREAD_STATE_WAITING;
1831
1832                         pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1833
1834                         thread->state = THREAD_STATE_RUNNABLE;
1835                 }
1836         }
1837
1838         /* check if we were interrupted */
1839
1840         wasinterrupted = thread->interrupted;
1841
1842         /* reset all flags */
1843
1844         thread->interrupted = false;
1845         thread->signaled    = false;
1846         thread->sleeping    = false;
1847
1848         /* release the waitmutex */
1849
1850         pthread_mutex_unlock(&thread->waitmutex);
1851
1852         return wasinterrupted;
1853 }
1854
1855
1856 /* threads_wait_with_timeout_relative ******************************************
1857
1858    Wait for the given maximum amount of time on a monitor until either
1859    we are notified, we are interrupted, or the time is up.
1860
1861    IN:
1862       t............the current thread
1863           millis.......milliseconds to wait
1864           nanos........nanoseconds to wait
1865
1866    RETURN VALUE:
1867       true.........if the wait has been interrupted,
1868           false........if the wait was ended by notification or timeout
1869
1870 *******************************************************************************/
1871
1872 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1873                                                                                 s4 nanos)
1874 {
1875         struct timespec wakeupTime;
1876
1877         /* calculate the the (latest) wakeup time */
1878
1879         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1880
1881         /* wait */
1882
1883         return threads_wait_with_timeout(thread, &wakeupTime);
1884 }
1885
1886
1887 /* threads_calc_absolute_time **************************************************
1888
1889    Calculate the absolute point in time a given number of ms and ns from now.
1890
1891    IN:
1892       millis............milliseconds from now
1893           nanos.............nanoseconds from now
1894
1895    OUT:
1896       *tm...............receives the timespec of the absolute point in time
1897
1898 *******************************************************************************/
1899
1900 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1901 {
1902         if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1903                 struct timeval tv;
1904                 long nsec;
1905                 gettimeofday(&tv, NULL);
1906                 tv.tv_sec += millis / 1000;
1907                 millis %= 1000;
1908                 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1909                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1910                 tm->tv_nsec = nsec % 1000000000;
1911         }
1912         else {
1913                 tm->tv_sec = 0;
1914                 tm->tv_nsec = 0;
1915         }
1916 }
1917
1918
1919 /* threads_thread_interrupt ****************************************************
1920
1921    Interrupt the given thread.
1922
1923    The thread gets the "waitcond" signal and 
1924    its interrupted flag is set to true.
1925
1926    IN:
1927       thread............the thread to interrupt
1928
1929 *******************************************************************************/
1930
1931 void threads_thread_interrupt(threadobject *thread)
1932 {
1933         /* Signal the thread a "waitcond" and tell it that it has been
1934            interrupted. */
1935
1936         pthread_mutex_lock(&thread->waitmutex);
1937
1938         /* Interrupt blocking system call using a signal. */
1939
1940         pthread_kill(thread->tid, SIGHUP);
1941
1942         if (thread->sleeping)
1943                 pthread_cond_signal(&thread->waitcond);
1944
1945         thread->interrupted = true;
1946
1947         pthread_mutex_unlock(&thread->waitmutex);
1948 }
1949
1950
1951 /* threads_check_if_interrupted_and_reset **************************************
1952
1953    Check if the current thread has been interrupted and reset the
1954    interruption flag.
1955
1956    RETURN VALUE:
1957       true, if the current thread had been interrupted
1958
1959 *******************************************************************************/
1960
1961 bool threads_check_if_interrupted_and_reset(void)
1962 {
1963         threadobject *thread;
1964         bool intr;
1965
1966         thread = THREADOBJECT;
1967
1968         /* get interrupted flag */
1969
1970         intr = thread->interrupted;
1971
1972         /* reset interrupted flag */
1973
1974         thread->interrupted = false;
1975
1976         return intr;
1977 }
1978
1979
1980 /* threads_thread_has_been_interrupted *****************************************
1981
1982    Check if the given thread has been interrupted
1983
1984    IN:
1985       t............the thread to check
1986
1987    RETURN VALUE:
1988       true, if the given thread had been interrupted
1989
1990 *******************************************************************************/
1991
1992 bool threads_thread_has_been_interrupted(threadobject *thread)
1993 {
1994         return thread->interrupted;
1995 }
1996
1997
1998 /* threads_sleep ***************************************************************
1999
2000    Sleep the current thread for the specified amount of time.
2001
2002 *******************************************************************************/
2003
2004 void threads_sleep(s8 millis, s4 nanos)
2005 {
2006         threadobject    *thread;
2007         struct timespec  wakeupTime;
2008         bool             wasinterrupted;
2009
2010         thread = THREADOBJECT;
2011
2012         threads_calc_absolute_time(&wakeupTime, millis, nanos);
2013
2014         wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
2015
2016         if (wasinterrupted)
2017                 exceptions_throw_interruptedexception();
2018 }
2019
2020
2021 /* threads_yield ***************************************************************
2022
2023    Yield to the scheduler.
2024
2025 *******************************************************************************/
2026
2027 void threads_yield(void)
2028 {
2029         sched_yield();
2030 }
2031
2032
2033 /* threads_table_dump *********************************************************
2034
2035    Dump the threads table for debugging purposes.
2036
2037    IN:
2038       file..............stream to write to
2039
2040 ******************************************************************************/
2041
2042 #if !defined(NDEBUG) && 0
2043 static void threads_table_dump(FILE *file)
2044 {
2045         s4 i;
2046         s4 size;
2047         ptrint index;
2048
2049         pthread_mutex_lock(&threadlistlock);
2050
2051         size = threads_table.size;
2052
2053         fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
2054
2055         for (i=0; i<size; ++i) {
2056                 index = threads_table.table[i].nextfree;
2057
2058                 fprintf(file, "%4d: ", i);
2059
2060                 if (index < size) {
2061                         fprintf(file, "free, nextfree = %d\n", (int) index);
2062                 }
2063                 else {
2064                         fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
2065                 }
2066         }
2067
2068         fprintf(file, "======== END OF THREADS TABLE ========\n");
2069
2070         pthread_mutex_unlock(&threadlistlock);
2071 }
2072 #endif
2073
2074 /*
2075  * These are local overrides for various environment variables in Emacs.
2076  * Please do not remove this and leave it at the end of the file, where
2077  * Emacs will automagically detect them.
2078  * ---------------------------------------------------------------------
2079  * Local variables:
2080  * mode: c
2081  * indent-tabs-mode: t
2082  * c-basic-offset: 4
2083  * tab-width: 4
2084  * End:
2085  * vim:noexpandtab:sw=4:ts=4:
2086  */