* src/threads/native/threads.c, src/threads/native/threads.c: Further
[cacao.git] / src / threads / native / threads.c
1 /* src/threads/native/threads.c - native threads support
2
3    Copyright (C) 1996-2005, 2006 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    Contact: cacao@cacaojvm.org
26
27    Authors: Stefan Ring
28
29    Changes: Christian Thalinger
30                         Edwin Steiner
31
32    $Id: threads.c 4909 2006-05-13 23:10:21Z edwin $
33
34 */
35
36
37 #include "config.h"
38
39 /* XXX cleanup these includes */
40
41 #include <stdlib.h>
42 #include <string.h>
43 #include <assert.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46 #include <signal.h>
47 #include <sys/time.h>
48 #include <time.h>
49 #include <errno.h>
50
51 #include <pthread.h>
52 #include <semaphore.h>
53
54 #include "vm/types.h"
55
56 #include "arch.h"
57
58 #if !defined(USE_MD_THREAD_STUFF)
59 #include "machine-instr.h"
60 #else
61 #include "threads/native/generic-primitives.h"
62 #endif
63
64 #include "mm/boehm.h"
65 #include "mm/memory.h"
66 #include "native/native.h"
67 #include "native/include/java_lang_Object.h"
68 #include "native/include/java_lang_Throwable.h"
69 #include "native/include/java_lang_Thread.h"
70 #include "native/include/java_lang_ThreadGroup.h"
71 #include "native/include/java_lang_VMThread.h"
72 #include "threads/native/threads.h"
73 #include "toolbox/avl.h"
74 #include "toolbox/logging.h"
75 #include "vm/builtin.h"
76 #include "vm/exceptions.h"
77 #include "vm/global.h"
78 #include "vm/loader.h"
79 #include "vm/options.h"
80 #include "vm/stringlocal.h"
81 #include "vm/vm.h"
82 #include "vm/jit/asmpart.h"
83
84 #if !defined(__DARWIN__)
85 #if defined(__LINUX__)
86 #define GC_LINUX_THREADS
87 #elif defined(__MIPS__)
88 #define GC_IRIX_THREADS
89 #endif
90 #include "boehm-gc/include/gc.h"
91 #endif
92
93
94 /* internally used constants **************************************************/
95
96 /* CAUTION: Do not change these values. Boehm GC code depends on them.        */
97 #define STOPWORLD_FROM_GC               1
98 #define STOPWORLD_FROM_CLASS_NUMBERING  2
99
100
101 /* startupinfo *****************************************************************
102
103    Struct used to pass info from threads_start_thread to 
104    threads_startup_thread.
105
106 ******************************************************************************/
107
108 typedef struct {
109         threadobject *thread;      /* threadobject for this thread             */
110         functionptr   function;    /* function to run in the new thread        */
111         sem_t        *psem;        /* signals when thread has been entered     */
112                                    /* in the thread list                       */
113         sem_t        *psem_first;  /* signals when pthread_create has returned */
114 } startupinfo;
115
116
117 /* prototypes *****************************************************************/
118
119 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
120
121
122 /******************************************************************************/
123 /* GLOBAL VARIABLES                                                           */
124 /******************************************************************************/
125
126 /* the main thread                                                            */
127 threadobject *mainthreadobj;
128
129 /* the thread object of the current thread                                    */
130 /* This is either a thread-local variable defined with __thread, or           */
131 /* a thread-specific value stored with key threads_current_threadobject_key.  */
132 #if defined(HAVE___THREAD)
133 __thread threadobject *threads_current_threadobject;
134 #else
135 pthread_key_t threads_current_threadobject_key;
136 #endif
137
138 /* global compiler mutex                                                      */
139 static pthread_mutex_rec_t compiler_mutex;
140
141 /* global mutex for changing the thread list                                  */
142 static pthread_mutex_t threadlistlock;
143
144 /* global mutex for stop-the-world                                            */
145 static pthread_mutex_t stopworldlock;
146
147 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is     */
148 /* being stopped                                                              */
149 static volatile int stopworldwhere;
150
151 /* semaphore used for acknowleding thread suspension                          */
152 static sem_t suspend_ack;
153 #if defined(__MIPS__)
154 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
155 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
156 #endif
157
158 static pthread_attr_t threadattr;
159
160 /* mutexes used by the fake atomic instructions                               */
161 #if defined(USE_MD_THREAD_STUFF)
162 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
163 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
164 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
165 #endif
166
167
168 /******************************************************************************/
169 /* Recursive Mutex Implementation for Darwin                                  */
170 /******************************************************************************/
171
172 #if defined(MUTEXSIM)
173
174 /* We need this for older MacOSX (10.1.x) */
175
176 void pthread_mutex_init_rec(pthread_mutex_rec_t *m)
177 {
178         pthread_mutex_init(&m->mutex, NULL);
179         m->count = 0;
180 }
181
182 void pthread_mutex_destroy_rec(pthread_mutex_rec_t *m)
183 {
184         pthread_mutex_destroy(&m->mutex);
185 }
186
187 void pthread_mutex_lock_rec(pthread_mutex_rec_t *m)
188 {
189         for (;;) {
190                 if (!m->count)
191                 {
192                         pthread_mutex_lock(&m->mutex);
193                         m->owner = pthread_self();
194                         m->count++;
195                         break;
196                 }
197                 else {
198                         if (m->owner != pthread_self()) {
199                                 pthread_mutex_lock(&m->mutex);
200                         }
201                         else {
202                                 m->count++;
203                                 break;
204                         }
205                 }
206         }
207 }
208
209 void pthread_mutex_unlock_rec(pthread_mutex_rec_t *m)
210 {
211         if (!--m->count)
212                 pthread_mutex_unlock(&m->mutex);
213 }
214
215 #endif /* defined(MUTEXSIM) */
216
217
218 /* threads_sem_init ************************************************************
219  
220    Initialize a semaphore. Checks against errors and interruptions.
221
222    IN:
223        sem..............the semaphore to initialize
224            shared...........true if this semaphore will be shared between processes
225            value............the initial value for the semaphore
226    
227 *******************************************************************************/
228
229 void threads_sem_init(sem_t *sem, bool shared, int value)
230 {
231         int r;
232
233         assert(sem);
234
235         do {
236                 r = sem_init(sem, shared, value);
237                 if (r == 0)
238                         return;
239         } while (errno == EINTR);
240
241         fprintf(stderr,"error: sem_init returned unexpected error %d: %s\n",
242                         errno, strerror(errno));
243         abort();
244 }
245
246
247 /* threads_sem_wait ************************************************************
248  
249    Wait for a semaphore, non-interruptible.
250
251    IMPORTANT: Always use this function instead of `sem_wait` directly, as
252               `sem_wait` may be interrupted by signals!
253   
254    IN:
255        sem..............the semaphore to wait on
256    
257 *******************************************************************************/
258
259 void threads_sem_wait(sem_t *sem)
260 {
261         int r;
262
263         assert(sem);
264
265         do {
266                 r = sem_wait(sem);
267                 if (r == 0)
268                         return;
269         } while (errno == EINTR);
270
271         fprintf(stderr,"error: sem_wait returned unexpected error %d: %s\n",
272                         errno, strerror(errno));
273         abort();
274 }
275
276
277 /* threads_sem_post ************************************************************
278  
279    Increase the count of a semaphore. Checks for errors.
280
281    IN:
282        sem..............the semaphore to increase the count of
283    
284 *******************************************************************************/
285
286 void threads_sem_post(sem_t *sem)
287 {
288         int r;
289
290         assert(sem);
291
292         /* unlike sem_wait, sem_post is not interruptible */
293
294         r = sem_post(sem);
295         if (r == 0)
296                 return;
297
298         fprintf(stderr,"error: sem_post returned unexpected error %d: %s\n",
299                         errno, strerror(errno));
300         abort();
301 }
302
303
304 /* threads_set_thread_priority *************************************************
305
306    Set the priority of the given thread.
307
308    IN:
309       tid..........thread id
310           priority.....priority to set
311
312 ******************************************************************************/
313
314 static void threads_set_thread_priority(pthread_t tid, int priority)
315 {
316         struct sched_param schedp;
317         int policy;
318
319         pthread_getschedparam(tid, &policy, &schedp);
320         schedp.sched_priority = priority;
321         pthread_setschedparam(tid, policy, &schedp);
322 }
323
324
325 /* compiler_lock ***************************************************************
326
327    Enter the compiler lock.
328
329 ******************************************************************************/
330
331 void compiler_lock(void)
332 {
333         pthread_mutex_lock_rec(&compiler_mutex);
334 }
335
336
337 /* compiler_unlock *************************************************************
338
339    Release the compiler lock.
340
341 ******************************************************************************/
342
343 void compiler_unlock(void)
344 {
345         pthread_mutex_unlock_rec(&compiler_mutex);
346 }
347
348
349 /* lock_stopworld **************************************************************
350
351    Enter the stopworld lock, specifying why the world shall be stopped.
352
353    IN:
354       where........ STOPWORLD_FROM_GC              (1) from within GC
355                     STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
356
357 ******************************************************************************/
358
359 void lock_stopworld(int where)
360 {
361         pthread_mutex_lock(&stopworldlock);
362         stopworldwhere = where;
363 }
364
365
366 /* unlock_stopworld ************************************************************
367
368    Release the stopworld lock.
369
370 ******************************************************************************/
371
372 void unlock_stopworld(void)
373 {
374         stopworldwhere = 0;
375         pthread_mutex_unlock(&stopworldlock);
376 }
377
378 #if !defined(__DARWIN__)
379 /* Caller must hold threadlistlock */
380 static int threads_cast_sendsignals(int sig, int count)
381 {
382         /* Count threads */
383         threadobject *tobj = mainthreadobj;
384         nativethread *infoself = THREADINFO;
385
386         if (count == 0) {
387                 do {
388                         count++;
389                         tobj = tobj->info.next;
390                 } while (tobj != mainthreadobj);
391         }
392
393         do {
394                 nativethread *info = &tobj->info;
395                 if (info != infoself)
396                         pthread_kill(info->tid, sig);
397                 tobj = tobj->info.next;
398         } while (tobj != mainthreadobj);
399
400         return count-1;
401 }
402
403 #else
404
405 static void threads_cast_darwinstop(void)
406 {
407         threadobject *tobj = mainthreadobj;
408         nativethread *infoself = THREADINFO;
409
410         do {
411                 nativethread *info = &tobj->info;
412                 if (info != infoself)
413                 {
414                         thread_state_flavor_t flavor = PPC_THREAD_STATE;
415                         mach_msg_type_number_t thread_state_count = PPC_THREAD_STATE_COUNT;
416                         ppc_thread_state_t thread_state;
417                         mach_port_t thread = info->mach_thread;
418                         kern_return_t r;
419
420                         r = thread_suspend(thread);
421                         if (r != KERN_SUCCESS) {
422                                 log_text("thread_suspend failed");
423                                 assert(0);
424                         }
425
426                         r = thread_get_state(thread, flavor,
427                                 (natural_t*)&thread_state, &thread_state_count);
428                         if (r != KERN_SUCCESS) {
429                                 log_text("thread_get_state failed");
430                                 assert(0);
431                         }
432
433                         thread_restartcriticalsection(&thread_state);
434
435                         r = thread_set_state(thread, flavor,
436                                 (natural_t*)&thread_state, thread_state_count);
437                         if (r != KERN_SUCCESS) {
438                                 log_text("thread_set_state failed");
439                                 assert(0);
440                         }
441                 }
442                 tobj = tobj->info.next;
443         } while (tobj != mainthreadobj);
444 }
445
446 static void threads_cast_darwinresume(void)
447 {
448         threadobject *tobj = mainthreadobj;
449         nativethread *infoself = THREADINFO;
450
451         do {
452                 nativethread *info = &tobj->info;
453                 if (info != infoself)
454                 {
455                         mach_port_t thread = info->mach_thread;
456                         kern_return_t r;
457
458                         r = thread_resume(thread);
459                         if (r != KERN_SUCCESS) {
460                                 log_text("thread_resume failed");
461                                 assert(0);
462                         }
463                 }
464                 tobj = tobj->info.next;
465         } while (tobj != mainthreadobj);
466 }
467
468 #endif
469
470 #if defined(__MIPS__)
471 static void threads_cast_irixresume(void)
472 {
473         pthread_mutex_lock(&suspend_ack_lock);
474         pthread_cond_broadcast(&suspend_cond);
475         pthread_mutex_unlock(&suspend_ack_lock);
476 }
477 #endif
478
479 void threads_cast_stopworld(void)
480 {
481         int count, i;
482         lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
483         pthread_mutex_lock(&threadlistlock);
484 #if defined(__DARWIN__)
485         threads_cast_darwinstop();
486 #else
487         count = threads_cast_sendsignals(GC_signum1(), 0);
488         for (i=0; i<count; i++)
489                 threads_sem_wait(&suspend_ack);
490 #endif
491         pthread_mutex_unlock(&threadlistlock);
492 }
493
494 void threads_cast_startworld(void)
495 {
496         pthread_mutex_lock(&threadlistlock);
497 #if defined(__DARWIN__)
498         threads_cast_darwinresume();
499 #elif defined(__MIPS__)
500         threads_cast_irixresume();
501 #else
502         threads_cast_sendsignals(GC_signum2(), -1);
503 #endif
504         pthread_mutex_unlock(&threadlistlock);
505         unlock_stopworld();
506 }
507
508 #if !defined(__DARWIN__)
509 static void threads_sigsuspend_handler(ucontext_t *ctx)
510 {
511         int sig;
512         sigset_t sigs;
513
514         /* XXX TWISTI: this is just a quick hack */
515 #if defined(ENABLE_JIT)
516         thread_restartcriticalsection(ctx);
517 #endif
518
519         /* Do as Boehm does. On IRIX a condition variable is used for wake-up
520            (not POSIX async-safe). */
521 #if defined(__IRIX__)
522         pthread_mutex_lock(&suspend_ack_lock);
523         threads_sem_post(&suspend_ack);
524         pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
525         pthread_mutex_unlock(&suspend_ack_lock);
526 #else
527         threads_sem_post(&suspend_ack);
528
529         sig = GC_signum2();
530         sigfillset(&sigs);
531         sigdelset(&sigs, sig);
532         sigsuspend(&sigs);
533 #endif
534 }
535
536 /* This function is called from Boehm GC code. */
537
538 int cacao_suspendhandler(ucontext_t *ctx)
539 {
540         if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
541                 return 0;
542
543         threads_sigsuspend_handler(ctx);
544         return 1;
545 }
546 #endif
547
548
549 /* threads_set_current_threadobject ********************************************
550
551    Set the current thread object.
552    
553    IN:
554       thread.......the thread object to set
555
556 *******************************************************************************/
557
558 #if !defined(ENABLE_JVMTI)
559 static void threads_set_current_threadobject(threadobject *thread)
560 #else
561 void threads_set_current_threadobject(threadobject *thread)
562 #endif
563 {
564 #if !defined(HAVE___THREAD)
565         pthread_setspecific(threads_current_threadobject_key, thread);
566 #else
567         threads_current_threadobject = thread;
568 #endif
569 }
570
571
572 /* threads_get_current_threadobject ********************************************
573
574    Return the threadobject of the current thread.
575    
576    RETURN VALUE:
577        the current threadobject * (an instance of java.lang.VMThread)
578
579 *******************************************************************************/
580
581 threadobject *threads_get_current_threadobject(void)
582 {
583         return THREADOBJECT;
584 }
585
586
587 /* threads_preinit *************************************************************
588
589    Do some early initialization of stuff required.
590
591 *******************************************************************************/
592
593 void threads_preinit(void)
594 {
595 #ifndef MUTEXSIM
596         pthread_mutexattr_t mutexattr;
597         pthread_mutexattr_init(&mutexattr);
598         pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
599         pthread_mutex_init(&compiler_mutex, &mutexattr);
600         pthread_mutexattr_destroy(&mutexattr);
601 #else
602         pthread_mutex_init_rec(&compiler_mutex);
603 #endif
604
605         pthread_mutex_init(&threadlistlock, NULL);
606         pthread_mutex_init(&stopworldlock, NULL);
607
608         /* Allocate something so the garbage collector's signal handlers
609            are installed. */
610         heap_allocate(1, false, NULL);
611
612         mainthreadobj = NEW(threadobject);
613         mainthreadobj->info.tid = pthread_self();
614 #if !defined(HAVE___THREAD)
615         pthread_key_create(&threads_current_threadobject_key, NULL);
616 #endif
617         threads_set_current_threadobject(mainthreadobj);
618
619         /* we need a working dummyLR before initializing the critical
620            section tree */
621
622         lock_init();
623
624         critical_init();
625
626         threads_sem_init(&suspend_ack, 0, 0);
627 }
628
629
630 /* threads_init ****************************************************************
631
632    Initializes the threads required by the JVM: main, finalizer.
633
634 *******************************************************************************/
635
636 bool threads_init(u1 *stackbottom)
637 {
638         java_lang_String      *threadname;
639         java_lang_Thread      *mainthread;
640         java_lang_ThreadGroup *threadgroup;
641         threadobject          *tempthread;
642         methodinfo            *method;
643
644         tempthread = mainthreadobj;
645
646         lock_record_free_pools(mainthreadobj->ee.lrpool);
647
648         /* This is kinda tricky, we grow the java.lang.Thread object so we
649            can keep the execution environment there. No Thread object must
650            have been created at an earlier time. */
651
652         class_java_lang_VMThread->instancesize = sizeof(threadobject);
653
654         /* create a VMThread */
655
656         mainthreadobj = (threadobject *) builtin_new(class_java_lang_VMThread);
657
658         if (!mainthreadobj)
659                 return false;
660
661         FREE(tempthread, threadobject);
662
663         threads_init_threadobject(&mainthreadobj->o);
664
665         threads_set_current_threadobject(mainthreadobj);
666
667         lock_init_thread_lock_record_pool(mainthreadobj);
668
669         mainthreadobj->info.next = mainthreadobj;
670         mainthreadobj->info.prev = mainthreadobj;
671
672 #if defined(ENABLE_INTRP)
673         /* create interpreter stack */
674
675         if (opt_intrp) {
676                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
677                 mainthreadobj->info._global_sp = intrp_main_stack + opt_stacksize;
678         }
679 #endif
680
681         threadname = javastring_new(utf_new_char("main"));
682
683         /* allocate and init ThreadGroup */
684
685         threadgroup = (java_lang_ThreadGroup *)
686                 native_new_and_init(class_java_lang_ThreadGroup);
687
688         if (!threadgroup)
689                 throw_exception_exit();
690
691         /* create a Thread */
692
693         mainthread = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
694
695         if (!mainthread)
696                 throw_exception_exit();
697
698         mainthreadobj->o.thread = mainthread;
699
700         /* call Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
701
702         method = class_resolveclassmethod(class_java_lang_Thread,
703                                                                           utf_init,
704                                                                           utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
705                                                                           class_java_lang_Thread,
706                                                                           true);
707
708         if (!method)
709                 return false;
710
711         (void) vm_call_method(method, (java_objectheader *) mainthread,
712                                                   mainthreadobj, threadname, 5, false);
713
714         if (*exceptionptr)
715                 return false;
716
717         mainthread->group = threadgroup;
718
719         /* add mainthread to ThreadGroup */
720
721         method = class_resolveclassmethod(class_java_lang_ThreadGroup,
722                                                                           utf_new_char("addThread"),
723                                                                           utf_new_char("(Ljava/lang/Thread;)V"),
724                                                                           class_java_lang_ThreadGroup,
725                                                                           true);
726
727         if (!method)
728                 return false;
729
730         (void) vm_call_method(method, (java_objectheader *) threadgroup,
731                                                   mainthread);
732
733         if (*exceptionptr)
734                 return false;
735
736         threads_set_thread_priority(pthread_self(), 5);
737
738         pthread_attr_init(&threadattr);
739         pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
740
741         /* everything's ok */
742
743         return true;
744 }
745
746
747 /* threads_init_threadobject **************************************************
748
749    Initialize implementation fields of a java.lang.VMThread.
750
751    IN:
752       t............the java.lang.VMThread
753
754 ******************************************************************************/
755
756 void threads_init_threadobject(java_lang_VMThread *t)
757 {
758         threadobject *thread = (threadobject*) t;
759         nativethread *info = &thread->info;
760         info->tid = pthread_self();
761         /* TODO destroy all those things */
762         pthread_mutex_init(&info->joinMutex, NULL);
763         pthread_cond_init(&info->joinCond, NULL);
764
765         pthread_mutex_init(&thread->waitLock, NULL);
766         pthread_cond_init(&thread->waitCond, NULL);
767         thread->interrupted = false;
768         thread->signaled = false;
769         thread->isSleeping = false;
770 }
771
772
773 /* threads_startup_thread ******************************************************
774
775    Thread startup function called by pthread_create.
776
777    NOTE: This function is not called directly by pthread_create. The Boehm GC
778          inserts its own GC_start_routine in between, which then calls
779                  threads_startup.
780
781    IN:
782       t............the argument passed to pthread_create, ie. a pointer to
783                        a startupinfo struct. CAUTION: When the `psem` semaphore
784                                    is posted, the startupinfo struct becomes invalid! (It
785                                    is allocated on the stack of threads_start_thread.)
786
787 ******************************************************************************/
788
789 static void *threads_startup_thread(void *t)
790 {
791         startupinfo  *startup;
792         threadobject *thread;
793         sem_t        *psem;
794         nativethread *info;
795         threadobject *tnext;
796         methodinfo   *method;
797         functionptr   function;
798
799 #if defined(ENABLE_INTRP)
800         u1 *intrp_thread_stack;
801
802         /* create interpreter stack */
803
804         if (opt_intrp) {
805                 intrp_thread_stack = (u1 *) alloca(opt_stacksize);
806                 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
807         } else {
808                 intrp_thread_stack = NULL;
809         }
810 #endif
811
812         /* get passed startupinfo structure and the values in there */
813
814         startup = t;
815         t = NULL; /* make sure it's not used wrongly */
816
817         thread   = startup->thread;
818         function = startup->function;
819         psem     = startup->psem;
820
821         info = &thread->info;
822
823         /* Seems like we've encountered a situation where info->tid was not set by
824          * pthread_create. We alleviate this problem by waiting for pthread_create
825          * to return. */
826         threads_sem_wait(startup->psem_first);
827
828         /* set the thread object */
829
830 #if defined(__DARWIN__)
831         info->mach_thread = mach_thread_self();
832 #endif
833         threads_set_current_threadobject(thread);
834
835         /* insert the thread into the threadlist */
836
837         pthread_mutex_lock(&threadlistlock);
838
839         info->prev = mainthreadobj;
840         info->next = tnext = mainthreadobj->info.next;
841         mainthreadobj->info.next = thread;
842         tnext->info.prev = thread;
843
844         pthread_mutex_unlock(&threadlistlock);
845
846         /* init data structures of this thread */
847
848         lock_init_thread_lock_record_pool(thread);
849
850         /* tell threads_startup_thread that we registered ourselves */
851         /* CAUTION: *startup becomes invalid with this!             */
852
853         startup = NULL;
854         threads_sem_post(psem);
855
856         /* set our priority */
857
858         threads_set_thread_priority(info->tid, thread->o.thread->priority);
859
860 #if defined(ENABLE_INTRP)
861         /* set interpreter stack */
862
863         if (opt_intrp)
864                 THREADINFO->_global_sp = (void *) (intrp_thread_stack + opt_stacksize);
865 #endif
866
867         /* find and run the Thread.run()V method if no other function was passed */
868
869         if (function == NULL) {
870                 method = class_resolveclassmethod(thread->o.header.vftbl->class,
871                                                                                   utf_run,
872                                                                                   utf_void__void,
873                                                                                   thread->o.header.vftbl->class,
874                                                                                   true);
875
876                 if (!method)
877                         throw_exception();
878
879                 (void) vm_call_method(method, (java_objectheader *) thread);
880
881         }
882         else {
883                 /* call passed function, e.g. finalizer_thread */
884
885                 (function)();
886         }
887
888         /* Allow lock record pools to be used by other threads. They
889            cannot be deleted so we'd better not waste them. */
890
891         lock_record_free_pools(thread->ee.lrpool);
892
893         /* remove thread from thread list, do this inside a lock */
894
895         pthread_mutex_lock(&threadlistlock);
896         info->next->info.prev = info->prev;
897         info->prev->info.next = info->next;
898         pthread_mutex_unlock(&threadlistlock);
899
900         /* reset thread id (lock on joinMutex? TWISTI) */
901
902         pthread_mutex_lock(&info->joinMutex);
903         info->tid = 0;
904         pthread_mutex_unlock(&info->joinMutex);
905
906         /* tell everyone that a thread has finished */
907
908         pthread_cond_broadcast(&info->joinCond);
909
910         return NULL;
911 }
912
913
914 /* threads_start_thread ********************************************************
915
916    Start a thread in the JVM.
917
918    IN:
919       t............the java.lang.Thread object
920           function.....function to run in the new thread. NULL means that the
921                        "run" method of the object `t` should be called
922
923 ******************************************************************************/
924
925 void threads_start_thread(java_lang_Thread *t, functionptr function)
926 {
927         nativethread *info;
928         sem_t         sem;
929         sem_t         sem_first;
930         startupinfo   startup;
931
932         info = &((threadobject *) t->vmThread)->info;
933
934         /* fill startupinfo structure passed by pthread_create to
935          * threads_startup_thread */
936
937         startup.thread     = (threadobject*) t->vmThread;
938         startup.function   = function;       /* maybe we don't call Thread.run()V */
939         startup.psem       = &sem;
940         startup.psem_first = &sem_first;
941
942         threads_sem_init(&sem, 0, 0);
943         threads_sem_init(&sem_first, 0, 0);
944
945         /* create the thread */
946
947         if (pthread_create(&info->tid, &threadattr, threads_startup_thread,
948                                            &startup)) {
949                 log_text("pthread_create failed");
950                 assert(0);
951         }
952
953         /* signal that pthread_create has returned, so info->tid is valid */
954
955         threads_sem_post(&sem_first);
956
957         /* wait here until the thread has entered itself into the thread list */
958
959         threads_sem_wait(&sem);
960
961         /* cleanup */
962
963         sem_destroy(&sem);
964         sem_destroy(&sem_first);
965 }
966
967
968 /* threads_find_non_daemon_thread **********************************************
969
970    Helper function used by threads_join_all_threads for finding non-daemon threads
971    that are still running.
972
973 *******************************************************************************/
974
975 /* At the end of the program, we wait for all running non-daemon threads to die
976  */
977
978 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
979 {
980         while (thread != mainthreadobj) {
981                 if (!thread->o.thread->daemon)
982                         return thread;
983                 thread = thread->info.prev;
984         }
985
986         return NULL;
987 }
988
989
990 /* threads_join_all_threads ****************************************************
991
992    Join all non-daemon threads.
993
994 *******************************************************************************/
995
996 void threads_join_all_threads(void)
997 {
998         threadobject *thread;
999         pthread_mutex_lock(&threadlistlock);
1000         while ((thread = threads_find_non_daemon_thread(mainthreadobj->info.prev)) != NULL) {
1001                 nativethread *info = &thread->info;
1002                 pthread_mutex_lock(&info->joinMutex);
1003                 pthread_mutex_unlock(&threadlistlock);
1004                 while (info->tid)
1005                         pthread_cond_wait(&info->joinCond, &info->joinMutex);
1006                 pthread_mutex_unlock(&info->joinMutex);
1007                 pthread_mutex_lock(&threadlistlock);
1008         }
1009         pthread_mutex_unlock(&threadlistlock);
1010 }
1011
1012
1013 /* threads_timespec_earlier ****************************************************
1014
1015    Return true if timespec tv1 is earlier than timespec tv2.
1016
1017    IN:
1018       tv1..........first timespec
1019           tv2..........second timespec
1020
1021    RETURN VALUE:
1022       true, if the first timespec is earlier
1023
1024 *******************************************************************************/
1025
1026 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1027                                                                                         const struct timespec *tv2)
1028 {
1029         return (tv1->tv_sec < tv2->tv_sec)
1030                                 ||
1031                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1032 }
1033
1034
1035 /* threads_current_time_is_earlier_than ****************************************
1036
1037    Check if the current time is earlier than the given timespec.
1038
1039    IN:
1040       tv...........the timespec to compare against
1041
1042    RETURN VALUE:
1043       true, if the current time is earlier
1044
1045 *******************************************************************************/
1046
1047 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1048 {
1049         struct timeval tvnow;
1050         struct timespec tsnow;
1051
1052         /* get current time */
1053
1054         if (gettimeofday(&tvnow, NULL) != 0) {
1055                 fprintf(stderr,"error: gettimeofday returned unexpected error %d: %s\n",
1056                                 errno, strerror(errno));
1057                 abort();
1058         }
1059
1060         /* convert it to a timespec */
1061
1062         tsnow.tv_sec = tvnow.tv_sec;
1063         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1064
1065         /* compare current time with the given timespec */
1066
1067         return threads_timespec_earlier(&tsnow, tv);
1068 }
1069
1070
1071 /* threads_wait_with_timeout ***************************************************
1072
1073    Wait until the given point in time on a monitor until either
1074    we are notified, we are interrupted, or the time is up.
1075
1076    IN:
1077       t............the current thread
1078           wakeupTime...absolute (latest) wakeup time
1079                            If both tv_sec and tv_nsec are zero, this function
1080                                            waits for an unlimited amount of time.
1081
1082    RETURN VALUE:
1083       true.........if the wait has been interrupted,
1084           false........if the wait was ended by notification or timeout
1085
1086 *******************************************************************************/
1087
1088 static bool threads_wait_with_timeout(threadobject *t,
1089                                                                           struct timespec *wakeupTime)
1090 {
1091         bool wasinterrupted;
1092
1093         /* acquire the waitLock */
1094
1095         pthread_mutex_lock(&t->waitLock);
1096
1097         /* mark us as sleeping */
1098
1099         t->isSleeping = true;
1100
1101         /* wait on waitCond */
1102
1103         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1104                 /* with timeout */
1105                 while (!t->interrupted && !t->signaled
1106                            && threads_current_time_is_earlier_than(wakeupTime))
1107                 {
1108                         pthread_cond_timedwait(&t->waitCond, &t->waitLock, wakeupTime);
1109                 }
1110         }
1111         else {
1112                 /* no timeout */
1113                 while (!t->interrupted && !t->signaled)
1114                         pthread_cond_wait(&t->waitCond, &t->waitLock);
1115         }
1116
1117         /* check if we were interrupted */
1118
1119         wasinterrupted = t->interrupted;
1120
1121         /* reset all flags */
1122
1123         t->interrupted = false;
1124         t->signaled = false;
1125         t->isSleeping = false;
1126
1127         /* release the waitLock */
1128
1129         pthread_mutex_unlock(&t->waitLock);
1130
1131         return wasinterrupted;
1132 }
1133
1134
1135 /* threads_wait_with_timeout_relative ******************************************
1136
1137    Wait for the given maximum amount of time on a monitor until either
1138    we are notified, we are interrupted, or the time is up.
1139
1140    IN:
1141       t............the current thread
1142           millis.......milliseconds to wait
1143           nanos........nanoseconds to wait
1144
1145    RETURN VALUE:
1146       true.........if the wait has been interrupted,
1147           false........if the wait was ended by notification or timeout
1148
1149 *******************************************************************************/
1150
1151 bool threads_wait_with_timeout_relative(threadobject *t,
1152                                                                                 s8 millis,
1153                                                                                 s4 nanos)
1154 {
1155         struct timespec wakeupTime;
1156
1157         /* calculate the the (latest) wakeup time */
1158
1159         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1160
1161         /* wait */
1162
1163         return threads_wait_with_timeout(t, &wakeupTime);
1164 }
1165
1166
1167 /* threads_calc_absolute_time **************************************************
1168
1169    Calculate the absolute point in time a given number of ms and ns from now.
1170
1171    IN:
1172       millis............milliseconds from now
1173           nanos.............nanoseconds from now
1174
1175    OUT:
1176       *tm...............receives the timespec of the absolute point in time
1177
1178 *******************************************************************************/
1179
1180 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1181 {
1182         if (millis || nanos) {
1183                 struct timeval tv;
1184                 long nsec;
1185                 gettimeofday(&tv, NULL);
1186                 tv.tv_sec += millis / 1000;
1187                 millis %= 1000;
1188                 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1189                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1190                 tm->tv_nsec = nsec % 1000000000;
1191         }
1192         else {
1193                 tm->tv_sec = 0;
1194                 tm->tv_nsec = 0;
1195         }
1196 }
1197
1198
1199 /* threads_interrupt_thread ****************************************************
1200
1201    Interrupt the given thread.
1202
1203    The thread gets the "waitCond" signal and 
1204    its interrupted flag is set to true.
1205
1206    IN:
1207       thread............the thread to interrupt
1208
1209 *******************************************************************************/
1210
1211 void threads_interrupt_thread(java_lang_VMThread *thread)
1212 {
1213         threadobject *t = (threadobject*) thread;
1214
1215         /* signal the thread a "waitCond" and tell it that it has been */
1216         /* interrupted                                                 */
1217
1218         pthread_mutex_lock(&t->waitLock);
1219         if (t->isSleeping)
1220                 pthread_cond_signal(&t->waitCond);
1221         t->interrupted = true;
1222         pthread_mutex_unlock(&t->waitLock);
1223 }
1224
1225
1226 /* threads_check_if_interrupted_and_reset **************************************
1227
1228    Check if the current thread has been interrupted and reset the
1229    interruption flag.
1230
1231    RETURN VALUE:
1232       true, if the current thread had been interrupted
1233
1234 *******************************************************************************/
1235
1236 bool threads_check_if_interrupted_and_reset(void)
1237 {
1238         threadobject *t;
1239         bool intr;
1240
1241         t = (threadobject*) THREADOBJECT;
1242
1243         intr = t->interrupted;
1244
1245         t->interrupted = false;
1246
1247         return intr;
1248 }
1249
1250
1251 /* threads_thread_has_been_interrupted *********************************************************
1252
1253    Check if the given thread has been interrupted
1254
1255    IN:
1256       t............the thread to check
1257
1258    RETURN VALUE:
1259       true, if the given thread had been interrupted
1260
1261 *******************************************************************************/
1262
1263 bool threads_thread_has_been_interrupted(java_lang_VMThread *thread)
1264 {
1265         threadobject *t;
1266
1267         t = (threadobject*) thread;
1268
1269         return t->interrupted;
1270 }
1271
1272
1273 /* threads_sleep ***************************************************************
1274
1275    Sleep the current thread for the specified amount of time.
1276
1277 *******************************************************************************/
1278
1279 void threads_sleep(s8 millis, s4 nanos)
1280 {
1281         threadobject       *t;
1282         struct timespec    wakeupTime;
1283         bool               wasinterrupted;
1284
1285         t = (threadobject *) THREADOBJECT;
1286
1287         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1288
1289         wasinterrupted = threads_wait_with_timeout(t, &wakeupTime);
1290
1291         if (wasinterrupted)
1292                 *exceptionptr = new_exception(string_java_lang_InterruptedException);
1293 }
1294
1295
1296 /* threads_yield *****************************************************************
1297
1298    Yield to the scheduler.
1299
1300 *******************************************************************************/
1301
1302 void threads_yield(void)
1303 {
1304         sched_yield();
1305 }
1306
1307
1308 /* threads_java_lang_Thread_set_priority ***********************************************************
1309
1310    Set the priority for the given java.lang.Thread.
1311
1312    IN:
1313       t............the java.lang.Thread
1314           priority.....the priority
1315
1316 *******************************************************************************/
1317
1318 void threads_java_lang_Thread_set_priority(java_lang_Thread *t, s4 priority)
1319 {
1320         nativethread *info = &((threadobject*) t->vmThread)->info;
1321         threads_set_thread_priority(info->tid, priority);
1322 }
1323
1324
1325 /* threads_dump ****************************************************************
1326
1327    Dumps info for all threads running in the JVM. This function is
1328    called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1329
1330 *******************************************************************************/
1331
1332 void threads_dump(void)
1333 {
1334         threadobject       *tobj;
1335         java_lang_VMThread *vmt;
1336         nativethread       *nt;
1337         java_lang_Thread   *t;
1338         utf                *name;
1339
1340         tobj = mainthreadobj;
1341
1342         printf("Full thread dump CACAO "VERSION":\n");
1343
1344         /* iterate over all started threads */
1345
1346         do {
1347                 /* get thread objects */
1348
1349                 vmt = &tobj->o;
1350                 nt  = &tobj->info;
1351                 t   = vmt->thread;
1352
1353                 /* the thread may be currently in initalization, don't print it */
1354
1355                 if (t) {
1356                         /* get thread name */
1357
1358                         name = javastring_toutf(t->name, false);
1359
1360                         printf("\n\"");
1361                         utf_display_printable_ascii(name);
1362                         printf("\" ");
1363
1364                         if (t->daemon)
1365                                 printf("daemon ");
1366
1367 #if SIZEOF_VOID_P == 8
1368                         printf("prio=%d tid=0x%016lx\n", t->priority, nt->tid);
1369 #else
1370                         printf("prio=%d tid=0x%08lx\n", t->priority, nt->tid);
1371 #endif
1372
1373                         /* send SIGUSR1 to thread to print stacktrace */
1374
1375                         pthread_kill(nt->tid, SIGUSR1);
1376
1377                         /* sleep this thread a bit, so the signal can reach the thread */
1378
1379                         threads_sleep(10, 0);
1380                 }
1381
1382                 tobj = tobj->info.next;
1383         } while (tobj && (tobj != mainthreadobj));
1384 }
1385
1386
1387 /*
1388  * These are local overrides for various environment variables in Emacs.
1389  * Please do not remove this and leave it at the end of the file, where
1390  * Emacs will automagically detect them.
1391  * ---------------------------------------------------------------------
1392  * Local variables:
1393  * mode: c
1394  * indent-tabs-mode: t
1395  * c-basic-offset: 4
1396  * tab-width: 4
1397  * End:
1398  * vim:noexpandtab:sw=4:ts=4:
1399  */