CACAO
thread-posix.cpp
Go to the documentation of this file.
1 /* src/threads/posix/thread-posix.cpp - POSIX thread functions
2 
3  Copyright (C) 1996-2013
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 #define __STDC_LIMIT_MACROS
26 
27 #include "threads/thread.hpp" // for threadobject, etc
28 #include <assert.h> // for assert
29 #include <errno.h> // for errno, EINTR
30 #include <pthread.h> // for pthread_attr_init, etc
31 #include <sched.h> // for sched_param, sched_yield, etc
32 #if !defined(__DARWIN__)
33 #include <semaphore.h> // for sem_t, sem_destroy, etc
34 #endif
35 #include <signal.h> // for pthread_kill, SIGUSR1
36 #include <stdint.h> // for INT32_MAX
37 #include <stdlib.h> // for NULL
38 #include <string.h> // for strerror
39 #include <sys/time.h> // for timeval, gettimeofday
40 #include <sys/types.h> // for int32_t, int64_t
41 #include <time.h> // for timespec
42 #include "config.h" // for ENABLE_GC_BOEHM, etc
43 #include "native/llni.hpp" // for LLNI_class_get, LLNI_WRAP
44 #include "threads/condition.hpp" // for Condition
45 #include "threads/lock.hpp" // for lock_monitor_enter, etc
46 #include "threads/mutex.hpp" // for Mutex
47 #include "threads/thread.hpp" // for DEBUGTHREADS, etc
48 #include "threads/threadlist.hpp" // for ThreadList
49 #include "threads/ThreadRuntime.hpp" // for ThreadRuntime
50 #include "vm/class.hpp" // for class_resolveclassmethod, etc
51 #include "vm/exceptions.hpp" // for exceptions_get_exception, etc
52 #include "vm/global.hpp" // for java_handle_t, functionptr
53 #include "vm/hook.hpp" // for thread_end, thread_start
54 #include "vm/javaobjects.hpp" // for java_lang_Thread
55 #include "vm/options.hpp" // for opt_stacksize
56 #include "vm/os.hpp" // for os
57 #include "vm/signallocal.hpp"
58 #include "vm/types.hpp" // for s4, s8, u2
59 #include "vm/utf8.hpp"
60 #include "vm/vm.hpp" // for vm_abort, vm_call_method
61 
62 #if defined(ENABLE_GC_CACAO)
63 # include "mm/cacao-gc/gc.h"
64 #endif
65 
66 #if defined(__DARWIN__)
67 
68 typedef struct {
69  Mutex* mutex;
70  Condition* cond;
71  int value;
72 } sem_t;
73 
74 #else
75 # include <semaphore.h>
76 #endif
77 
78 #include "mm/gc-boehm.hpp"
79 
80 struct methodinfo;
81 
82 using namespace cacao;
83 
84 #if defined(__DARWIN__)
85 /* Darwin has no working semaphore implementation. This one is taken
86  from Boehm-GC. */
87 
88 /*
89  This is a very simple semaphore implementation for Darwin. It
90  is implemented in terms of pthreads calls so it isn't async signal
91  safe. This isn't a problem because signals aren't used to
92  suspend threads on Darwin.
93 */
94 
95 static int sem_init(sem_t *sem, int pshared, int value)
96 {
97  if (pshared)
98  assert(0);
99 
100  sem->mutex = new Mutex();
101  sem->cond = new Condition();
102  sem->value = value;
103 
104  return 0;
105 }
106 
107 static int sem_post(sem_t *sem)
108 {
109  sem->mutex->lock();
110  sem->value++;
111  sem->cond->signal();
112  sem->mutex->unlock();
113 
114  return 0;
115 }
116 
117 static int sem_wait(sem_t *sem)
118 {
119  sem->mutex->lock();
120 
121  while (sem->value == 0) {
122  sem->cond->wait(sem->mutex);
123  }
124 
125  sem->value--;
126  sem->mutex->unlock();
127 
128  return 0;
129 }
130 
131 static int sem_destroy(sem_t *sem)
132 {
133  delete sem->cond;
134  delete sem->mutex;
135 
136  return 0;
137 }
138 #endif /* defined(__DARWIN__) */
139 
140 
141 /* startupinfo *****************************************************************
142 
143  Struct used to pass info from threads_start_thread to
144  threads_startup_thread.
145 
146 ******************************************************************************/
147 
148 typedef struct {
149  threadobject *thread; /* threadobject for this thread */
150  functionptr function; /* function to run in the new thread */
151  sem_t *psem; /* signals when thread has been entered */
152  /* in the thread list */
153  sem_t *psem_first; /* signals when pthread_create has returned */
154 } startupinfo;
155 
156 
157 /* prototypes *****************************************************************/
158 
159 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
160 static void threads_set_thread_priority(pthread_t tid, int priority);
161 
162 
163 /******************************************************************************/
164 /* GLOBAL VARIABLES */
165 /******************************************************************************/
166 
167 /* the thread object of the current thread */
168 /* This is either a thread-local variable defined with __thread, or */
169 /* a thread-specific value stored with key threads_current_threadobject_key. */
170 #if defined(HAVE___THREAD)
172 #else
173 pthread_key_t thread_current_key;
174 #endif
175 
176 /* global mutex for stop-the-world */
178 
179 #if defined(ENABLE_GC_CACAO)
180 /* global mutex for the GC */
181 static Mutex* mutex_gc;
182 #endif
183 
184 /* global mutex and condition for joining threads on exit */
186 
187 #if defined(ENABLE_GC_CACAO)
188 /* semaphore used for acknowleding thread suspension */
189 static sem_t suspend_ack;
190 #endif
191 
192 
193 /* threads_sem_init ************************************************************
194 
195  Initialize a semaphore. Checks against errors and interruptions.
196 
197  IN:
198  sem..............the semaphore to initialize
199  shared...........true if this semaphore will be shared between processes
200  value............the initial value for the semaphore
201 
202 *******************************************************************************/
203 
204 void threads_sem_init(sem_t *sem, bool shared, int value)
205 {
206  int r;
207 
208  assert(sem);
209 
210  do {
211  r = sem_init(sem, shared, value);
212  if (r == 0)
213  return;
214  } while (errno == EINTR);
215 
216  vm_abort("sem_init failed: %s", strerror(errno));
217 }
218 
219 
220 /* threads_sem_wait ************************************************************
221 
222  Wait for a semaphore, non-interruptible.
223 
224  IMPORTANT: Always use this function instead of `sem_wait` directly, as
225  `sem_wait` may be interrupted by signals!
226 
227  IN:
228  sem..............the semaphore to wait on
229 
230 *******************************************************************************/
231 
232 void threads_sem_wait(sem_t *sem)
233 {
234  int r;
235 
236  assert(sem);
237 
238  do {
239  r = sem_wait(sem);
240  if (r == 0)
241  return;
242  } while (errno == EINTR);
243 
244  vm_abort("sem_wait failed: %s", strerror(errno));
245 }
246 
247 
248 /* threads_sem_post ************************************************************
249 
250  Increase the count of a semaphore. Checks for errors.
251 
252  IN:
253  sem..............the semaphore to increase the count of
254 
255 *******************************************************************************/
256 
257 void threads_sem_post(sem_t *sem)
258 {
259  int r;
260 
261  assert(sem);
262 
263  /* unlike sem_wait, sem_post is not interruptible */
264 
265  r = sem_post(sem);
266  if (r == 0)
267  return;
268 
269  vm_abort("sem_post failed: %s", strerror(errno));
270 }
271 
272 
273 /* threads_stopworld ***********************************************************
274 
275  Stops the world from turning. All threads except the calling one
276  are suspended. The function returns as soon as all threads have
277  acknowledged their suspension.
278 
279 *******************************************************************************/
280 
281 #if defined(ENABLE_GC_CACAO)
282 void threads_stopworld(void)
283 {
284 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
285  threadobject *t;
286  threadobject *self;
287  bool result;
288  s4 count, i;
289 #endif
290 
291  stopworldlock->lock();
292 
293  /* lock the threads lists */
294 
295  threadlist_lock();
296 
297 #if defined(__DARWIN__)
298  /*threads_cast_darwinstop();*/
299  assert(0);
300 #elif defined(__CYGWIN__)
301  /* TODO */
302  assert(0);
303 #else
304  self = THREADOBJECT;
305 
306  DEBUGTHREADS("stops World", self);
307 
308  count = 0;
309 
310  /* suspend all running threads */
311  for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
312  /* don't send the signal to ourself */
313 
314  if (t == self)
315  continue;
316 
317  /* don't send the signal to NEW threads (because they are not
318  completely initialized) */
319 
320  if (t->state == THREAD_STATE_NEW)
321  continue;
322 
323  /* send the signal */
324 
326  assert(result);
327 
328  /* increase threads count */
329 
330  count++;
331  }
332 
333  /* wait for all threads signaled to suspend */
334  for (i = 0; i < count; i++)
335  threads_sem_wait(&suspend_ack);
336 #endif
337 
338  /* ATTENTION: Don't unlock the threads-lists here so that
339  non-signaled NEW threads can't change their state and execute
340  code. */
341 }
342 #endif
343 
344 
345 /* threads_startworld **********************************************************
346 
347  Starts the world again after it has previously been stopped.
348 
349 *******************************************************************************/
350 
351 #if defined(ENABLE_GC_CACAO)
352 void threads_startworld(void)
353 {
354 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
355  threadobject *t;
356  threadobject *self;
357  bool result;
358  s4 count, i;
359 #endif
360 
361 #if defined(__DARWIN__)
362  /*threads_cast_darwinresume();*/
363  assert(0);
364 #elif defined(__IRIX__)
365  threads_cast_irixresume();
366 #elif defined(__CYGWIN__)
367  /* TODO */
368  assert(0);
369 #else
370  self = THREADOBJECT;
371 
372  DEBUGTHREADS("starts World", self);
373 
374  count = 0;
375 
376  /* resume all thread we haltet */
377  for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
378  /* don't send the signal to ourself */
379 
380  if (t == self)
381  continue;
382 
383  /* don't send the signal to NEW threads (because they are not
384  completely initialized) */
385 
386  if (t->state == THREAD_STATE_NEW)
387  continue;
388 
389  /* send the signal */
390 
391  result = threads_resume_thread(t);
392  assert(result);
393 
394  /* increase threads count */
395 
396  count++;
397  }
398 
399  /* wait for all threads signaled to suspend */
400  for (i = 0; i < count; i++)
401  threads_sem_wait(&suspend_ack);
402 
403 #endif
404 
405  /* unlock the threads lists */
406 
407  threadlist_unlock();
408 
410 }
411 #endif
412 
413 
414 /* threads_impl_thread_clear ***************************************************
415 
416  Clears all fields in threadobject the way an MZERO would have
417  done. MZERO cannot be used anymore because it would mess up the
418  pthread_* bits.
419 
420  IN:
421  t....the threadobject
422 
423 *******************************************************************************/
424 
426 {
427  t->object = NULL;
428 
429  t->thinlock = 0;
430 
431  t->index = 0;
432  t->flags = 0;
433  t->state = THREAD_STATE_NEW;
434  t->is_in_active_list = false;
435 
436  t->impl.tid = 0;
437 
438 #if defined(__DARWIN__)
439  t->impl.mach_thread = 0;
440 #endif
441 
442  t->interrupted = false;
443  t->signaled = false;
444 
445  t->suspended = false;
447 
448  t->pc = NULL;
449 
450  t->_exceptionptr = NULL;
451  t->_stackframeinfo = NULL;
452  t->_localref_table = NULL;
453 
454 #if defined(ENABLE_INTRP)
455  t->_global_sp = NULL;
456 #endif
457 
458 #if defined(ENABLE_GC_CACAO)
459  t->gc_critical = false;
460 
461  t->ss = NULL;
462  t->es = NULL;
463 #endif
464 
465  // Simply reuse the existing dump memory.
466 }
467 
468 /* threads_impl_thread_reuse ***************************************************
469 
470  Resets some implementation fields in threadobject. This was
471  previously done in threads_impl_thread_new.
472 
473  IN:
474  t....the threadobject
475 
476 *******************************************************************************/
477 
479 {
480  /* get the pthread id */
481 
482  t->impl.tid = pthread_self();
483 }
484 
486 {
487  t->object = 0;
488  t->flc_object = 0;
489 }
490 
491 /* threads_impl_preinit ********************************************************
492 
493  Do some early initialization of stuff required.
494 
495  ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
496  is called AFTER this function!
497 
498 *******************************************************************************/
499 
501 {
502  stopworldlock = new Mutex();
503 
504  /* initialize exit mutex and condition (on exit we join all
505  threads) */
506 
507  cond_join = new Condition();
508 
509 #if defined(ENABLE_GC_CACAO)
510  /* initialize the GC mutex & suspend semaphore */
511 
512  mutex_gc = new Mutex();
513  threads_sem_init(&suspend_ack, 0, 0);
514 #endif
515 
516 #if !defined(HAVE___THREAD)
517  int result = pthread_key_create(&thread_current_key, NULL);
518  if (result != 0)
519  os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
520 #endif
521 }
522 
523 
524 /* threads_mutex_gc_lock *******************************************************
525 
526  Enter the global GC mutex.
527 
528 *******************************************************************************/
529 
530 #if defined(ENABLE_GC_CACAO)
531 void threads_mutex_gc_lock(void)
532 {
533  mutex_gc->lock();
534 }
535 #endif
536 
537 
538 /* threads_mutex_gc_unlock *****************************************************
539 
540  Leave the global GC mutex.
541 
542 *******************************************************************************/
543 
544 #if defined(ENABLE_GC_CACAO)
545 void threads_mutex_gc_unlock(void)
546 {
547  mutex_gc->unlock();
548 }
549 #endif
550 
551 /* threads_impl_init ***********************************************************
552 
553  Initializes the implementation specific bits.
554 
555 *******************************************************************************/
556 
558 {
559  pthread_attr_t attr;
560  int result;
561 
563 
564  /* Initialize the thread attribute object. */
565 
566  result = pthread_attr_init(&attr);
567 
568  if (result != 0)
569  os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
570 
571  result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
572 
573  if (result != 0)
574  os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
575 }
576 
577 
578 /* threads_startup_thread ******************************************************
579 
580  Thread startup function called by pthread_create.
581 
582  Thread which have a startup.function != NULL are marked as internal
583  threads. All other threads are threated as normal Java threads.
584 
585  NOTE: This function is not called directly by pthread_create. The Boehm GC
586  inserts its own GC_start_routine in between, which then calls
587  threads_startup.
588 
589  IN:
590  arg..........the argument passed to pthread_create, ie. a pointer to
591  a startupinfo struct. CAUTION: When the `psem` semaphore
592  is posted, the startupinfo struct becomes invalid! (It
593  is allocated on the stack of threads_start_thread.)
594 
595 ******************************************************************************/
596 
597 static void *threads_startup_thread(void *arg)
598 {
599  startupinfo *startup;
600  threadobject *t;
601  sem_t *psem;
602  classinfo *c;
603  methodinfo *m;
604  functionptr function;
605 
606 #if defined(ENABLE_GC_BOEHM)
607 # if !defined(__DARWIN__)
608  struct GC_stack_base sb;
609  int result;
610 # endif
611 #endif
612 
613 #if defined(ENABLE_INTRP)
614  u1 *intrp_thread_stack;
615 #endif
616 
617 #if defined(ENABLE_INTRP)
618  /* create interpreter stack */
619 
620  if (opt_intrp) {
621  intrp_thread_stack = GCMNEW(u1, opt_stacksize);
622  MSET(intrp_thread_stack, 0, u1, opt_stacksize);
623  }
624  else
625  intrp_thread_stack = NULL;
626 #endif
627 
628  /* get passed startupinfo structure and the values in there */
629 
630  startup = (startupinfo*) arg;
631 
632  t = startup->thread;
633  function = startup->function;
634  psem = startup->psem;
635 
636  /* Seems like we've encountered a situation where thread->tid was
637  not set by pthread_create. We alleviate this problem by waiting
638  for pthread_create to return. */
639 
640  threads_sem_wait(startup->psem_first);
641 
642 #if defined(__DARWIN__)
643  t->impl.mach_thread = mach_thread_self();
644 #endif
645 
646  /* Now that we are in the new thread, we can store the internal
647  thread data-structure in the TSD. */
648 
650 
651 #if defined(ENABLE_GC_BOEHM)
652 # if defined(__DARWIN__)
653  // This is currently not implemented in Boehm-GC. Just fail silently.
654 # else
655  /* Register the thread with Boehm-GC. This must happen before the
656  thread allocates any memory from the GC heap.*/
657 
658  result = GC_get_stack_base(&sb);
659 
660  if (result != 0)
661  vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
662 
663  GC_register_my_thread(&sb);
664 # endif
665 #endif
666 
667  // Get the java.lang.Thread object for this thread.
668  java_handle_t* object = LLNI_WRAP(t->object);
669  java_lang_Thread jlt(object);
670 
671  /* set our priority */
672 
674 
675  /* tell threads_startup_thread that we registered ourselves */
676  /* CAUTION: *startup becomes invalid with this! */
677 
678  startup = NULL;
679  threads_sem_post(psem);
680 
681 #if defined(ENABLE_INTRP)
682  /* set interpreter stack */
683 
684  if (opt_intrp)
685  thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
686 #endif
687 
688  // Hook point just before the threads initial method is executed.
690 
691  DEBUGTHREADS("starting", t);
692 
693  /* find and run the Thread.run()V method if no other function was passed */
694 
695  if (function == NULL) {
697 
698  m = class_resolveclassmethod(c, utf8::run, utf8::void__void, c, true);
699 
700  if (m == NULL)
701  vm_abort("threads_startup_thread: run() method not found in class");
702 
704 
705  /* Run the thread. */
706 
707  (void) vm_call_method(m, h);
708  }
709  else {
710  /* call passed function, e.g. finalizer_thread */
711 
712  (function)();
713  }
714 
715  DEBUGTHREADS("stopping", t);
716 
717  // Hook point just after the threads initial method returned.
718  Hook::thread_end(t);
719 
720  /* We ignore the return value. */
721 
723 
724  return NULL;
725 }
726 
727 
728 /* threads_impl_thread_start ***************************************************
729 
730  Start a thread in the JVM. Both (vm internal and java) thread
731  objects exist.
732 
733  IN:
734  thread....the thread object
735  f.........function to run in the new thread. NULL means that the
736  "run" method of the object `t` should be called
737 
738 ******************************************************************************/
739 
741 {
742  sem_t sem;
743  sem_t sem_first;
744  pthread_attr_t attr;
745  startupinfo startup;
746  int result;
747 
748  /* fill startupinfo structure passed by pthread_create to
749  * threads_startup_thread */
750 
751  startup.thread = thread;
752  startup.function = f; /* maybe we don't call Thread.run()V */
753  startup.psem = &sem;
754  startup.psem_first = &sem_first;
755 
756  threads_sem_init(&sem, 0, 0);
757  threads_sem_init(&sem_first, 0, 0);
758 
759  /* Initialize thread attributes. */
760 
761  result = pthread_attr_init(&attr);
762 
763  if (result != 0)
764  os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
765 
766  result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
767 
768  if (result != 0)
769  os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
770 
771  /* initialize thread stacksize */
772 
773  result = pthread_attr_setstacksize(&attr, opt_stacksize);
774 
775  if (result != 0)
776  os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
777 
778  /* create the thread */
779 
780  result = pthread_create(&(thread->impl.tid), &attr, threads_startup_thread, &startup);
781 
782  if (result != 0)
783  os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
784 
785  /* destroy the thread attributes */
786 
787  result = pthread_attr_destroy(&attr);
788 
789  if (result != 0)
790  os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
791 
792  /* signal that pthread_create has returned, so thread->tid is valid */
793 
794  threads_sem_post(&sem_first);
795 
796  /* wait here until the thread has entered itself into the thread list */
797 
798  threads_sem_wait(&sem);
799 
800  /* cleanup */
801 
802  sem_destroy(&sem);
803  sem_destroy(&sem_first);
804 }
805 
806 
807 /* threads_set_thread_priority *************************************************
808 
809  Set the priority of the given thread.
810 
811  IN:
812  tid..........thread id
813  priority.....priority to set
814 
815 ******************************************************************************/
816 
818 {
819  threads_set_thread_priority(t->impl.tid, priority);
820 }
821 
822 
823 static void threads_set_thread_priority(pthread_t tid, int priority)
824 {
825  struct sched_param schedp;
826  int policy;
827 
828  pthread_getschedparam(tid, &policy, &schedp);
829  schedp.sched_priority = priority;
830  pthread_setschedparam(tid, policy, &schedp);
831 }
832 
833 
834 /**
835  * Detaches the current thread from the VM.
836  *
837  * @return true on success, false otherwise
838  */
840 {
842 
843  /* Sanity check. */
844 
845  assert(t != NULL);
846 
847  /* If the given thread has already been detached, this operation
848  is a no-op. */
849 
850  if (thread_is_attached(t) == false)
851  return true;
852 
853  DEBUGTHREADS("detaching", t);
854 
855  java_handle_t* object = LLNI_WRAP(t->object);
856  java_lang_Thread jlt(object);
857 
858 #if defined(ENABLE_JAVASE)
859  java_handle_t* group = jlt.get_group();
860 
861  /* If there's an uncaught exception, call uncaughtException on the
862  thread's exception handler, or the thread's group if this is
863  unset. */
864 
866 
867  if (e != NULL) {
868  /* We use the type void* for handler here, as it's not trivial
869  to build the java_lang_Thread_UncaughtExceptionHandler
870  header file with cacaoh. */
871 
873 
874  classinfo* c;
875  java_handle_t* h;
876 
877  if (handler != NULL) {
878  LLNI_class_get(handler, c);
879  h = (java_handle_t *) handler;
880  }
881  else {
882  LLNI_class_get(group, c);
883  h = (java_handle_t *) group;
884  }
885 
887  utf8::uncaughtException,
888  utf8::java_lang_Thread_java_lang_Throwable__V,
889  NULL,
890  true);
891 
892  if (m == NULL)
893  return false;
894 
895  (void) vm_call_method(m, h, object, e);
896 
898  return false;
899  }
900 
901  /* XXX TWISTI: should all threads be in a ThreadGroup? */
902 
903  /* Remove thread from the thread group. */
904 
905  if (group != NULL) {
906  classinfo* c;
907  LLNI_class_get(group, c);
908 
910 
911  if (m == NULL)
912  return false;
913 
914  (void) vm_call_method(m, group, object);
915 
917  return false;
918 
919  // Clear the ThreadGroup in the Java thread object (Mauve
920  // test: gnu/testlet/java/lang/Thread/getThreadGroup).
921  jlt.set_group(NULL);
922  }
923 #endif
924 
925  /* Thread has terminated. */
926 
928 
929  /* Notify all threads waiting on this thread. These are joining
930  this thread. */
931 
932  /* XXX Care about exceptions? */
934 
936 
937  /* XXX Care about exceptions? */
939 
940  t->waitmutex->lock();
941  t->impl.tid = 0;
942  t->waitmutex->unlock();
943 
944  {
946 
947  /* Free the internal thread data-structure. */
948 
949  thread_free(t);
950 
951  /* Signal that this thread has finished and leave the mutex. */
952 
953  cond_join->signal();
954  }
955 
956  t->suspendmutex->lock();
957  t->suspendmutex->unlock();
958 
959  return true;
960 }
961 
962 
963 /**
964  * Internal helper function which suspends the current thread. This is
965  * the core method of the suspension mechanism actually blocking the
966  * execution until the suspension reason is cleared again. Note that
967  * the current thread needs to hold the suspension mutex while calling
968  * this function.
969  */
970 static void threads_suspend_self()
971 {
973 
974  DEBUGTHREADS("suspending", thread);
975 
976  // Mark thread as suspended.
977  assert(!thread->suspended);
978  assert(thread->suspend_reason != SUSPEND_REASON_NONE);
979  thread->suspended = true;
980 
981  // Acknowledge the suspension.
982  thread->suspendcond->broadcast();
983 
984 #if defined(ENABLE_GC_CACAO)
985  // If we are stopping the world, we should send a global ack.
987  threads_sem_post(&suspend_ack);
988 #endif
989 
990  // Release the suspension mutex and wait till we are resumed.
991  while (thread->suspend_reason != SUSPEND_REASON_NONE)
992  thread->suspendcond->wait(thread->suspendmutex);
993 
994 #if defined(ENABLE_GC_CACAO)
995  // XXX This is propably not ok!
996  // If we are starting the world, we should send a global ack.
998  threads_sem_post(&suspend_ack);
999 #endif
1000 
1001  // Mark thread as not suspended.
1002  assert(thread->suspended);
1003  assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1004  thread->suspended = false;
1005 
1006  DEBUGTHREADS("resuming", thread);
1007 }
1008 
1009 
1010 /**
1011  * Suspend the passed thread. Execution of that thread stops until the thread
1012  * is explicitly resumed again.
1013  *
1014  * @param thread The thread to be suspended.
1015  * @param reason Reason for suspending the given thread.
1016  * @return True of operation was successful, false otherwise.
1017  */
1019 {
1020  // Sanity check.
1021  assert(reason != SUSPEND_REASON_NONE);
1022 
1023  // Guard this with the suspension mutex.
1024  MutexLocker ml(*thread->suspendmutex);
1025 
1026  // Check if thread is already suspended.
1027  if (thread->suspended)
1028  return false;
1029 
1030  // Check if thread is in the process of suspending.
1031  if (thread->suspend_reason != SUSPEND_REASON_NONE)
1032  return false;
1033 
1034  // Set the reason for suspending the thread.
1035  thread->suspend_reason = reason;
1036 
1037  if (thread == THREADOBJECT) {
1038  // We already hold the suspension mutex and can suspend ourselves
1039  // immediately without using signals at all.
1041  }
1042  else {
1043  // Send the suspend signal to the other thread.
1044  if (!thread->impl.tid)
1045  return false;
1046  if (pthread_kill(thread->impl.tid, SIGUSR1) != 0)
1047  os::abort_errno("threads_suspend_thread: pthread_kill failed");
1048 
1049  // Wait for the thread to acknowledge the suspension.
1050  while (!thread->suspended)
1051  thread->suspendcond->wait(thread->suspendmutex);
1052  }
1053 
1054  return true;
1055 }
1056 
1057 
1058 /**
1059  * Resumes execution of the passed thread.
1060  *
1061  * @param thread The thread to be resumed.
1062  * @param reason Reason for suspending the given thread.
1063  * @return True of operation was successful, false otherwise.
1064  */
1066 {
1067  // Sanity check.
1068  assert(thread != THREADOBJECT);
1069  assert(reason != SUSPEND_REASON_NONE);
1070 
1071  // Guard this with the suspension mutex.
1072  MutexLocker ml(*thread->suspendmutex);
1073 
1074  // Check if thread really is suspended.
1075  if (!thread->suspended)
1076  return false;
1077 
1078  // Threads can only be resumed for the same reason they were suspended.
1079  if (thread->suspend_reason != reason)
1080  return false;
1081 
1082  // Clear the reason for suspending the thread.
1084 
1085  // Tell everyone that the thread should resume.
1086  thread->suspendcond->broadcast();
1087 
1088  return true;
1089 }
1090 
1091 
1092 /**
1093  * Acknowledges the suspension of the current thread.
1094  */
1096 {
1098 
1099  // Guard this with the suspension mutex.
1100  MutexLocker ml(*thread->suspendmutex);
1101 
1102  // Suspend ourselves while holding the suspension mutex.
1104 }
1105 
1106 
1107 /* threads_join_all_threads ****************************************************
1108 
1109  Join all non-daemon threads.
1110 
1111 *******************************************************************************/
1112 
1114 {
1115  threadobject *t;
1116 
1117  /* get current thread */
1118 
1119  t = THREADOBJECT;
1120 
1121  /* This thread is waiting for all non-daemon threads to exit. */
1122 
1124 
1125  /* enter join mutex */
1126 
1128 
1129  /* Wait for condition as long as we have non-daemon threads. We
1130  compare against 1 because the current (main thread) is also a
1131  non-daemon thread. */
1132 
1133  while (ThreadList::get()->get_number_of_non_daemon_threads() > 1)
1135 }
1136 
1137 
1138 /* threads_timespec_earlier ****************************************************
1139 
1140  Return true if timespec tv1 is earlier than timespec tv2.
1141 
1142  IN:
1143  tv1..........first timespec
1144  tv2..........second timespec
1145 
1146  RETURN VALUE:
1147  true, if the first timespec is earlier
1148 
1149 *******************************************************************************/
1150 
1151 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1152  const struct timespec *tv2)
1153 {
1154  return (tv1->tv_sec < tv2->tv_sec)
1155  ||
1156  (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1157 }
1158 
1159 
1160 /* threads_current_time_is_earlier_than ****************************************
1161 
1162  Check if the current time is earlier than the given timespec.
1163 
1164  IN:
1165  tv...........the timespec to compare against
1166 
1167  RETURN VALUE:
1168  true, if the current time is earlier
1169 
1170 *******************************************************************************/
1171 
1172 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1173 {
1174  struct timeval tvnow;
1175  struct timespec tsnow;
1176 
1177  /* get current time */
1178 
1179  if (gettimeofday(&tvnow, NULL) != 0)
1180  vm_abort("gettimeofday failed: %s\n", strerror(errno));
1181 
1182  /* convert it to a timespec */
1183 
1184  tsnow.tv_sec = tvnow.tv_sec;
1185  tsnow.tv_nsec = tvnow.tv_usec * 1000;
1186 
1187  /* compare current time with the given timespec */
1188 
1189  return threads_timespec_earlier(&tsnow, tv);
1190 }
1191 
1192 
1193 /* threads_wait_with_timeout ***************************************************
1194 
1195  Wait until the given point in time on a monitor until either
1196  we are notified, we are interrupted, or the time is up.
1197 
1198  IN:
1199  t............the current thread
1200  wakeupTime...absolute (latest) wakeup time
1201  If both tv_sec and tv_nsec are zero, this function
1202  waits for an unlimited amount of time.
1203 
1204 *******************************************************************************/
1205 
1206 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1207 {
1208  // Acquire the waitmutex.
1209  t->waitmutex->lock();
1210 
1211  /* wait on waitcond */
1212 
1213  if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1214  /* with timeout */
1215  while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1216  && threads_current_time_is_earlier_than(wakeupTime))
1217  {
1218  if (parking)
1220  else
1222 
1223  t->waitcond->timedwait(t->waitmutex, wakeupTime);
1224 
1226  }
1227  }
1228  else {
1229  /* no timeout */
1230  while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1231  if (parking)
1233  else
1235 
1236  t->waitcond->wait(t->waitmutex);
1237 
1239  }
1240  }
1241 
1242  if (parking)
1243  t->park_permit = false;
1244 
1245  // Release the waitmutex.
1246  t->waitmutex->unlock();
1247 }
1248 
1249 
1250 /* threads_wait_with_timeout_relative ******************************************
1251 
1252  Wait for the given maximum amount of time on a monitor until either
1253  we are notified, we are interrupted, or the time is up.
1254 
1255  IN:
1256  t............the current thread
1257  millis.......milliseconds to wait
1258  nanos........nanoseconds to wait
1259 
1260 *******************************************************************************/
1261 
1263  s4 nanos)
1264 {
1265  struct timespec wakeupTime;
1266 
1267  /* calculate the the (latest) wakeup time */
1268 
1269  threads_calc_absolute_time(&wakeupTime, millis, nanos);
1270 
1271  /* wait */
1272 
1273  threads_wait_with_timeout(thread, &wakeupTime, false);
1274 }
1275 
1276 
1277 /* threads_calc_absolute_time **************************************************
1278 
1279  Calculate the absolute point in time a given number of ms and ns from now.
1280 
1281  IN:
1282  millis............milliseconds from now
1283  nanos.............nanoseconds from now
1284 
1285  OUT:
1286  *tm...............receives the timespec of the absolute point in time
1287 
1288 *******************************************************************************/
1289 
1290 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1291 {
1292  // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1293  do {
1294  if (!millis && !nanos)
1295  break;
1296  struct timeval tv;
1297  gettimeofday(&tv, NULL);
1298  s8 secs = tv.tv_sec + millis / 1000;
1299  if (secs > INT32_MAX) // integer overflow
1300  break;
1301  tv.tv_sec = secs;
1302  millis %= 1000;
1303  long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1304  tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1305  if (tm->tv_sec < tv.tv_sec) // integer overflow
1306  break;
1307  tm->tv_nsec = nsec % 1000000000;
1308  return;
1309  } while (0);
1310  tm->tv_sec = 0;
1311  tm->tv_nsec = 0;
1312 }
1313 
1314 
1315 /* threads_thread_interrupt ****************************************************
1316 
1317  Interrupt the given thread.
1318 
1319  The thread gets the "waitcond" signal and
1320  its interrupted flag is set to true.
1321 
1322  IN:
1323  thread............the thread to interrupt
1324 
1325 *******************************************************************************/
1326 
1328 {
1329  /* Signal the thread a "waitcond" and tell it that it has been
1330  interrupted. */
1331 
1332  t->waitmutex->lock();
1333 
1334  DEBUGTHREADS("interrupted", t);
1335 
1336  /* Interrupt blocking system call using a signal. */
1337 
1338  if (t->impl.tid)
1339  pthread_kill(t->impl.tid, Signal_INTERRUPT_SYSTEM_CALL);
1340 
1341  t->waitcond->signal();
1342 
1343  t->interrupted = true;
1344 
1345  t->waitmutex->unlock();
1346 }
1347 
1348 
1349 /**
1350  * Sleep the current thread for the specified amount of time.
1351  *
1352  * @param millis Milliseconds to sleep.
1353  * @param nanos Nanoseconds to sleep.
1354  */
1355 void threads_sleep(int64_t millis, int32_t nanos)
1356 {
1357  threadobject *t;
1358  struct timespec wakeupTime;
1359  bool interrupted;
1360 
1361  if (millis < 0) {
1362 /* exceptions_throw_illegalargumentexception(); */
1364  return;
1365  }
1366 
1367  t = thread_get_current();
1368 
1370  /* Clear interrupted flag (Mauve test:
1371  gnu/testlet/java/lang/Thread/interrupt). */
1372 
1373  thread_set_interrupted(t, false);
1374 
1375 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1377  return;
1378  }
1379 
1380  // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1381  // Note: JDK treats a zero length sleep is like Thread.yield(),
1382  // without checking the interrupted status of the thread. It's
1383  // unclear if this is a bug in the implementation or the spec.
1384  // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1385  if (millis == 0 && nanos == 0) {
1386  threads_yield();
1387  }
1388  else {
1389  threads_calc_absolute_time(&wakeupTime, millis, nanos);
1390 
1391  threads_wait_with_timeout(t, &wakeupTime, false);
1392 
1393  interrupted = thread_is_interrupted(t);
1394 
1395  if (interrupted) {
1396  thread_set_interrupted(t, false);
1397 
1398  // An other exception could have been thrown
1399  // (e.g. ThreadDeathException).
1400  if (!exceptions_get_exception())
1402  }
1403  }
1404 }
1405 
1406 /**
1407  * Park the current thread for the specified amount of time or until a
1408  * specified deadline.
1409  *
1410  * @param absolute Is the time in nanos a deadline or a duration?
1411  * @param nanos Nanoseconds to park (absolute=false)
1412  * or deadline in milliseconds (absolute=true)
1413  */
1414 void threads_park(bool absolute, int64_t nanos)
1415 {
1416  threadobject *t;
1417  struct timespec wakeupTime;
1418 
1419  t = thread_get_current();
1420 
1421  if (absolute) {
1422  wakeupTime.tv_nsec = 0;
1423  wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1424  }
1425  else
1426  threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1427 
1428  threads_wait_with_timeout(t, &wakeupTime, true);
1429 }
1430 
1431 /**
1432  * Unpark the specified thread.
1433  *
1434  * @param t The thread to unpark.
1435  */
1437 {
1438  t->waitmutex->lock();
1439 
1440  t->waitcond->signal();
1441 
1442  t->park_permit = true;
1443 
1444  t->waitmutex->unlock();
1445 }
1446 
1447 
1448 /* threads_yield ***************************************************************
1449 
1450  Yield to the scheduler.
1451 
1452 *******************************************************************************/
1453 
1454 void threads_yield(void)
1455 {
1456  sched_yield();
1457 }
1458 
1459 
1460 /***
1461  * Return the tid of a thread.
1462  */
1464  // pthread_t is a pointer type in OS X
1465  // and a unsigned integer on linux.
1466  // Thus we need different casts
1467 #ifdef __DARWIN__
1468  return reinterpret_cast<intptr_t>(t->impl.tid);
1469 #else
1470  return static_cast<intptr_t>(t->impl.tid);
1471 #endif
1472 }
1473 
1474 
1475 /*
1476  * These are local overrides for various environment variables in Emacs.
1477  * Please do not remove this and leave it at the end of the file, where
1478  * Emacs will automagically detect them.
1479  * ---------------------------------------------------------------------
1480  * Local variables:
1481  * mode: c++
1482  * indent-tabs-mode: t
1483  * c-basic-offset: 4
1484  * tab-width: 4
1485  * End:
1486  * vim:noexpandtab:sw=4:ts=4:
1487  */
void exceptions_throw_illegalargumentexception(void)
SuspendReason
Definition: thread.hpp:65
Mutex * waitmutex
Definition: thread.hpp:113
int32_t get_priority() const
#define GCMNEW(type, num)
Definition: memory.hpp:118
methodinfo * class_resolveclassmethod(classinfo *c, Utf8String name, Utf8String desc, classinfo *referer, bool throwexception)
Definition: class.cpp:1211
bool park_permit
Definition: thread.hpp:121
virtual java_handle_t * get_handle() const
void threads_thread_interrupt(threadobject *t)
bool threads_suspend_thread(threadobject *thread, SuspendReason reason)
Suspend the passed thread.
#define MSET(ptr, byte, type, num)
Definition: memory.hpp:104
void thread_start(threadobject *t)
Definition: hook.hpp:130
sem_t * psem_first
Mutex * suspendmutex
Definition: thread.hpp:116
void signal()
Restarts one of the threads that are waiting on this condition variable.
s8 Cell
Definition: intrp.h:42
static void abort_errno(const char *text,...)
Equal to abort_errnum, but uses errno to get the error number.
Definition: os.cpp:165
void threads_unpark(threadobject *t)
Unpark the specified thread.
intptr_t threads_get_tid(threadobject *t)
functionptr function
void thread_set_state_runnable(threadobject *t)
Definition: thread.cpp:754
void threads_sem_post(sem_t *sem)
void exceptions_throw_interruptedexception(void)
bool opt_intrp
Definition: options.cpp:55
void thread_set_state_timed_parked(threadobject *t)
Definition: thread.cpp:831
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
bool lock_monitor_exit(java_handle_t *o)
Definition: lock.cpp:900
Dummy implementation of a mutex.
Definition: mutex-none.hpp:33
java_handle_t * vm_call_method(methodinfo *m, java_handle_t *o,...)
uint8_t u1
Definition: types.hpp:40
static java_handle_t * get_thread_exception_handler(const java_lang_Thread &jlt)
void threads_impl_thread_clear(threadobject *t)
void threads_set_thread_priority(threadobject *t, int priority)
Definition: thread-none.cpp:77
int64_t s8
Definition: types.hpp:48
void threads_sem_init(sem_t *sem, bool shared, int value)
static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
#define DEBUGTHREADS(message, thread)
Definition: thread.hpp:166
static bool threads_current_time_is_earlier_than(const struct timespec *tv)
static Mutex lock
Definition: atomic.cpp:34
static void abort_errnum(int errnum, const char *text,...)
Prints an error message, appends &quot;:&quot; plus the strerror-message of errnum and aborts the VM...
Definition: os.cpp:150
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
void(* functionptr)(void)
Definition: global.hpp:39
ptrint thinlock
Definition: thread.hpp:95
cacao::detail::threadobject impl
Definition: thread.hpp:91
java_handle_t * get_group() const
#define LLNI_class_get(obj, variable)
Definition: llni.hpp:60
void lock_notify_all_object(java_handle_t *o)
Definition: lock.cpp:1359
Condition * waitcond
Definition: thread.hpp:114
JNIEnv void * arg
Definition: jvmti.h:405
#define LLNI_WRAP(obj)
Definition: llni.hpp:51
static bool threads_timespec_earlier(const struct timespec *tv1, const struct timespec *tv2)
static ThreadList * get()
Provides access to singleton.
Definition: threadlist.hpp:62
java_object_t * _exceptionptr
Definition: thread.hpp:128
void wait_cond(Condition *cond)
Definition: threadlist.hpp:66
static void * threads_startup_thread(void *arg)
void thread_end(threadobject *t)
Definition: hook.hpp:135
Condition * suspendcond
Definition: thread.hpp:117
bool suspended
Definition: thread.hpp:123
static Mutex * stopworldlock
void thread_set_state_parked(threadobject *t)
Definition: thread.cpp:812
void threads_impl_thread_start(threadobject *thread, functionptr f)
Definition: thread-none.cpp:64
localref_table * _localref_table
Definition: thread.hpp:130
void threads_wait_with_timeout_relative(threadobject *thread, s8 millis, s4 nanos)
bool interrupted
Definition: thread.hpp:119
JNIEnv jthread thread
Definition: jvmti.h:207
SuspendReason suspend_reason
Definition: thread.hpp:124
#define exceptions_get_and_clear_exception
Definition: md-asm.hpp:98
static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
bool thread_is_interrupted(threadobject *t)
Definition: thread.cpp:926
void thread_free(threadobject *t)
Definition: thread.cpp:371
Dummy condition variable.
MIIterator i
threadobject * thread_current
Definition: thread-none.cpp:41
void threads_join_all_threads()
void broadcast()
Restarts all the threads that are waiting on the condition variable.
int32_t s4
Definition: types.hpp:45
ThreadState state
Definition: thread.hpp:97
void threads_suspend_ack()
static Mutex mutex
Definition: show.cpp:73
void thread_set_state_terminated(threadobject *t)
Definition: thread.cpp:848
void set_group(java_handle_t *value)
Helper class used to implicitly acquire and release a mutex within a method scope.
Definition: mutex.hpp:42
bool thread_detach_current_thread(void)
Detaches the current thread from the VM.
Definition: thread-none.cpp:86
static methodinfo * get_threadgroup_remove_method(classinfo *c)
java_handle_t * flc_object
Definition: thread.hpp:108
void threads_impl_preinit()
Definition: thread-none.cpp:52
MIIterator e
s4 opt_stacksize
Definition: options.cpp:65
void thread_set_interrupted(threadobject *t, bool interrupted)
Definition: thread.cpp:949
static bool thread_is_attached(threadobject *t)
Definition: thread.hpp:262
static java_handle_t * get_vmthread_handle(const java_lang_Thread &jlt)
static threadobject * thread_get_current()
Return the threadobject for the current thread.
Definition: thread-none.hpp:56
void threads_impl_init()
Definition: thread-none.cpp:58
void thread_set_state_timed_waiting(threadobject *t)
Definition: thread.cpp:793
void threads_park(bool absolute, int64_t nanos)
Park the current thread for the specified amount of time or until a specified deadline.
void threads_impl_clear_heap_pointers(threadobject *t)
bool signaled
Definition: thread.hpp:120
static Condition * cond_join
threadobject * thread
java_handle_t * exceptions_get_exception(void)
Definition: exceptions.cpp:76
#define Signal_INTERRUPT_SYSTEM_CALL
Definition: signallocal.hpp:43
void unlock()
Unlocks the given mutex object and checks for errors.
Definition: mutex-none.hpp:36
GNU Classpath java/lang/Thread.
java_object_t * object
Definition: thread.hpp:93
void thread_set_state_waiting(threadobject *t)
Definition: thread.cpp:773
stackframeinfo_t * _stackframeinfo
Definition: thread.hpp:129
static classinfo * get_thread_class_from_object(java_handle_t *object)
bool lock_monitor_enter(java_handle_t *o)
Definition: lock.cpp:786
void threads_sleep(int64_t millis, int32_t nanos)
void threads_sem_wait(sem_t *sem)
bool is_in_active_list
Definition: thread.hpp:100
#define THREADOBJECT
Definition: thread-none.hpp:47
void wait(Mutex *mutex)
Waits for the condition variable.
void lock()
Locks the given mutex object and checks for errors.
Definition: mutex-none.hpp:35
void threads_impl_thread_reuse(threadobject *t)
void threads_yield(void)
void timedwait(Mutex *mutex, const timespec *abstime)
static void thread_set_current(threadobject *t)
Set the threadobject for the current thread.
Definition: thread-none.hpp:63
static void threads_suspend_self()
Internal helper function which suspends the current thread.
bool threads_resume_thread(threadobject *thread, SuspendReason reason)
Resumes execution of the passed thread.