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