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