* src/threads/threads-common.c [ENABLE_GC_CACAO]: References to java.lang.Thread
[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 8052 2007-06-10 13:44:33Z 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 #if defined(ENABLE_GC_CACAO)
60 # include "mm/cacao-gc/gc.h"
61 #endif
62
63 #include "native/jni.h"
64 #include "native/native.h"
65 #include "native/include/java_lang_Object.h"
66 #include "native/include/java_lang_String.h"
67 #include "native/include/java_lang_Throwable.h"
68 #include "native/include/java_lang_Thread.h"
69
70 #if defined(ENABLE_JAVASE)
71 # include "native/include/java_lang_ThreadGroup.h"
72 #endif
73
74 #if defined(WITH_CLASSPATH_GNU)
75 # include "native/include/java_lang_VMThread.h"
76 #endif
77
78 #include "threads/lock-common.h"
79 #include "threads/threads-common.h"
80
81 #include "threads/native/threads.h"
82
83 #include "toolbox/logging.h"
84
85 #include "vm/builtin.h"
86 #include "vm/exceptions.h"
87 #include "vm/global.h"
88 #include "vm/stringlocal.h"
89 #include "vm/vm.h"
90
91 #include "vm/jit/asmpart.h"
92
93 #include "vmcore/options.h"
94
95 #if defined(ENABLE_STATISTICS)
96 # include "vmcore/statistics.h"
97 #endif
98
99 #if !defined(__DARWIN__)
100 # if defined(__LINUX__)
101 #  define GC_LINUX_THREADS
102 # elif defined(__MIPS__)
103 #  define GC_IRIX_THREADS
104 # endif
105 # include <semaphore.h>
106 # if defined(ENABLE_GC_BOEHM)
107 #  include "mm/boehm-gc/include/gc.h"
108 # endif
109 #endif
110
111 #if defined(ENABLE_JVMTI)
112 #include "native/jvmti/cacaodbg.h"
113 #endif
114
115 #if defined(__DARWIN__)
116 /* Darwin has no working semaphore implementation.  This one is taken
117    from Boehm-GC. */
118
119 /*
120    This is a very simple semaphore implementation for darwin. It
121    is implemented in terms of pthreads calls so it isn't async signal
122    safe. This isn't a problem because signals aren't used to
123    suspend threads on darwin.
124 */
125    
126 static int sem_init(sem_t *sem, int pshared, int value)
127 {
128         if (pshared)
129                 assert(0);
130
131         sem->value = value;
132     
133         if (pthread_mutex_init(&sem->mutex, NULL) < 0)
134                 return -1;
135
136         if (pthread_cond_init(&sem->cond, NULL) < 0)
137                 return -1;
138
139         return 0;
140 }
141
142 static int sem_post(sem_t *sem)
143 {
144         if (pthread_mutex_lock(&sem->mutex) < 0)
145                 return -1;
146
147         sem->value++;
148
149         if (pthread_cond_signal(&sem->cond) < 0) {
150                 pthread_mutex_unlock(&sem->mutex);
151                 return -1;
152         }
153
154         if (pthread_mutex_unlock(&sem->mutex) < 0)
155                 return -1;
156
157         return 0;
158 }
159
160 static int sem_wait(sem_t *sem)
161 {
162         if (pthread_mutex_lock(&sem->mutex) < 0)
163                 return -1;
164
165         while (sem->value == 0) {
166                 pthread_cond_wait(&sem->cond, &sem->mutex);
167         }
168
169         sem->value--;
170
171         if (pthread_mutex_unlock(&sem->mutex) < 0)
172                 return -1;    
173
174         return 0;
175 }
176
177 static int sem_destroy(sem_t *sem)
178 {
179         if (pthread_cond_destroy(&sem->cond) < 0)
180                 return -1;
181
182         if (pthread_mutex_destroy(&sem->mutex) < 0)
183                 return -1;
184
185         return 0;
186 }
187 #endif /* defined(__DARWIN__) */
188
189
190 /* internally used constants **************************************************/
191
192 /* CAUTION: Do not change these values. Boehm GC code depends on them.        */
193 #define STOPWORLD_FROM_GC               1
194 #define STOPWORLD_FROM_CLASS_NUMBERING  2
195
196
197 /* startupinfo *****************************************************************
198
199    Struct used to pass info from threads_start_thread to 
200    threads_startup_thread.
201
202 ******************************************************************************/
203
204 typedef struct {
205         threadobject *thread;      /* threadobject for this thread             */
206         functionptr   function;    /* function to run in the new thread        */
207         sem_t        *psem;        /* signals when thread has been entered     */
208                                    /* in the thread list                       */
209         sem_t        *psem_first;  /* signals when pthread_create has returned */
210 } startupinfo;
211
212
213 /* prototypes *****************************************************************/
214
215 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
216
217
218 /******************************************************************************/
219 /* GLOBAL VARIABLES                                                           */
220 /******************************************************************************/
221
222 static methodinfo *method_thread_init;
223
224 /* the thread object of the current thread                                    */
225 /* This is either a thread-local variable defined with __thread, or           */
226 /* a thread-specific value stored with key threads_current_threadobject_key.  */
227 #if defined(HAVE___THREAD)
228 __thread threadobject *threads_current_threadobject;
229 #else
230 pthread_key_t threads_current_threadobject_key;
231 #endif
232
233 /* global mutex for the threads table */
234 static pthread_mutex_t mutex_threads_list;
235
236 /* global mutex for stop-the-world                                            */
237 static pthread_mutex_t stopworldlock;
238
239 /* global mutex and condition for joining threads on exit */
240 static pthread_mutex_t mutex_join;
241 static pthread_cond_t  cond_join;
242
243 /* XXX We disable that whole bunch of code until we have the exact-GC
244    running. */
245
246 #if 1
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 #endif /* 0 */
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 /* lock_stopworld **************************************************************
350
351    Enter the stopworld lock, specifying why the world shall be stopped.
352
353    IN:
354       where........ STOPWORLD_FROM_GC              (1) from within GC
355                     STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
356
357 ******************************************************************************/
358
359 void lock_stopworld(int where)
360 {
361         pthread_mutex_lock(&stopworldlock);
362 /*      stopworldwhere = where; */
363 }
364
365
366 /* unlock_stopworld ************************************************************
367
368    Release the stopworld lock.
369
370 ******************************************************************************/
371
372 void unlock_stopworld(void)
373 {
374 /*      stopworldwhere = 0; */
375         pthread_mutex_unlock(&stopworldlock);
376 }
377
378 /* XXX We disable that whole bunch of code until we have the exact-GC
379    running. */
380
381 #if 0
382
383 #if !defined(__DARWIN__)
384 /* Caller must hold threadlistlock */
385 static s4 threads_cast_sendsignals(s4 sig)
386 {
387         threadobject *t;
388         threadobject *self;
389         s4            count;
390
391         self = THREADOBJECT;
392
393         /* iterate over all started threads */
394
395         count = 0;
396
397         for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
398                 /* don't send the signal to ourself */
399
400                 if (t == self)
401                         continue;
402
403                 /* don't send the signal to NEW threads (because they are not
404                    completely initialized) */
405
406                 if (t->state == THREAD_STATE_NEW)
407                         continue;
408
409                 /* send the signal */
410
411                 pthread_kill(t->tid, sig);
412
413                 /* increase threads count */
414
415                 count++;
416         }
417
418         return count;
419 }
420
421 #else
422
423 static void threads_cast_darwinstop(void)
424 {
425         threadobject *tobj = mainthreadobj;
426         threadobject *self = THREADOBJECT;
427
428         do {
429                 if (tobj != self)
430                 {
431                         thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
432                         mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
433 #if defined(__I386__)
434                         i386_thread_state_t thread_state;
435 #else
436                         ppc_thread_state_t thread_state;
437 #endif
438                         mach_port_t thread = tobj->mach_thread;
439                         kern_return_t r;
440
441                         r = thread_suspend(thread);
442
443                         if (r != KERN_SUCCESS)
444                                 vm_abort("thread_suspend failed");
445
446                         r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
447                                                                  &thread_state_count);
448
449                         if (r != KERN_SUCCESS)
450                                 vm_abort("thread_get_state failed");
451
452                         md_critical_section_restart((ucontext_t *) &thread_state);
453
454                         r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
455                                                                  thread_state_count);
456
457                         if (r != KERN_SUCCESS)
458                                 vm_abort("thread_set_state failed");
459                 }
460
461                 tobj = tobj->next;
462         } while (tobj != mainthreadobj);
463 }
464
465 static void threads_cast_darwinresume(void)
466 {
467         threadobject *tobj = mainthreadobj;
468         threadobject *self = THREADOBJECT;
469
470         do {
471                 if (tobj != self)
472                 {
473                         mach_port_t thread = tobj->mach_thread;
474                         kern_return_t r;
475
476                         r = thread_resume(thread);
477
478                         if (r != KERN_SUCCESS)
479                                 vm_abort("thread_resume failed");
480                 }
481
482                 tobj = tobj->next;
483         } while (tobj != mainthreadobj);
484 }
485
486 #endif
487
488 #if defined(__MIPS__)
489 static void threads_cast_irixresume(void)
490 {
491         pthread_mutex_lock(&suspend_ack_lock);
492         pthread_cond_broadcast(&suspend_cond);
493         pthread_mutex_unlock(&suspend_ack_lock);
494 }
495 #endif
496 #endif
497
498 #if !defined(__DARWIN__)
499 static void threads_sigsuspend_handler(ucontext_t *_uc)
500 {
501         int sig;
502         sigset_t sigs;
503
504         /* XXX TWISTI: this is just a quick hack */
505 #if defined(ENABLE_JIT)
506         md_critical_section_restart(_uc);
507 #endif
508
509         /* Do as Boehm does. On IRIX a condition variable is used for wake-up
510            (not POSIX async-safe). */
511 #if defined(__IRIX__)
512         pthread_mutex_lock(&suspend_ack_lock);
513         threads_sem_post(&suspend_ack);
514         pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
515         pthread_mutex_unlock(&suspend_ack_lock);
516 #elif defined(__CYGWIN__)
517         /* TODO */
518         assert(0);
519 #else
520
521         sig = GC_signum2();
522         sigfillset(&sigs);
523         sigdelset(&sigs, sig);
524         sigsuspend(&sigs);
525 #endif
526 }
527 #endif
528
529 /* threads_stopworld ***********************************************************
530
531    Stops the world from turning. All threads except the calling one
532    are suspended. The function returns as soon as all threads have
533    acknowledged their suspension.
534
535 *******************************************************************************/
536
537 #if !defined(DISABLE_GC)
538 void threads_stopworld(void)
539 {
540 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
541         threadobject *t;
542         threadobject *self;
543         bool result;
544         s4 count, i;
545 #endif
546
547         lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
548
549         /* lock the threads lists */
550
551         threads_list_lock();
552
553 #if defined(__DARWIN__)
554         threads_cast_darwinstop();
555 #elif defined(__CYGWIN__)
556         /* TODO */
557         assert(0);
558 #else
559         self = THREADOBJECT;
560
561         count = 0;
562
563         /* suspend all running threads */
564         for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
565                 /* don't send the signal to ourself */
566
567                 if (t == self)
568                         continue;
569
570                 /* don't send the signal to NEW threads (because they are not
571                    completely initialized) */
572
573                 if (t->state == THREAD_STATE_NEW)
574                         continue;
575
576                 /* send the signal */
577
578                 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
579                 assert(result);
580
581                 /* increase threads count */
582
583                 count++;
584         }
585
586         /* wait for all threads signaled to suspend */
587         for (i = 0; i < count; i++)
588                 threads_sem_wait(&suspend_ack);
589 #endif
590
591         /* ATTENTION: Don't unlock the threads-lists here so that
592            non-signaled NEW threads can't change their state and execute
593            code. */
594 }
595 #endif /* !defined(DISABLE_GC) */
596
597
598 /* threads_startworld **********************************************************
599
600    Starts the world again after it has previously been stopped. 
601
602 *******************************************************************************/
603
604 #if !defined(DISABLE_GC)
605 void threads_startworld(void)
606 {
607 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
608         threadobject *t;
609         threadobject *self;
610         bool result;
611         s4 count, i;
612 #endif
613
614 #if defined(__DARWIN__)
615         threads_cast_darwinresume();
616 #elif defined(__MIPS__)
617         threads_cast_irixresume();
618 #elif defined(__CYGWIN__)
619         /* TODO */
620         assert(0);
621 #else
622         self = THREADOBJECT;
623
624         count = 0;
625
626         /* resume all thread we haltet */
627         for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
628                 /* don't send the signal to ourself */
629
630                 if (t == self)
631                         continue;
632
633                 /* don't send the signal to NEW threads (because they are not
634                    completely initialized) */
635
636                 if (t->state == THREAD_STATE_NEW)
637                         continue;
638
639                 /* send the signal */
640
641                 result = threads_resume_thread(t);
642                 assert(result);
643
644                 /* increase threads count */
645
646                 count++;
647         }
648
649         /* wait for all threads signaled to suspend */
650         for (i = 0; i < count; i++)
651                 threads_sem_wait(&suspend_ack);
652
653 #endif
654
655         /* unlock the threads lists */
656
657         threads_list_unlock();
658
659         unlock_stopworld();
660 }
661 #endif
662
663
664 /* threads_set_current_threadobject ********************************************
665
666    Set the current thread object.
667    
668    IN:
669       thread.......the thread object to set
670
671 *******************************************************************************/
672
673 void threads_set_current_threadobject(threadobject *thread)
674 {
675 #if !defined(HAVE___THREAD)
676         if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
677                 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
678 #else
679         threads_current_threadobject = thread;
680 #endif
681 }
682
683
684 /* threads_impl_thread_new *****************************************************
685
686    Initialize implementation fields of a threadobject.
687
688    IN:
689       t....the threadobject
690
691 *******************************************************************************/
692
693 void threads_impl_thread_new(threadobject *t)
694 {
695         /* get the pthread id */
696
697         t->tid = pthread_self();
698
699         /* initialize the mutex and the condition */
700
701         pthread_mutex_init(&(t->waitmutex), NULL);
702         pthread_cond_init(&(t->waitcond), NULL);
703         pthread_mutex_init(&(t->suspendmutex), NULL);
704         pthread_cond_init(&(t->suspendcond), NULL);
705
706 #if defined(ENABLE_DEBUG_FILTER)
707         /* Initialize filter counters */
708         t->filterverbosecallctr[0] = 0;
709         t->filterverbosecallctr[1] = 0;
710 #endif
711 }
712
713
714 /* threads_impl_thread_free ****************************************************
715
716    Cleanup thread stuff.
717
718    IN:
719       t....the threadobject
720
721 *******************************************************************************/
722
723 void threads_impl_thread_free(threadobject *t)
724 {
725         /* destroy the mutex and the condition */
726
727         if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
728                 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
729                                  strerror(errno));
730
731         if (pthread_cond_destroy(&(t->waitcond)) != 0)
732                 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
733                                  strerror(errno));
734
735         if (pthread_mutex_destroy(&(t->suspendmutex)) != 0)
736                 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
737                                  strerror(errno));
738
739         if (pthread_cond_destroy(&(t->suspendcond)) != 0)
740                 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
741                                  strerror(errno));
742 }
743
744
745 /* threads_get_current_threadobject ********************************************
746
747    Return the threadobject of the current thread.
748    
749    RETURN VALUE:
750        the current threadobject *
751
752 *******************************************************************************/
753
754 threadobject *threads_get_current_threadobject(void)
755 {
756         return THREADOBJECT;
757 }
758
759
760 /* threads_impl_preinit ********************************************************
761
762    Do some early initialization of stuff required.
763
764    ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
765    is called AFTER this function!
766
767 *******************************************************************************/
768
769 void threads_impl_preinit(void)
770 {
771         pthread_mutex_init(&stopworldlock, NULL);
772
773         /* initialize exit mutex and condition (on exit we join all
774            threads) */
775
776         pthread_mutex_init(&mutex_join, NULL);
777         pthread_cond_init(&cond_join, NULL);
778
779         /* initialize the threads-list mutex */
780
781         pthread_mutex_init(&mutex_threads_list, NULL);
782
783 #if !defined(HAVE___THREAD)
784         pthread_key_create(&threads_current_threadobject_key, NULL);
785 #endif
786
787         threads_sem_init(&suspend_ack, 0, 0);
788 }
789
790
791 /* threads_list_lock ***********************************************************
792
793    Enter the threads table mutex.
794
795    NOTE: We need this function as we can't use an internal lock for
796          the threads lists because the thread's lock is initialized in
797          threads_table_add (when we have the thread index), but we
798          already need the lock at the entry of the function.
799
800 *******************************************************************************/
801
802 void threads_list_lock(void)
803 {
804         if (pthread_mutex_lock(&mutex_threads_list) != 0)
805                 vm_abort("threads_list_lock: pthread_mutex_lock failed: %s",
806                                  strerror(errno));
807 }
808
809
810 /* threads_list_unlock *********************************************************
811
812    Leave the threads list mutex.
813
814 *******************************************************************************/
815
816 void threads_list_unlock(void)
817 {
818         if (pthread_mutex_unlock(&mutex_threads_list) != 0)
819                 vm_abort("threads_list_unlock: pthread_mutex_unlock failed: %s",
820                                  strerror(errno));
821 }
822
823
824 /* threads_mutex_join_lock *****************************************************
825
826    Enter the join mutex.
827
828 *******************************************************************************/
829
830 void threads_mutex_join_lock(void)
831 {
832         if (pthread_mutex_lock(&mutex_join) != 0)
833                 vm_abort("threads_mutex_join_lock: pthread_mutex_lock failed: %s",
834                                  strerror(errno));
835 }
836
837
838 /* threads_mutex_join_unlock ***************************************************
839
840    Leave the join mutex.
841
842 *******************************************************************************/
843
844 void threads_mutex_join_unlock(void)
845 {
846         if (pthread_mutex_unlock(&mutex_join) != 0)
847                 vm_abort("threads_mutex_join_unlock: pthread_mutex_unlock failed: %s",
848                                  strerror(errno));
849 }
850
851
852 /* threads_init ****************************************************************
853
854    Initializes the threads required by the JVM: main, finalizer.
855
856 *******************************************************************************/
857
858 bool threads_init(void)
859 {
860         threadobject          *mainthread;
861         java_objectheader     *threadname;
862         java_lang_Thread      *t;
863         java_objectheader     *o;
864
865 #if defined(ENABLE_JAVASE)
866         java_lang_ThreadGroup *threadgroup;
867         methodinfo            *m;
868 #endif
869
870 #if defined(WITH_CLASSPATH_GNU)
871         java_lang_VMThread    *vmt;
872 #endif
873
874         pthread_attr_t attr;
875
876         /* get methods we need in this file */
877
878 #if defined(WITH_CLASSPATH_GNU)
879         method_thread_init =
880                 class_resolveclassmethod(class_java_lang_Thread,
881                                                                  utf_init,
882                                                                  utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
883                                                                  class_java_lang_Thread,
884                                                                  true);
885 #else
886         method_thread_init =
887                 class_resolveclassmethod(class_java_lang_Thread,
888                                                                  utf_init,
889                                                                  utf_new_char("(Ljava/lang/String;)V"),
890                                                                  class_java_lang_Thread,
891                                                                  true);
892 #endif
893
894         if (method_thread_init == NULL)
895                 return false;
896
897         /* Get the main-thread (NOTE: The main threads is always the first
898            thread in the list). */
899
900         mainthread = threads_list_first();
901
902 #if defined(ENABLE_GC_CACAO)
903         /* register reference to java.lang.Thread with the GC */
904
905         gc_reference_register((java_objectheader **) &(mainthread->object));
906 #endif
907
908         /* create a java.lang.Thread for the main thread */
909
910         t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
911
912         if (t == NULL)
913                 return false;
914
915         /* set the object in the internal data structure */
916
917         mainthread->object = t;
918
919 #if defined(ENABLE_INTRP)
920         /* create interpreter stack */
921
922         if (opt_intrp) {
923                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
924                 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
925         }
926 #endif
927
928         threadname = javastring_new(utf_new_char("main"));
929
930 #if defined(ENABLE_JAVASE)
931         /* allocate and init ThreadGroup */
932
933         threadgroup = (java_lang_ThreadGroup *)
934                 native_new_and_init(class_java_lang_ThreadGroup);
935
936         if (threadgroup == NULL)
937                 return false;
938 #endif
939
940 #if defined(WITH_CLASSPATH_GNU)
941         /* create a java.lang.VMThread for the main thread */
942
943         vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
944
945         if (vmt == NULL)
946                 return false;
947
948         /* set the thread */
949
950         vmt->thread = t;
951         vmt->vmdata = (java_lang_Object *) mainthread;
952
953         /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
954         o = (java_objectheader *) t;
955
956         (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
957                                                   false);
958 #elif defined(WITH_CLASSPATH_CLDC1_1)
959         /* set the thread */
960
961         t->vm_thread = (java_lang_Object *) mainthread;
962
963         /* call public Thread(String name) */
964
965         o = (java_objectheader *) t;
966
967         (void) vm_call_method(method_thread_init, o, threadname);
968 #endif
969
970         if (*exceptionptr)
971                 return false;
972
973 #if defined(ENABLE_JAVASE)
974         t->group = threadgroup;
975
976         /* add main thread to java.lang.ThreadGroup */
977
978         m = class_resolveclassmethod(class_java_lang_ThreadGroup,
979                                                                  utf_addThread,
980                                                                  utf_java_lang_Thread__V,
981                                                                  class_java_lang_ThreadGroup,
982                                                                  true);
983
984         o = (java_objectheader *) threadgroup;
985
986         (void) vm_call_method(m, o, t);
987
988         if (*exceptionptr)
989                 return false;
990 #endif
991
992         threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
993
994         /* initialize the thread attribute object */
995
996         if (pthread_attr_init(&attr) != 0)
997                 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
998
999         if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1000                 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
1001                                  strerror(errno));
1002
1003 #if !defined(NDEBUG)
1004         if (opt_verbosethreads) {
1005                 printf("[Starting thread ");
1006                 threads_thread_print_info(mainthread);
1007                 printf("]\n");
1008         }
1009 #endif
1010
1011         /* everything's ok */
1012
1013         return true;
1014 }
1015
1016
1017 /* threads_startup_thread ******************************************************
1018
1019    Thread startup function called by pthread_create.
1020
1021    Thread which have a startup.function != NULL are marked as internal
1022    threads. All other threads are threated as normal Java threads.
1023
1024    NOTE: This function is not called directly by pthread_create. The Boehm GC
1025          inserts its own GC_start_routine in between, which then calls
1026                  threads_startup.
1027
1028    IN:
1029       arg..........the argument passed to pthread_create, ie. a pointer to
1030                        a startupinfo struct. CAUTION: When the `psem` semaphore
1031                                    is posted, the startupinfo struct becomes invalid! (It
1032                                    is allocated on the stack of threads_start_thread.)
1033
1034 ******************************************************************************/
1035
1036 static void *threads_startup_thread(void *arg)
1037 {
1038         startupinfo        *startup;
1039         threadobject       *thread;
1040 #if defined(WITH_CLASSPATH_GNU)
1041         java_lang_VMThread *vmt;
1042 #endif
1043         sem_t              *psem;
1044         classinfo          *c;
1045         methodinfo         *m;
1046         java_objectheader  *o;
1047         functionptr         function;
1048
1049 #if defined(ENABLE_INTRP)
1050         u1 *intrp_thread_stack;
1051
1052         /* create interpreter stack */
1053
1054         if (opt_intrp) {
1055                 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1056                 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1057         }
1058         else
1059                 intrp_thread_stack = NULL;
1060 #endif
1061
1062         /* get passed startupinfo structure and the values in there */
1063
1064         startup = arg;
1065
1066         thread   = startup->thread;
1067         function = startup->function;
1068         psem     = startup->psem;
1069
1070         /* Seems like we've encountered a situation where thread->tid was
1071            not set by pthread_create. We alleviate this problem by waiting
1072            for pthread_create to return. */
1073
1074         threads_sem_wait(startup->psem_first);
1075
1076 #if defined(__DARWIN__)
1077         thread->mach_thread = mach_thread_self();
1078 #endif
1079
1080         /* store the internal thread data-structure in the TSD */
1081
1082         threads_set_current_threadobject(thread);
1083
1084         /* set our priority */
1085
1086         threads_set_thread_priority(thread->tid, thread->object->priority);
1087
1088         /* thread is completely initialized */
1089
1090         threads_thread_state_runnable(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 #if defined(ENABLE_INTRP)
1099         /* set interpreter stack */
1100
1101         if (opt_intrp)
1102                 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1103 #endif
1104
1105 #if defined(ENABLE_JVMTI)
1106         /* fire thread start event */
1107
1108         if (jvmti) 
1109                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1110 #endif
1111
1112 #if !defined(NDEBUG)
1113         if (opt_verbosethreads) {
1114                 printf("[Starting thread ");
1115                 threads_thread_print_info(thread);
1116                 printf("]\n");
1117         }
1118 #endif
1119
1120         /* find and run the Thread.run()V method if no other function was passed */
1121
1122         if (function == NULL) {
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                         vm_abort("threads_startup_thread: run() method not found in class");
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                 /* run the thread */
1159
1160                 (void) vm_call_method(m, o);
1161         }
1162         else {
1163                 /* set ThreadMXBean variables */
1164
1165                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1166                 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1167
1168                 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1169                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1170                         _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1171                                 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1172
1173                 /* call passed function, e.g. finalizer_thread */
1174
1175                 (function)();
1176         }
1177
1178 #if !defined(NDEBUG)
1179         if (opt_verbosethreads) {
1180                 printf("[Stopping thread ");
1181                 threads_thread_print_info(thread);
1182                 printf("]\n");
1183         }
1184 #endif
1185
1186 #if defined(ENABLE_JVMTI)
1187         /* fire thread end event */
1188
1189         if (jvmti)
1190                 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1191 #endif
1192
1193         if (!threads_detach_thread(thread))
1194                 vm_abort("threads_startup_thread: threads_detach_thread failed");
1195
1196         /* set ThreadMXBean variables */
1197
1198         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1199
1200         return NULL;
1201 }
1202
1203
1204 /* threads_impl_thread_start ***************************************************
1205
1206    Start a thread in the JVM.  Both (vm internal and java) thread
1207    objects exist.
1208
1209    IN:
1210       thread....the thread object
1211           f.........function to run in the new thread. NULL means that the
1212                     "run" method of the object `t` should be called
1213
1214 ******************************************************************************/
1215
1216 void threads_impl_thread_start(threadobject *thread, functionptr f)
1217 {
1218         sem_t          sem;
1219         sem_t          sem_first;
1220         pthread_attr_t attr;
1221         startupinfo    startup;
1222         int            ret;
1223
1224         /* fill startupinfo structure passed by pthread_create to
1225          * threads_startup_thread */
1226
1227         startup.thread     = thread;
1228         startup.function   = f;              /* maybe we don't call Thread.run()V */
1229         startup.psem       = &sem;
1230         startup.psem_first = &sem_first;
1231
1232         threads_sem_init(&sem, 0, 0);
1233         threads_sem_init(&sem_first, 0, 0);
1234
1235         /* initialize thread attributes */
1236
1237         if (pthread_attr_init(&attr) != 0)
1238                 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1239                                  strerror(errno));
1240
1241     if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1242                 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1243                                  strerror(errno));
1244
1245         /* initialize thread stacksize */
1246
1247         if (pthread_attr_setstacksize(&attr, opt_stacksize))
1248                 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1249                                  strerror(errno));
1250
1251         /* create the thread */
1252
1253         ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1254
1255         /* destroy the thread attributes */
1256
1257         if (pthread_attr_destroy(&attr) != 0)
1258                 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1259                                  strerror(errno));
1260
1261         /* check for pthread_create error */
1262
1263         if (ret != 0)
1264                 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1265                                  strerror(errno));
1266
1267         /* signal that pthread_create has returned, so thread->tid is valid */
1268
1269         threads_sem_post(&sem_first);
1270
1271         /* wait here until the thread has entered itself into the thread list */
1272
1273         threads_sem_wait(&sem);
1274
1275         /* cleanup */
1276
1277         sem_destroy(&sem);
1278         sem_destroy(&sem_first);
1279 }
1280
1281
1282 /* threads_set_thread_priority *************************************************
1283
1284    Set the priority of the given thread.
1285
1286    IN:
1287       tid..........thread id
1288           priority.....priority to set
1289
1290 ******************************************************************************/
1291
1292 void threads_set_thread_priority(pthread_t tid, int priority)
1293 {
1294         struct sched_param schedp;
1295         int policy;
1296
1297         pthread_getschedparam(tid, &policy, &schedp);
1298         schedp.sched_priority = priority;
1299         pthread_setschedparam(tid, policy, &schedp);
1300 }
1301
1302
1303 /* threads_attach_current_thread ***********************************************
1304
1305    Attaches the current thread to the VM.  Used in JNI.
1306
1307 *******************************************************************************/
1308
1309 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1310 {
1311         threadobject          *thread;
1312         utf                   *u;
1313         java_objectheader     *s;
1314         java_objectheader     *o;
1315         java_lang_Thread      *t;
1316
1317 #if defined(ENABLE_JAVASE)
1318         java_lang_ThreadGroup *group;
1319         threadobject          *mainthread;
1320         methodinfo            *m;
1321 #endif
1322
1323 #if defined(WITH_CLASSPATH_GNU)
1324         java_lang_VMThread    *vmt;
1325 #endif
1326
1327         /* Enter the join-mutex, so if the main-thread is currently
1328            waiting to join all threads, the number of non-daemon threads
1329            is correct. */
1330
1331         threads_mutex_join_lock();
1332
1333         /* create internal thread data-structure */
1334
1335         thread = threads_thread_new();
1336
1337         /* thread is a Java thread and running */
1338
1339         thread->flags = THREAD_FLAG_JAVA;
1340
1341         if (isdaemon)
1342                 thread->flags |= THREAD_FLAG_DAEMON;
1343
1344         /* The thread is flagged and (non-)daemon thread, we can leave the
1345            mutex. */
1346
1347         threads_mutex_join_unlock();
1348
1349         /* create a java.lang.Thread object */
1350
1351         t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1352
1353         /* XXX memory leak!!! */
1354         if (t == NULL)
1355                 return false;
1356
1357         thread->object = t;
1358
1359         /* thread is completely initialized */
1360
1361         threads_thread_state_runnable(thread);
1362
1363 #if !defined(NDEBUG)
1364         if (opt_verbosethreads) {
1365                 printf("[Attaching thread ");
1366                 threads_thread_print_info(thread);
1367                 printf("]\n");
1368         }
1369 #endif
1370
1371 #if defined(ENABLE_INTRP)
1372         /* create interpreter stack */
1373
1374         if (opt_intrp) {
1375                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1376                 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1377         }
1378 #endif
1379
1380 #if defined(WITH_CLASSPATH_GNU)
1381         /* create a java.lang.VMThread object */
1382
1383         vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1384
1385         /* XXX memory leak!!! */
1386         if (vmt == NULL)
1387                 return false;
1388
1389         /* set the thread */
1390
1391         vmt->thread = t;
1392         vmt->vmdata = (java_lang_Object *) thread;
1393 #elif defined(WITH_CLASSPATH_CLDC1_1)
1394         t->vm_thread = (java_lang_Object *) thread;
1395 #endif
1396
1397         if (vm_aargs != NULL) {
1398                 u     = utf_new_char(vm_aargs->name);
1399 #if defined(ENABLE_JAVASE)
1400                 group = (java_lang_ThreadGroup *) vm_aargs->group;
1401 #endif
1402         }
1403         else {
1404                 u     = utf_null;
1405 #if defined(ENABLE_JAVASE)
1406                 /* get the main thread */
1407
1408                 mainthread = threads_list_first();
1409                 group = mainthread->object->group;
1410 #endif
1411         }
1412
1413         /* the the thread name */
1414
1415         s = javastring_new(u);
1416
1417         /* for convenience */
1418
1419         o = (java_objectheader *) thread->object;
1420
1421 #if defined(WITH_CLASSPATH_GNU)
1422         (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1423                                                   isdaemon);
1424 #elif defined(WITH_CLASSPATH_CLDC1_1)
1425         (void) vm_call_method(method_thread_init, o, s);
1426 #endif
1427
1428         if (*exceptionptr)
1429                 return false;
1430
1431 #if defined(ENABLE_JAVASE)
1432         /* store the thread group in the object */
1433
1434         thread->object->group = group;
1435
1436         /* add thread to given thread-group */
1437
1438         m = class_resolveclassmethod(group->header.vftbl->class,
1439                                                                  utf_addThread,
1440                                                                  utf_java_lang_Thread__V,
1441                                                                  class_java_lang_ThreadGroup,
1442                                                                  true);
1443
1444         o = (java_objectheader *) group;
1445
1446         (void) vm_call_method(m, o, t);
1447
1448         if (*exceptionptr)
1449                 return false;
1450 #endif
1451
1452         return true;
1453 }
1454
1455
1456 /* threads_detach_thread *******************************************************
1457
1458    Detaches the passed thread from the VM.  Used in JNI.
1459
1460 *******************************************************************************/
1461
1462 bool threads_detach_thread(threadobject *thread)
1463 {
1464 #if defined(ENABLE_JAVASE)
1465         java_lang_ThreadGroup *group;
1466         methodinfo            *m;
1467         java_objectheader     *o;
1468         java_lang_Thread      *t;
1469 #endif
1470
1471         /* XXX implement uncaught exception stuff (like JamVM does) */
1472
1473 #if defined(ENABLE_JAVASE)
1474         /* remove thread from the thread group */
1475
1476         group = thread->object->group;
1477
1478         /* XXX TWISTI: should all threads be in a ThreadGroup? */
1479
1480         if (group != NULL) {
1481                 m = class_resolveclassmethod(group->header.vftbl->class,
1482                                                                          utf_removeThread,
1483                                                                          utf_java_lang_Thread__V,
1484                                                                          class_java_lang_ThreadGroup,
1485                                                                          true);
1486
1487                 if (m == NULL)
1488                         return false;
1489
1490                 o = (java_objectheader *) group;
1491                 t = thread->object;
1492
1493                 (void) vm_call_method(m, o, t);
1494
1495                 if (*exceptionptr)
1496                         return false;
1497         }
1498 #endif
1499
1500         /* thread is terminated */
1501
1502         threads_thread_state_terminated(thread);
1503
1504 #if !defined(NDEBUG)
1505         if (opt_verbosethreads) {
1506                 printf("[Detaching thread ");
1507                 threads_thread_print_info(thread);
1508                 printf("]\n");
1509         }
1510 #endif
1511
1512         /* Enter the join-mutex before calling threads_thread_free, so
1513            threads_join_all_threads gets the correct number of non-daemon
1514            threads. */
1515
1516         threads_mutex_join_lock();
1517
1518         /* free the vm internal thread object */
1519
1520         threads_thread_free(thread);
1521
1522         /* Signal that this thread has finished and leave the mutex. */
1523
1524         pthread_cond_signal(&cond_join);
1525         threads_mutex_join_unlock();
1526
1527         return true;
1528 }
1529
1530
1531 /* threads_suspend_thread ******************************************************
1532
1533    Suspend the passed thread. Execution stops until the thread
1534    is explicitly resumend again.
1535
1536    IN:
1537      reason.....Reason for suspending this thread.
1538
1539 *******************************************************************************/
1540
1541 bool threads_suspend_thread(threadobject *thread, s4 reason)
1542 {
1543         /* acquire the suspendmutex */
1544         if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1545                 vm_abort("threads_suspend_thread: pthread_mutex_lock failed: %s",
1546                                  strerror(errno));
1547
1548         if (thread->suspended) {
1549                 pthread_mutex_unlock(&(thread->suspendmutex));
1550                 return false;
1551         }
1552
1553         /* set the reason for the suspension */
1554         thread->suspend_reason = reason;
1555
1556         /* send the suspend signal to the thread */
1557         assert(thread != THREADOBJECT);
1558         if (pthread_kill(thread->tid, SIGUSR1) != 0)
1559                 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1560                                  strerror(errno));
1561
1562         /* REMEMBER: do not release the suspendmutex, this is done
1563            by the thread itself in threads_suspend_ack().  */
1564
1565         return true;
1566 }
1567
1568
1569 /* threads_suspend_ack *********************************************************
1570
1571    Acknowledges the suspension of the current thread.
1572
1573    IN:
1574      pc.....The PC where the thread suspended its execution.
1575      sp.....The SP before the thread suspended its execution.
1576
1577 *******************************************************************************/
1578
1579 void threads_suspend_ack(u1* pc, u1* sp)
1580 {
1581         threadobject *thread;
1582
1583         thread = THREADOBJECT;
1584
1585         assert(thread->suspend_reason != 0);
1586
1587         /* TODO: remember dump memory size */
1588
1589 #if defined(ENABLE_GC_CACAO)
1590         /* inform the GC about the suspension */
1591         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1592
1593                 /* check if the GC wants to leave the thread running */
1594                 if (!gc_suspend(thread, pc, sp)) {
1595
1596                         /* REMEMBER: we do not unlock the suspendmutex because the thread
1597                            will suspend itself again at a later time */
1598                         return;
1599
1600                 }
1601         }
1602 #endif
1603
1604         /* mark this thread as suspended and remember the PC */
1605         thread->pc        = pc;
1606         thread->suspended = true;
1607
1608         /* if we are stopping the world, we should send a global ack */
1609         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1610                 threads_sem_post(&suspend_ack);
1611         }
1612
1613         /* release the suspension mutex and wait till we are resumed */
1614         /*printf("thread down %p\n", thread);*/
1615         pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1616         /*printf("thread up %p\n", thread);*/
1617
1618         /* if we are stopping the world, we should send a global ack */
1619         if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1620                 threads_sem_post(&suspend_ack);
1621         }
1622
1623         /* TODO: free dump memory */
1624
1625         /* release the suspendmutex */
1626         if (pthread_mutex_unlock(&(thread->suspendmutex)) != 0)
1627                 vm_abort("threads_suspend_ack: pthread_mutex_unlock failed: %s",
1628                                  strerror(errno));
1629 }
1630
1631
1632 /* threads_resume_thread *******************************************************
1633
1634    Resumes the execution of the passed thread.
1635
1636 *******************************************************************************/
1637
1638 bool threads_resume_thread(threadobject *thread)
1639 {
1640         /* acquire the suspendmutex */
1641         if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1642                 vm_abort("threads_resume_ack: pthread_mutex_unlock failed: %s",
1643                                  strerror(errno));
1644
1645         if (!thread->suspended) {
1646                 pthread_mutex_unlock(&(thread->suspendmutex));
1647                 return false;
1648         }
1649
1650         thread->suspended = false;
1651
1652         /* tell everyone that the thread should resume */
1653         assert(thread != THREADOBJECT);
1654         pthread_cond_broadcast(&(thread->suspendcond));
1655
1656         /* release the suspendmutex */
1657         pthread_mutex_unlock(&(thread->suspendmutex));
1658
1659         return true;
1660 }
1661
1662
1663 /* threads_join_all_threads ****************************************************
1664
1665    Join all non-daemon threads.
1666
1667 *******************************************************************************/
1668
1669 void threads_join_all_threads(void)
1670 {
1671         threadobject *t;
1672
1673         /* get current thread */
1674
1675         t = THREADOBJECT;
1676
1677         /* this thread is waiting for all non-daemon threads to exit */
1678
1679         threads_thread_state_waiting(t);
1680
1681         /* enter join mutex */
1682
1683         threads_mutex_join_lock();
1684
1685         /* Wait for condition as long as we have non-daemon threads.  We
1686            compare against 1 because the current (main thread) is also a
1687            non-daemon thread. */
1688
1689         while (threads_list_get_non_daemons() > 1)
1690                 pthread_cond_wait(&cond_join, &mutex_join);
1691
1692         /* leave join mutex */
1693
1694         threads_mutex_join_unlock();
1695 }
1696
1697
1698 /* threads_timespec_earlier ****************************************************
1699
1700    Return true if timespec tv1 is earlier than timespec tv2.
1701
1702    IN:
1703       tv1..........first timespec
1704           tv2..........second timespec
1705
1706    RETURN VALUE:
1707       true, if the first timespec is earlier
1708
1709 *******************************************************************************/
1710
1711 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1712                                                                                         const struct timespec *tv2)
1713 {
1714         return (tv1->tv_sec < tv2->tv_sec)
1715                                 ||
1716                 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1717 }
1718
1719
1720 /* threads_current_time_is_earlier_than ****************************************
1721
1722    Check if the current time is earlier than the given timespec.
1723
1724    IN:
1725       tv...........the timespec to compare against
1726
1727    RETURN VALUE:
1728       true, if the current time is earlier
1729
1730 *******************************************************************************/
1731
1732 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1733 {
1734         struct timeval tvnow;
1735         struct timespec tsnow;
1736
1737         /* get current time */
1738
1739         if (gettimeofday(&tvnow, NULL) != 0)
1740                 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1741
1742         /* convert it to a timespec */
1743
1744         tsnow.tv_sec = tvnow.tv_sec;
1745         tsnow.tv_nsec = tvnow.tv_usec * 1000;
1746
1747         /* compare current time with the given timespec */
1748
1749         return threads_timespec_earlier(&tsnow, tv);
1750 }
1751
1752
1753 /* threads_wait_with_timeout ***************************************************
1754
1755    Wait until the given point in time on a monitor until either
1756    we are notified, we are interrupted, or the time is up.
1757
1758    IN:
1759       t............the current thread
1760           wakeupTime...absolute (latest) wakeup time
1761                            If both tv_sec and tv_nsec are zero, this function
1762                                            waits for an unlimited amount of time.
1763
1764    RETURN VALUE:
1765       true.........if the wait has been interrupted,
1766           false........if the wait was ended by notification or timeout
1767
1768 *******************************************************************************/
1769
1770 static bool threads_wait_with_timeout(threadobject *thread,
1771                                                                           struct timespec *wakeupTime)
1772 {
1773         bool wasinterrupted;
1774
1775         /* acquire the waitmutex */
1776
1777         pthread_mutex_lock(&thread->waitmutex);
1778
1779         /* mark us as sleeping */
1780
1781         thread->sleeping = true;
1782
1783         /* wait on waitcond */
1784
1785         if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1786                 /* with timeout */
1787                 while (!thread->interrupted && !thread->signaled
1788                            && threads_current_time_is_earlier_than(wakeupTime))
1789                 {
1790                         threads_thread_state_timed_waiting(thread);
1791
1792                         pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1793                                                                    wakeupTime);
1794
1795                         threads_thread_state_runnable(thread);
1796                 }
1797         }
1798         else {
1799                 /* no timeout */
1800                 while (!thread->interrupted && !thread->signaled) {
1801                         threads_thread_state_waiting(thread);
1802
1803                         pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1804
1805                         threads_thread_state_runnable(thread);
1806                 }
1807         }
1808
1809         /* check if we were interrupted */
1810
1811         wasinterrupted = thread->interrupted;
1812
1813         /* reset all flags */
1814
1815         thread->interrupted = false;
1816         thread->signaled    = false;
1817         thread->sleeping    = false;
1818
1819         /* release the waitmutex */
1820
1821         pthread_mutex_unlock(&thread->waitmutex);
1822
1823         return wasinterrupted;
1824 }
1825
1826
1827 /* threads_wait_with_timeout_relative ******************************************
1828
1829    Wait for the given maximum amount of time on a monitor until either
1830    we are notified, we are interrupted, or the time is up.
1831
1832    IN:
1833       t............the current thread
1834           millis.......milliseconds to wait
1835           nanos........nanoseconds to wait
1836
1837    RETURN VALUE:
1838       true.........if the wait has been interrupted,
1839           false........if the wait was ended by notification or timeout
1840
1841 *******************************************************************************/
1842
1843 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1844                                                                                 s4 nanos)
1845 {
1846         struct timespec wakeupTime;
1847
1848         /* calculate the the (latest) wakeup time */
1849
1850         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1851
1852         /* wait */
1853
1854         return threads_wait_with_timeout(thread, &wakeupTime);
1855 }
1856
1857
1858 /* threads_calc_absolute_time **************************************************
1859
1860    Calculate the absolute point in time a given number of ms and ns from now.
1861
1862    IN:
1863       millis............milliseconds from now
1864           nanos.............nanoseconds from now
1865
1866    OUT:
1867       *tm...............receives the timespec of the absolute point in time
1868
1869 *******************************************************************************/
1870
1871 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1872 {
1873         if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1874                 struct timeval tv;
1875                 long nsec;
1876                 gettimeofday(&tv, NULL);
1877                 tv.tv_sec += millis / 1000;
1878                 millis %= 1000;
1879                 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1880                 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1881                 tm->tv_nsec = nsec % 1000000000;
1882         }
1883         else {
1884                 tm->tv_sec = 0;
1885                 tm->tv_nsec = 0;
1886         }
1887 }
1888
1889
1890 /* threads_thread_interrupt ****************************************************
1891
1892    Interrupt the given thread.
1893
1894    The thread gets the "waitcond" signal and 
1895    its interrupted flag is set to true.
1896
1897    IN:
1898       thread............the thread to interrupt
1899
1900 *******************************************************************************/
1901
1902 void threads_thread_interrupt(threadobject *thread)
1903 {
1904         /* Signal the thread a "waitcond" and tell it that it has been
1905            interrupted. */
1906
1907         pthread_mutex_lock(&thread->waitmutex);
1908
1909         /* Interrupt blocking system call using a signal. */
1910
1911         pthread_kill(thread->tid, SIGHUP);
1912
1913         if (thread->sleeping)
1914                 pthread_cond_signal(&thread->waitcond);
1915
1916         thread->interrupted = true;
1917
1918         pthread_mutex_unlock(&thread->waitmutex);
1919 }
1920
1921
1922 /* threads_check_if_interrupted_and_reset **************************************
1923
1924    Check if the current thread has been interrupted and reset the
1925    interruption flag.
1926
1927    RETURN VALUE:
1928       true, if the current thread had been interrupted
1929
1930 *******************************************************************************/
1931
1932 bool threads_check_if_interrupted_and_reset(void)
1933 {
1934         threadobject *thread;
1935         bool intr;
1936
1937         thread = THREADOBJECT;
1938
1939         /* get interrupted flag */
1940
1941         intr = thread->interrupted;
1942
1943         /* reset interrupted flag */
1944
1945         thread->interrupted = false;
1946
1947         return intr;
1948 }
1949
1950
1951 /* threads_thread_has_been_interrupted *****************************************
1952
1953    Check if the given thread has been interrupted
1954
1955    IN:
1956       t............the thread to check
1957
1958    RETURN VALUE:
1959       true, if the given thread had been interrupted
1960
1961 *******************************************************************************/
1962
1963 bool threads_thread_has_been_interrupted(threadobject *thread)
1964 {
1965         return thread->interrupted;
1966 }
1967
1968
1969 /* threads_sleep ***************************************************************
1970
1971    Sleep the current thread for the specified amount of time.
1972
1973 *******************************************************************************/
1974
1975 void threads_sleep(s8 millis, s4 nanos)
1976 {
1977         threadobject    *thread;
1978         struct timespec  wakeupTime;
1979         bool             wasinterrupted;
1980
1981         thread = THREADOBJECT;
1982
1983         threads_calc_absolute_time(&wakeupTime, millis, nanos);
1984
1985         wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1986
1987         if (wasinterrupted)
1988                 exceptions_throw_interruptedexception();
1989 }
1990
1991
1992 /* threads_yield ***************************************************************
1993
1994    Yield to the scheduler.
1995
1996 *******************************************************************************/
1997
1998 void threads_yield(void)
1999 {
2000         sched_yield();
2001 }
2002
2003
2004 /*
2005  * These are local overrides for various environment variables in Emacs.
2006  * Please do not remove this and leave it at the end of the file, where
2007  * Emacs will automagically detect them.
2008  * ---------------------------------------------------------------------
2009  * Local variables:
2010  * mode: c
2011  * indent-tabs-mode: t
2012  * c-basic-offset: 4
2013  * tab-width: 4
2014  * End:
2015  * vim:noexpandtab:sw=4:ts=4:
2016  */