* src/vm/vm.cpp (vm_abort_errnum, vm_abort_errno): Removed obsolete functions.
[cacao.git] / src / threads / posix / thread-posix.cpp
1 /* src/threads/posix/thread-posix.cpp - POSIX thread functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 /* XXX cleanup these includes */
29
30 #define __STDC_LIMIT_MACROS
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 #include <sys/time.h>
38 #include <time.h>
39 #include <errno.h>
40
41 #include <pthread.h>
42
43 #include "vm/types.h"
44
45 #include "arch.h"
46
47 #include "mm/gc.hpp"
48 #include "mm/memory.hpp"
49
50 #if defined(ENABLE_GC_CACAO)
51 # include "mm/cacao-gc/gc.h"
52 #endif
53
54 #include "native/llni.h"
55 #include "native/native.hpp"
56
57 #include "threads/condition.hpp"
58 #include "threads/lock.hpp"
59 #include "threads/mutex.hpp"
60 #include "threads/threadlist.hpp"
61 #include "threads/thread.hpp"
62
63 #include "toolbox/logging.hpp"
64
65 #include "vm/jit/builtin.hpp"
66 #include "vm/exceptions.hpp"
67 #include "vm/global.h"
68 #include "vm/globals.hpp"
69 #include "vm/javaobjects.hpp"
70 #include "vm/options.h"
71 #include "vm/os.hpp"
72 #include "vm/signallocal.hpp"
73 #include "vm/string.hpp"
74 #include "vm/vm.hpp"
75
76 #if defined(ENABLE_STATISTICS)
77 # include "vm/statistics.h"
78 #endif
79
80 #include "vm/jit/asmpart.h"
81
82 #if !defined(__DARWIN__)
83 # include <semaphore.h>
84 #endif
85
86 #if defined(__LINUX__)
87 # define GC_LINUX_THREADS
88 #elif defined(__IRIX__)
89 # define GC_IRIX_THREADS
90 #elif defined(__DARWIN__)
91 # define GC_DARWIN_THREADS
92 #endif
93
94 #if defined(ENABLE_GC_BOEHM)
95 /* We need to include Boehm's gc.h here because it overrides
96    pthread_create and friends. */
97 # include "mm/boehm-gc/include/gc.h"
98 #endif
99
100 #if defined(ENABLE_JVMTI)
101 #include "native/jvmti/cacaodbg.h"
102 #endif
103
104
105 #if defined(__DARWIN__)
106 /* Darwin has no working semaphore implementation.  This one is taken
107    from Boehm-GC. */
108
109 /*
110    This is a very simple semaphore implementation for Darwin. It
111    is implemented in terms of pthreads calls so it isn't async signal
112    safe. This isn't a problem because signals aren't used to
113    suspend threads on Darwin.
114 */
115    
116 static int sem_init(sem_t *sem, int pshared, int value)
117 {
118         if (pshared)
119                 assert(0);
120
121         sem->mutex = new Mutex();
122         sem->cond  = new Condition();
123         sem->value = value;
124
125         return 0;
126 }
127
128 static int sem_post(sem_t *sem)
129 {
130         sem->mutex->lock();
131         sem->value++;
132         sem->cond->signal();
133         sem->mutex->unlock();
134
135         return 0;
136 }
137
138 static int sem_wait(sem_t *sem)
139 {
140         sem->mutex->lock();
141
142         while (sem->value == 0) {
143                 sem->cond->wait(sem->mutex);
144         }
145
146         sem->value--;
147         sem->mutex->unlock();
148
149         return 0;
150 }
151
152 static int sem_destroy(sem_t *sem)
153 {
154         delete sem->cond;
155         delete sem->mutex;
156
157         return 0;
158 }
159 #endif /* defined(__DARWIN__) */
160
161
162 /* startupinfo *****************************************************************
163
164    Struct used to pass info from threads_start_thread to 
165    threads_startup_thread.
166
167 ******************************************************************************/
168
169 typedef struct {
170         threadobject *thread;      /* threadobject for this thread             */
171         functionptr   function;    /* function to run in the new thread        */
172         sem_t        *psem;        /* signals when thread has been entered     */
173                                    /* in the thread list                       */
174         sem_t        *psem_first;  /* signals when pthread_create has returned */
175 } startupinfo;
176
177
178 /* prototypes *****************************************************************/
179
180 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
181
182
183 /******************************************************************************/
184 /* GLOBAL VARIABLES                                                           */
185 /******************************************************************************/
186
187 /* the thread object of the current thread                                    */
188 /* This is either a thread-local variable defined with __thread, or           */
189 /* a thread-specific value stored with key threads_current_threadobject_key.  */
190 #if defined(HAVE___THREAD)
191 __thread threadobject *thread_current;
192 #else
193 pthread_key_t thread_current_key;
194 #endif
195
196 /* global mutex for stop-the-world                                            */
197 static Mutex* stopworldlock;
198
199 #if defined(ENABLE_GC_CACAO)
200 /* global mutex for the GC */
201 static Mutex* mutex_gc;
202 #endif
203
204 /* global mutex and condition for joining threads on exit */
205 static Mutex* mutex_join;
206 static Condition* cond_join;
207
208 #if defined(ENABLE_GC_CACAO)
209 /* semaphore used for acknowleding thread suspension                          */
210 static sem_t suspend_ack;
211 #endif
212
213
214 /* threads_sem_init ************************************************************
215  
216    Initialize a semaphore. Checks against errors and interruptions.
217
218    IN:
219        sem..............the semaphore to initialize
220            shared...........true if this semaphore will be shared between processes
221            value............the initial value for the semaphore
222    
223 *******************************************************************************/
224
225 void threads_sem_init(sem_t *sem, bool shared, int value)
226 {
227         int r;
228
229         assert(sem);
230
231         do {
232                 r = sem_init(sem, shared, value);
233                 if (r == 0)
234                         return;
235         } while (errno == EINTR);
236
237         vm_abort("sem_init failed: %s", strerror(errno));
238 }
239
240
241 /* threads_sem_wait ************************************************************
242  
243    Wait for a semaphore, non-interruptible.
244
245    IMPORTANT: Always use this function instead of `sem_wait` directly, as
246               `sem_wait` may be interrupted by signals!
247   
248    IN:
249        sem..............the semaphore to wait on
250    
251 *******************************************************************************/
252
253 void threads_sem_wait(sem_t *sem)
254 {
255         int r;
256
257         assert(sem);
258
259         do {
260                 r = sem_wait(sem);
261                 if (r == 0)
262                         return;
263         } while (errno == EINTR);
264
265         vm_abort("sem_wait failed: %s", strerror(errno));
266 }
267
268
269 /* threads_sem_post ************************************************************
270  
271    Increase the count of a semaphore. Checks for errors.
272
273    IN:
274        sem..............the semaphore to increase the count of
275    
276 *******************************************************************************/
277
278 void threads_sem_post(sem_t *sem)
279 {
280         int r;
281
282         assert(sem);
283
284         /* unlike sem_wait, sem_post is not interruptible */
285
286         r = sem_post(sem);
287         if (r == 0)
288                 return;
289
290         vm_abort("sem_post failed: %s", strerror(errno));
291 }
292
293
294 /* threads_stopworld ***********************************************************
295
296    Stops the world from turning. All threads except the calling one
297    are suspended. The function returns as soon as all threads have
298    acknowledged their suspension.
299
300 *******************************************************************************/
301
302 #if defined(ENABLE_GC_CACAO)
303 void threads_stopworld(void)
304 {
305 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
306         threadobject *t;
307         threadobject *self;
308         bool result;
309         s4 count, i;
310 #endif
311
312         stopworldlock->lock();
313
314         /* lock the threads lists */
315
316         threadlist_lock();
317
318 #if defined(__DARWIN__)
319         /*threads_cast_darwinstop();*/
320         assert(0);
321 #elif defined(__CYGWIN__)
322         /* TODO */
323         assert(0);
324 #else
325         self = THREADOBJECT;
326
327         DEBUGTHREADS("stops World", self);
328
329         count = 0;
330
331         /* suspend all running threads */
332         for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
333                 /* don't send the signal to ourself */
334
335                 if (t == self)
336                         continue;
337
338                 /* don't send the signal to NEW threads (because they are not
339                    completely initialized) */
340
341                 if (t->state == THREAD_STATE_NEW)
342                         continue;
343
344                 /* send the signal */
345
346                 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
347                 assert(result);
348
349                 /* increase threads count */
350
351                 count++;
352         }
353
354         /* wait for all threads signaled to suspend */
355         for (i = 0; i < count; i++)
356                 threads_sem_wait(&suspend_ack);
357 #endif
358
359         /* ATTENTION: Don't unlock the threads-lists here so that
360            non-signaled NEW threads can't change their state and execute
361            code. */
362 }
363 #endif
364
365
366 /* threads_startworld **********************************************************
367
368    Starts the world again after it has previously been stopped. 
369
370 *******************************************************************************/
371
372 #if defined(ENABLE_GC_CACAO)
373 void threads_startworld(void)
374 {
375 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
376         threadobject *t;
377         threadobject *self;
378         bool result;
379         s4 count, i;
380 #endif
381
382 #if defined(__DARWIN__)
383         /*threads_cast_darwinresume();*/
384         assert(0);
385 #elif defined(__IRIX__)
386         threads_cast_irixresume();
387 #elif defined(__CYGWIN__)
388         /* TODO */
389         assert(0);
390 #else
391         self = THREADOBJECT;
392
393         DEBUGTHREADS("starts World", self);
394
395         count = 0;
396
397         /* resume all thread we haltet */
398         for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
399                 /* don't send the signal to ourself */
400
401                 if (t == self)
402                         continue;
403
404                 /* don't send the signal to NEW threads (because they are not
405                    completely initialized) */
406
407                 if (t->state == THREAD_STATE_NEW)
408                         continue;
409
410                 /* send the signal */
411
412                 result = threads_resume_thread(t);
413                 assert(result);
414
415                 /* increase threads count */
416
417                 count++;
418         }
419
420         /* wait for all threads signaled to suspend */
421         for (i = 0; i < count; i++)
422                 threads_sem_wait(&suspend_ack);
423
424 #endif
425
426         /* unlock the threads lists */
427
428         threadlist_unlock();
429
430         stopworldlock->unlock();
431 }
432 #endif
433
434
435 /* threads_impl_thread_clear ***************************************************
436
437    Clears all fields in threadobject the way an MZERO would have
438    done. MZERO cannot be used anymore because it would mess up the
439    pthread_* bits.
440
441    IN:
442       t....the threadobject
443
444 *******************************************************************************/
445
446 void threads_impl_thread_clear(threadobject *t)
447 {
448         t->object = NULL;
449
450         t->thinlock = 0;
451
452         t->index = 0;
453         t->flags = 0;
454         t->state = 0;
455
456         t->tid = 0;
457
458 #if defined(__DARWIN__)
459         t->mach_thread = 0;
460 #endif
461
462         t->interrupted = false;
463         t->signaled = false;
464
465         t->suspended = false;
466         t->suspend_reason = 0;
467
468         t->pc = NULL;
469
470         t->_exceptionptr = NULL;
471         t->_stackframeinfo = NULL;
472         t->_localref_table = NULL;
473
474 #if defined(ENABLE_INTRP)
475         t->_global_sp = NULL;
476 #endif
477
478 #if defined(ENABLE_GC_CACAO)
479         t->gc_critical = false;
480
481         t->ss = NULL;
482         t->es = NULL;
483 #endif
484
485         // Simply reuse the existing dump memory.
486 }
487
488 /* threads_impl_thread_reuse ***************************************************
489
490    Resets some implementation fields in threadobject. This was
491    previously done in threads_impl_thread_new.
492
493    IN:
494       t....the threadobject
495
496 *******************************************************************************/
497
498 void threads_impl_thread_reuse(threadobject *t)
499 {
500         /* get the pthread id */
501
502         t->tid = pthread_self();
503
504 #if defined(ENABLE_DEBUG_FILTER)
505         /* Initialize filter counters */
506         t->filterverbosecallctr[0] = 0;
507         t->filterverbosecallctr[1] = 0;
508 #endif
509
510 #if !defined(NDEBUG)
511         t->tracejavacallindent = 0;
512         t->tracejavacallcount = 0;
513 #endif
514
515         t->flc_bit = false;
516         t->flc_next = NULL;
517         t->flc_list = NULL;
518
519 /*      not really needed */
520         t->flc_object = NULL;
521
522 #if defined(ENABLE_TLH)
523         tlh_destroy(&(t->tlh));
524         tlh_init(&(t->tlh));
525 #endif
526 }
527
528
529 /* threads_impl_thread_free ****************************************************
530
531    Cleanup thread stuff.
532
533    IN:
534       t....the threadobject
535
536 *******************************************************************************/
537
538 #if 0
539 /* never used */
540 void threads_impl_thread_free(threadobject *t)
541 {
542         int result;
543
544         /* Destroy the mutex and the condition. */
545
546         delete t->flc_lock;
547
548         result = pthread_cond_destroy(&(t->flc_cond));
549
550         if (result != 0)
551                 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
552
553         delete t->waitmutex;
554
555         result = pthread_cond_destroy(&(t->waitcond));
556
557         if (result != 0)
558                 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
559
560         delete t->suspendmutex;
561
562         result = pthread_cond_destroy(&(t->suspendcond));
563
564         if (result != 0)
565                 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
566 }
567 #endif
568
569
570 /* threads_impl_preinit ********************************************************
571
572    Do some early initialization of stuff required.
573
574    ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
575    is called AFTER this function!
576
577 *******************************************************************************/
578
579 void threads_impl_preinit(void)
580 {
581         int result;
582
583         stopworldlock = new Mutex();
584
585         /* initialize exit mutex and condition (on exit we join all
586            threads) */
587
588         mutex_join = new Mutex();
589         cond_join = new Condition();
590
591 #if defined(ENABLE_GC_CACAO)
592         /* initialize the GC mutex & suspend semaphore */
593
594         mutex_gc = new Mutex();
595         threads_sem_init(&suspend_ack, 0, 0);
596 #endif
597
598 #if !defined(HAVE___THREAD)
599         result = pthread_key_create(&thread_current_key, NULL);
600         if (result != 0)
601                 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
602 #endif
603 }
604
605
606 /* threads_mutex_gc_lock *******************************************************
607
608    Enter the global GC mutex.
609
610 *******************************************************************************/
611
612 #if defined(ENABLE_GC_CACAO)
613 void threads_mutex_gc_lock(void)
614 {
615         mutex_gc->lock();
616 }
617 #endif
618
619
620 /* threads_mutex_gc_unlock *****************************************************
621
622    Leave the global GC mutex.
623
624 *******************************************************************************/
625
626 #if defined(ENABLE_GC_CACAO)
627 void threads_mutex_gc_unlock(void)
628 {
629         mutex_gc->unlock();
630 }
631 #endif
632
633 /* threads_mutex_join_lock *****************************************************
634
635    Enter the join mutex.
636
637 *******************************************************************************/
638
639 void threads_mutex_join_lock(void)
640 {
641         mutex_join->lock();
642 }
643
644
645 /* threads_mutex_join_unlock ***************************************************
646
647    Leave the join mutex.
648
649 *******************************************************************************/
650
651 void threads_mutex_join_unlock(void)
652 {
653         mutex_join->unlock();
654 }
655
656
657 /* threads_impl_init ***********************************************************
658
659    Initializes the implementation specific bits.
660
661 *******************************************************************************/
662
663 void threads_impl_init(void)
664 {
665         pthread_attr_t attr;
666         int            result;
667
668         threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
669
670         /* Initialize the thread attribute object. */
671
672         result = pthread_attr_init(&attr);
673
674         if (result != 0)
675                 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
676
677         result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
678
679         if (result != 0)
680                 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
681 }
682
683
684 /* threads_startup_thread ******************************************************
685
686    Thread startup function called by pthread_create.
687
688    Thread which have a startup.function != NULL are marked as internal
689    threads. All other threads are threated as normal Java threads.
690
691    NOTE: This function is not called directly by pthread_create. The Boehm GC
692          inserts its own GC_start_routine in between, which then calls
693                  threads_startup.
694
695    IN:
696       arg..........the argument passed to pthread_create, ie. a pointer to
697                        a startupinfo struct. CAUTION: When the `psem` semaphore
698                                    is posted, the startupinfo struct becomes invalid! (It
699                                    is allocated on the stack of threads_start_thread.)
700
701 ******************************************************************************/
702
703 static void *threads_startup_thread(void *arg)
704 {
705         startupinfo  *startup;
706         threadobject *t;
707         sem_t        *psem;
708         classinfo    *c;
709         methodinfo   *m;
710         functionptr   function;
711
712 #if defined(ENABLE_GC_BOEHM)
713 # if !defined(__DARWIN__)
714         struct GC_stack_base sb;
715         int result;
716 # endif
717 #endif
718
719 #if defined(ENABLE_INTRP)
720         u1 *intrp_thread_stack;
721 #endif
722
723 #if defined(ENABLE_INTRP)
724         /* create interpreter stack */
725
726         if (opt_intrp) {
727                 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
728                 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
729         }
730         else
731                 intrp_thread_stack = NULL;
732 #endif
733
734         /* get passed startupinfo structure and the values in there */
735
736         startup = (startupinfo*) arg;
737
738         t        = startup->thread;
739         function = startup->function;
740         psem     = startup->psem;
741
742         /* Seems like we've encountered a situation where thread->tid was
743            not set by pthread_create. We alleviate this problem by waiting
744            for pthread_create to return. */
745
746         threads_sem_wait(startup->psem_first);
747
748 #if defined(__DARWIN__)
749         t->mach_thread = mach_thread_self();
750 #endif
751
752         /* Now that we are in the new thread, we can store the internal
753            thread data-structure in the TSD. */
754
755         thread_set_current(t);
756
757 #if defined(ENABLE_GC_BOEHM)
758 # if defined(__DARWIN__)
759         // This is currently not implemented in Boehm-GC.  Just fail silently.
760 # else
761         /* Register the thread with Boehm-GC.  This must happen before the
762            thread allocates any memory from the GC heap.*/
763
764         result = GC_get_stack_base(&sb);
765
766         if (result != 0)
767                 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
768
769         GC_register_my_thread(&sb);
770 # endif
771 #endif
772
773         // Get the java.lang.Thread object for this thread.
774         java_handle_t* object = thread_get_object(t);
775         java_lang_Thread jlt(object);
776
777         /* set our priority */
778
779         threads_set_thread_priority(t->tid, jlt.get_priority());
780
781         /* Thread is completely initialized. */
782
783         thread_set_state_runnable(t);
784
785         /* tell threads_startup_thread that we registered ourselves */
786         /* CAUTION: *startup becomes invalid with this!             */
787
788         startup = NULL;
789         threads_sem_post(psem);
790
791 #if defined(ENABLE_INTRP)
792         /* set interpreter stack */
793
794         if (opt_intrp)
795                 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
796 #endif
797
798 #if defined(ENABLE_JVMTI)
799         /* fire thread start event */
800
801         if (jvmti) 
802                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
803 #endif
804
805         DEBUGTHREADS("starting", t);
806
807         /* find and run the Thread.run()V method if no other function was passed */
808
809         if (function == NULL) {
810 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
811                 /* We need to start the run method of
812                    java.lang.VMThread. Since this is a final class, we can use
813                    the class object directly. */
814
815                 c = class_java_lang_VMThread;
816 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
817                 LLNI_class_get(object, c);
818 #else
819 # error unknown classpath configuration
820 #endif
821
822                 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
823
824                 if (m == NULL)
825                         vm_abort("threads_startup_thread: run() method not found in class");
826
827                 /* set ThreadMXBean variables */
828
829 /*              _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
830 /*              _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
831
832 /*              if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
833 /*                      _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
834 /*                      _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
835 /*                              _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
836 #warning Move to C++
837
838 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
839
840                 // We need to start the run method of java.lang.VMThread.
841                 java_lang_VMThread jlvmt(jlt.get_vmThread());
842                 java_handle_t* h = jlvmt.get_handle();
843
844 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
845
846                 java_handle_t* h = jlt.get_handle();
847
848 #else
849 # error unknown classpath configuration
850 #endif
851
852                 /* Run the thread. */
853
854                 (void) vm_call_method(m, h);
855         }
856         else {
857                 /* set ThreadMXBean variables */
858
859 /*              _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
860 /*              _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
861
862 /*              if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
863 /*                      _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
864 /*                      _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
865 /*                              _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
866 #warning Move to C++
867
868                 /* call passed function, e.g. finalizer_thread */
869
870                 (function)();
871         }
872
873         DEBUGTHREADS("stopping", t);
874
875 #if defined(ENABLE_JVMTI)
876         /* fire thread end event */
877
878         if (jvmti)
879                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
880 #endif
881
882         /* We ignore the return value. */
883
884         (void) thread_detach_current_thread();
885
886         /* set ThreadMXBean variables */
887
888 /*      _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--; */
889 #warning Move to C++
890
891         return NULL;
892 }
893
894
895 /* threads_impl_thread_start ***************************************************
896
897    Start a thread in the JVM.  Both (vm internal and java) thread
898    objects exist.
899
900    IN:
901       thread....the thread object
902           f.........function to run in the new thread. NULL means that the
903                     "run" method of the object `t` should be called
904
905 ******************************************************************************/
906
907 void threads_impl_thread_start(threadobject *thread, functionptr f)
908 {
909         sem_t          sem;
910         sem_t          sem_first;
911         pthread_attr_t attr;
912         startupinfo    startup;
913         int            result;
914
915         /* fill startupinfo structure passed by pthread_create to
916          * threads_startup_thread */
917
918         startup.thread     = thread;
919         startup.function   = f;              /* maybe we don't call Thread.run()V */
920         startup.psem       = &sem;
921         startup.psem_first = &sem_first;
922
923         threads_sem_init(&sem, 0, 0);
924         threads_sem_init(&sem_first, 0, 0);
925
926         /* Initialize thread attributes. */
927
928         result = pthread_attr_init(&attr);
929
930         if (result != 0)
931                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
932
933     result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
934
935     if (result != 0)
936                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
937
938         /* initialize thread stacksize */
939
940         result = pthread_attr_setstacksize(&attr, opt_stacksize);
941
942         if (result != 0)
943                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
944
945         /* create the thread */
946
947         result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
948
949         if (result != 0)
950                 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
951
952         /* destroy the thread attributes */
953
954         result = pthread_attr_destroy(&attr);
955
956         if (result != 0)
957                 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
958
959         /* signal that pthread_create has returned, so thread->tid is valid */
960
961         threads_sem_post(&sem_first);
962
963         /* wait here until the thread has entered itself into the thread list */
964
965         threads_sem_wait(&sem);
966
967         /* cleanup */
968
969         sem_destroy(&sem);
970         sem_destroy(&sem_first);
971 }
972
973
974 /* threads_set_thread_priority *************************************************
975
976    Set the priority of the given thread.
977
978    IN:
979       tid..........thread id
980           priority.....priority to set
981
982 ******************************************************************************/
983
984 void threads_set_thread_priority(pthread_t tid, int priority)
985 {
986         struct sched_param schedp;
987         int policy;
988
989         pthread_getschedparam(tid, &policy, &schedp);
990         schedp.sched_priority = priority;
991         pthread_setschedparam(tid, policy, &schedp);
992 }
993
994
995 /**
996  * Detaches the current thread from the VM.
997  *
998  * @return true on success, false otherwise
999  */
1000 bool thread_detach_current_thread(void)
1001 {
1002         threadobject* t = thread_get_current();
1003
1004         /* Sanity check. */
1005
1006         assert(t != NULL);
1007
1008     /* If the given thread has already been detached, this operation
1009            is a no-op. */
1010
1011         if (thread_is_attached(t) == false)
1012                 return true;
1013
1014         DEBUGTHREADS("detaching", t);
1015
1016         java_handle_t* object = thread_get_object(t);
1017         java_lang_Thread jlt(object);
1018
1019 #if defined(ENABLE_JAVASE)
1020         java_handle_t* group = jlt.get_group();
1021
1022     /* If there's an uncaught exception, call uncaughtException on the
1023        thread's exception handler, or the thread's group if this is
1024        unset. */
1025
1026         java_handle_t* e = exceptions_get_and_clear_exception();
1027
1028     if (e != NULL) {
1029                 /* We use the type void* for handler here, as it's not trivial
1030                    to build the java_lang_Thread_UncaughtExceptionHandler
1031                    header file with cacaoh. */
1032
1033 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1034
1035                 java_handle_t* handler = jlt.get_exceptionHandler();
1036
1037 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1038
1039                 java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
1040
1041 # endif
1042
1043                 classinfo*     c;
1044                 java_handle_t* h;
1045
1046                 if (handler != NULL) {
1047                         LLNI_class_get(handler, c);
1048                         h = (java_handle_t *) handler;
1049                 }
1050                 else {
1051                         LLNI_class_get(group, c);
1052                         h = (java_handle_t *) group;
1053                 }
1054
1055                 methodinfo* m = class_resolveclassmethod(c,
1056                                                                                                  utf_uncaughtException,
1057                                                                                                  utf_java_lang_Thread_java_lang_Throwable__V,
1058                                                                                                  NULL,
1059                                                                                                  true);
1060
1061                 if (m == NULL)
1062                         return false;
1063
1064                 (void) vm_call_method(m, h, object, e);
1065
1066                 if (exceptions_get_exception())
1067                         return false;
1068     }
1069
1070         /* XXX TWISTI: should all threads be in a ThreadGroup? */
1071
1072         /* Remove thread from the thread group. */
1073
1074         if (group != NULL) {
1075                 classinfo* c;
1076                 LLNI_class_get(group, c);
1077
1078 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1079                 methodinfo* m = class_resolveclassmethod(c,
1080                                                                                                  utf_removeThread,
1081                                                                                                  utf_java_lang_Thread__V,
1082                                                                                                  class_java_lang_ThreadGroup,
1083                                                                                                  true);
1084 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1085                 methodinfo* m = class_resolveclassmethod(c,
1086                                                                                                  utf_remove,
1087                                                                                                  utf_java_lang_Thread__V,
1088                                                                                                  class_java_lang_ThreadGroup,
1089                                                                                                  true);
1090 # else
1091 #  error unknown classpath configuration
1092 # endif
1093
1094                 if (m == NULL)
1095                         return false;
1096
1097                 (void) vm_call_method(m, group, object);
1098
1099                 if (exceptions_get_exception())
1100                         return false;
1101
1102                 // Clear the ThreadGroup in the Java thread object (Mauve
1103                 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
1104                 jlt.set_group(NULL);
1105         }
1106 #endif
1107
1108         /* Thread has terminated. */
1109
1110         thread_set_state_terminated(t);
1111
1112         /* Notify all threads waiting on this thread.  These are joining
1113            this thread. */
1114
1115         /* XXX Care about exceptions? */
1116         (void) lock_monitor_enter(jlt.get_handle());
1117         
1118         lock_notify_all_object(jlt.get_handle());
1119
1120         /* XXX Care about exceptions? */
1121         (void) lock_monitor_exit(jlt.get_handle());
1122
1123         /* Enter the join-mutex before calling thread_free, so
1124            threads_join_all_threads gets the correct number of non-daemon
1125            threads. */
1126
1127         threads_mutex_join_lock();
1128
1129         /* Free the internal thread data-structure. */
1130
1131         thread_free(t);
1132
1133         /* Signal that this thread has finished and leave the mutex. */
1134
1135         cond_join->signal();
1136         threads_mutex_join_unlock();
1137
1138         return true;
1139 }
1140
1141
1142 /* threads_suspend_thread ******************************************************
1143
1144    Suspend the passed thread. Execution stops until the thread
1145    is explicitly resumend again.
1146
1147    IN:
1148      reason.....Reason for suspending this thread.
1149
1150 *******************************************************************************/
1151
1152 bool threads_suspend_thread(threadobject *thread, s4 reason)
1153 {
1154         /* acquire the suspendmutex */
1155         thread->suspendmutex->lock();
1156
1157         if (thread->suspended) {
1158                 thread->suspendmutex->unlock();
1159                 return false;
1160         }
1161
1162         /* set the reason for the suspension */
1163         thread->suspend_reason = reason;
1164
1165         /* send the suspend signal to the thread */
1166         assert(thread != THREADOBJECT);
1167         if (pthread_kill(thread->tid, SIGUSR1) != 0)
1168                 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1169                                  strerror(errno));
1170
1171         /* REMEMBER: do not release the suspendmutex, this is done
1172            by the thread itself in threads_suspend_ack().  */
1173
1174         return true;
1175 }
1176
1177
1178 /* threads_suspend_ack *********************************************************
1179
1180    Acknowledges the suspension of the current thread.
1181
1182    IN:
1183      pc.....The PC where the thread suspended its execution.
1184      sp.....The SP before the thread suspended its execution.
1185
1186 *******************************************************************************/
1187
1188 #if defined(ENABLE_GC_CACAO)
1189 void threads_suspend_ack(u1* pc, u1* sp)
1190 {
1191         threadobject *thread;
1192
1193         thread = THREADOBJECT;
1194
1195         assert(thread->suspend_reason != 0);
1196
1197         /* TODO: remember dump memory size */
1198
1199         /* inform the GC about the suspension */
1200         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1201
1202                 /* check if the GC wants to leave the thread running */
1203                 if (!gc_suspend(thread, pc, sp)) {
1204
1205                         /* REMEMBER: we do not unlock the suspendmutex because the thread
1206                            will suspend itself again at a later time */
1207                         return;
1208
1209                 }
1210         }
1211
1212         /* mark this thread as suspended and remember the PC */
1213         thread->pc        = pc;
1214         thread->suspended = true;
1215
1216         /* if we are stopping the world, we should send a global ack */
1217         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1218                 threads_sem_post(&suspend_ack);
1219         }
1220
1221         DEBUGTHREADS("suspending", thread);
1222
1223         /* release the suspension mutex and wait till we are resumed */
1224         thread->suspendcond->wait(thread->suspendmutex);
1225
1226         DEBUGTHREADS("resuming", thread);
1227
1228         /* if we are stopping the world, we should send a global ack */
1229         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1230                 threads_sem_post(&suspend_ack);
1231         }
1232
1233         /* TODO: free dump memory */
1234
1235         /* release the suspendmutex */
1236         thread->suspendmutex->unlock();
1237 }
1238 #endif
1239
1240
1241 /* threads_resume_thread *******************************************************
1242
1243    Resumes the execution of the passed thread.
1244
1245 *******************************************************************************/
1246
1247 #if defined(ENABLE_GC_CACAO)
1248 bool threads_resume_thread(threadobject *thread)
1249 {
1250         /* acquire the suspendmutex */
1251         thread->suspendmutex->lock();
1252
1253         if (!thread->suspended) {
1254                 thread->suspendmutex->unlock();
1255                 return false;
1256         }
1257
1258         thread->suspended = false;
1259
1260         /* tell everyone that the thread should resume */
1261         assert(thread != THREADOBJECT);
1262         thread->suspendcond->broadcast();
1263
1264         /* release the suspendmutex */
1265         thread->suspendmutex->unlock();
1266
1267         return true;
1268 }
1269 #endif
1270
1271
1272 /* threads_join_all_threads ****************************************************
1273
1274    Join all non-daemon threads.
1275
1276 *******************************************************************************/
1277
1278 void threads_join_all_threads(void)
1279 {
1280         threadobject *t;
1281
1282         /* get current thread */
1283
1284         t = THREADOBJECT;
1285
1286         /* This thread is waiting for all non-daemon threads to exit. */
1287
1288         thread_set_state_waiting(t);
1289
1290         /* enter join mutex */
1291
1292         threads_mutex_join_lock();
1293
1294         /* Wait for condition as long as we have non-daemon threads.  We
1295            compare against 1 because the current (main thread) is also a
1296            non-daemon thread. */
1297
1298         while (ThreadList::get_number_of_non_daemon_threads() > 1)
1299                 cond_join->wait(mutex_join);
1300
1301         /* leave join mutex */
1302
1303         threads_mutex_join_unlock();
1304 }
1305
1306
1307 /* threads_timespec_earlier ****************************************************
1308
1309    Return true if timespec tv1 is earlier than timespec tv2.
1310
1311    IN:
1312       tv1..........first timespec
1313           tv2..........second timespec
1314
1315    RETURN VALUE:
1316       true, if the first timespec is earlier
1317
1318 *******************************************************************************/
1319
1320 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1321                                                                                         const struct timespec *tv2)
1322 {
1323         return (tv1->tv_sec < tv2->tv_sec)
1324                                 ||
1325                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1326 }
1327
1328
1329 /* threads_current_time_is_earlier_than ****************************************
1330
1331    Check if the current time is earlier than the given timespec.
1332
1333    IN:
1334       tv...........the timespec to compare against
1335
1336    RETURN VALUE:
1337       true, if the current time is earlier
1338
1339 *******************************************************************************/
1340
1341 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1342 {
1343         struct timeval tvnow;
1344         struct timespec tsnow;
1345
1346         /* get current time */
1347
1348         if (gettimeofday(&tvnow, NULL) != 0)
1349                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1350
1351         /* convert it to a timespec */
1352
1353         tsnow.tv_sec = tvnow.tv_sec;
1354         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1355
1356         /* compare current time with the given timespec */
1357
1358         return threads_timespec_earlier(&tsnow, tv);
1359 }
1360
1361
1362 /* threads_wait_with_timeout ***************************************************
1363
1364    Wait until the given point in time on a monitor until either
1365    we are notified, we are interrupted, or the time is up.
1366
1367    IN:
1368       t............the current thread
1369           wakeupTime...absolute (latest) wakeup time
1370                            If both tv_sec and tv_nsec are zero, this function
1371                                            waits for an unlimited amount of time.
1372
1373 *******************************************************************************/
1374
1375 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1376 {
1377         // Acquire the waitmutex.
1378         t->waitmutex->lock();
1379
1380         /* wait on waitcond */
1381
1382         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1383                 /* with timeout */
1384                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1385                            && threads_current_time_is_earlier_than(wakeupTime))
1386                 {
1387                         if (parking)
1388                                 thread_set_state_timed_parked(t);
1389                         else
1390                                 thread_set_state_timed_waiting(t);
1391
1392                         t->waitcond->timedwait(t->waitmutex, wakeupTime);
1393
1394                         thread_set_state_runnable(t);
1395                 }
1396         }
1397         else {
1398                 /* no timeout */
1399                 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1400                         if (parking)
1401                                 thread_set_state_parked(t);
1402                         else
1403                                 thread_set_state_waiting(t);
1404
1405                         t->waitcond->wait(t->waitmutex);
1406
1407                         thread_set_state_runnable(t);
1408                 }
1409         }
1410
1411         if (parking)
1412                 t->park_permit = false;
1413
1414         // Release the waitmutex.
1415         t->waitmutex->unlock();
1416 }
1417
1418
1419 /* threads_wait_with_timeout_relative ******************************************
1420
1421    Wait for the given maximum amount of time on a monitor until either
1422    we are notified, we are interrupted, or the time is up.
1423
1424    IN:
1425       t............the current thread
1426           millis.......milliseconds to wait
1427           nanos........nanoseconds to wait
1428
1429 *******************************************************************************/
1430
1431 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1432                                                                                 s4 nanos)
1433 {
1434         struct timespec wakeupTime;
1435
1436         /* calculate the the (latest) wakeup time */
1437
1438         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1439
1440         /* wait */
1441
1442         threads_wait_with_timeout(thread, &wakeupTime, false);
1443 }
1444
1445
1446 /* threads_calc_absolute_time **************************************************
1447
1448    Calculate the absolute point in time a given number of ms and ns from now.
1449
1450    IN:
1451       millis............milliseconds from now
1452           nanos.............nanoseconds from now
1453
1454    OUT:
1455       *tm...............receives the timespec of the absolute point in time
1456
1457 *******************************************************************************/
1458
1459 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1460 {
1461         // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1462         do {
1463                 if (!millis && !nanos)
1464                         break;
1465                 struct timeval tv;
1466                 gettimeofday(&tv, NULL);
1467                 s8 secs = tv.tv_sec + millis / 1000;
1468                 if (secs > INT32_MAX)   // integer overflow
1469                         break;
1470                 tv.tv_sec = secs;
1471                 millis %= 1000;
1472                 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1473                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1474                 if (tm->tv_sec < tv.tv_sec) // integer overflow
1475                         break;
1476                 tm->tv_nsec = nsec % 1000000000;
1477                 return;
1478         } while (0);
1479         tm->tv_sec = 0;
1480         tm->tv_nsec = 0;
1481 }
1482
1483
1484 /* threads_thread_interrupt ****************************************************
1485
1486    Interrupt the given thread.
1487
1488    The thread gets the "waitcond" signal and 
1489    its interrupted flag is set to true.
1490
1491    IN:
1492       thread............the thread to interrupt
1493
1494 *******************************************************************************/
1495
1496 void threads_thread_interrupt(threadobject *t)
1497 {
1498         /* Signal the thread a "waitcond" and tell it that it has been
1499            interrupted. */
1500
1501         t->waitmutex->lock();
1502
1503         DEBUGTHREADS("interrupted", t);
1504
1505         /* Interrupt blocking system call using a signal. */
1506
1507         pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1508
1509         t->waitcond->signal();
1510
1511         t->interrupted = true;
1512
1513         t->waitmutex->unlock();
1514 }
1515
1516
1517 /**
1518  * Sleep the current thread for the specified amount of time.
1519  *
1520  * @param millis Milliseconds to sleep.
1521  * @param nanos  Nanoseconds to sleep.
1522  */
1523 void threads_sleep(int64_t millis, int32_t nanos)
1524 {
1525         threadobject    *t;
1526         struct timespec  wakeupTime;
1527         bool             interrupted;
1528
1529         if (millis < 0) {
1530 /*              exceptions_throw_illegalargumentexception("timeout value is negative"); */
1531                 exceptions_throw_illegalargumentexception();
1532                 return;
1533         }
1534
1535         t = thread_get_current();
1536
1537         if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1538                 /* Clear interrupted flag (Mauve test:
1539                    gnu/testlet/java/lang/Thread/interrupt). */
1540
1541                 thread_set_interrupted(t, false);
1542
1543 /*              exceptions_throw_interruptedexception("sleep interrupted"); */
1544                 exceptions_throw_interruptedexception();
1545                 return;
1546         }
1547
1548         // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1549         // Note: JDK treats a zero length sleep is like Thread.yield(),
1550         // without checking the interrupted status of the thread.  It's
1551         // unclear if this is a bug in the implementation or the spec.
1552         // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1553         if (millis == 0 && nanos == 0) {
1554                 threads_yield();
1555         }
1556         else {
1557                 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1558
1559                 threads_wait_with_timeout(t, &wakeupTime, false);
1560
1561                 interrupted = thread_is_interrupted(t);
1562
1563                 if (interrupted) {
1564                         thread_set_interrupted(t, false);
1565
1566                         // An other exception could have been thrown
1567                         // (e.g. ThreadDeathException).
1568                         if (!exceptions_get_exception())
1569                                 exceptions_throw_interruptedexception();
1570                 }
1571         }
1572 }
1573
1574 /**
1575  * Park the current thread for the specified amount of time or until a
1576  * specified deadline.
1577  *
1578  * @param absolute Is the time in nanos a deadline or a duration?
1579  * @param nanos    Nanoseconds to park (absolute=false)
1580  *                 or deadline in milliseconds (absolute=true)
1581  */
1582 void threads_park(bool absolute, int64_t nanos)
1583 {
1584         threadobject    *t;
1585         struct timespec  wakeupTime;
1586
1587         t = thread_get_current();
1588
1589         if (absolute) {
1590                 wakeupTime.tv_nsec = 0;
1591                 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1592         }
1593         else
1594                 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1595
1596         threads_wait_with_timeout(t, &wakeupTime, true);
1597 }
1598
1599 /**
1600  * Unpark the specified thread.
1601  *
1602  * @param t The thread to unpark.
1603  */
1604 void threads_unpark(threadobject *t)
1605 {
1606         t->waitmutex->lock();
1607
1608         t->waitcond->signal();
1609
1610         t->park_permit = true;
1611
1612         t->waitmutex->unlock();
1613 }
1614
1615
1616 /* threads_yield ***************************************************************
1617
1618    Yield to the scheduler.
1619
1620 *******************************************************************************/
1621
1622 void threads_yield(void)
1623 {
1624         sched_yield();
1625 }
1626
1627 #if defined(ENABLE_TLH)
1628
1629 void threads_tlh_add_frame() {
1630         tlh_add_frame(&(THREADOBJECT->tlh));
1631 }
1632
1633 void threads_tlh_remove_frame() {
1634         tlh_remove_frame(&(THREADOBJECT->tlh));
1635 }
1636
1637 #endif
1638
1639
1640 /*
1641  * These are local overrides for various environment variables in Emacs.
1642  * Please do not remove this and leave it at the end of the file, where
1643  * Emacs will automagically detect them.
1644  * ---------------------------------------------------------------------
1645  * Local variables:
1646  * mode: c++
1647  * indent-tabs-mode: t
1648  * c-basic-offset: 4
1649  * tab-width: 4
1650  * End:
1651  * vim:noexpandtab:sw=4:ts=4:
1652  */