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