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