Line data Source code
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)
171 : __thread threadobject *thread_current;
172 : #else
173 : pthread_key_t thread_current_key;
174 : #endif
175 :
176 : /* global mutex for stop-the-world */
177 : static Mutex* stopworldlock;
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 */
185 : static Condition* cond_join;
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 998 : void threads_sem_init(sem_t *sem, bool shared, int value)
205 : {
206 : int r;
207 :
208 998 : assert(sem);
209 :
210 0 : do {
211 998 : r = sem_init(sem, shared, value);
212 998 : if (r == 0)
213 998 : return;
214 : } while (errno == EINTR);
215 :
216 0 : 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 998 : void threads_sem_wait(sem_t *sem)
233 : {
234 : int r;
235 :
236 998 : assert(sem);
237 :
238 0 : do {
239 998 : r = sem_wait(sem);
240 998 : if (r == 0)
241 998 : return;
242 : } while (errno == EINTR);
243 :
244 0 : 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 998 : void threads_sem_post(sem_t *sem)
258 : {
259 : int r;
260 :
261 998 : assert(sem);
262 :
263 : /* unlike sem_wait, sem_post is not interruptible */
264 :
265 998 : r = sem_post(sem);
266 998 : if (r == 0)
267 998 : return;
268 :
269 0 : 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 :
325 : result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
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 :
409 : stopworldlock->unlock();
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 :
425 0 : void threads_impl_thread_clear(threadobject *t)
426 : {
427 0 : t->object = NULL;
428 :
429 0 : t->thinlock = 0;
430 :
431 0 : t->index = 0;
432 0 : t->flags = 0;
433 0 : t->state = THREAD_STATE_NEW;
434 0 : t->is_in_active_list = false;
435 :
436 0 : t->impl.tid = 0;
437 :
438 : #if defined(__DARWIN__)
439 : t->impl.mach_thread = 0;
440 : #endif
441 :
442 0 : t->interrupted = false;
443 0 : t->signaled = false;
444 :
445 0 : t->suspended = false;
446 0 : t->suspend_reason = SUSPEND_REASON_NONE;
447 :
448 0 : t->pc = NULL;
449 :
450 0 : t->_exceptionptr = NULL;
451 0 : t->_stackframeinfo = NULL;
452 0 : 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 0 : }
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 :
478 793 : void threads_impl_thread_reuse(threadobject *t)
479 : {
480 : /* get the pthread id */
481 :
482 793 : t->impl.tid = pthread_self();
483 793 : }
484 :
485 282 : void threads_impl_clear_heap_pointers(threadobject *t)
486 : {
487 282 : t->object = 0;
488 282 : t->flc_object = 0;
489 282 : }
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 :
500 163 : void threads_impl_preinit(void)
501 : {
502 163 : stopworldlock = new Mutex();
503 :
504 : /* initialize exit mutex and condition (on exit we join all
505 : threads) */
506 :
507 163 : 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 163 : }
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 :
557 163 : void threads_impl_init(void)
558 : {
559 : pthread_attr_t attr;
560 : int result;
561 :
562 163 : threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
563 :
564 : /* Initialize the thread attribute object. */
565 :
566 163 : result = pthread_attr_init(&attr);
567 :
568 163 : if (result != 0)
569 0 : os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
570 :
571 163 : result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
572 :
573 163 : if (result != 0)
574 0 : os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
575 163 : }
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 499 : 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 499 : startup = (startupinfo*) arg;
631 :
632 499 : t = startup->thread;
633 499 : function = startup->function;
634 499 : 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 499 : 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 :
649 499 : thread_set_current(t);
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 499 : result = GC_get_stack_base(&sb);
659 :
660 499 : if (result != 0)
661 0 : vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
662 :
663 499 : GC_register_my_thread(&sb);
664 : # endif
665 : #endif
666 :
667 : // Get the java.lang.Thread object for this thread.
668 499 : java_handle_t* object = LLNI_WRAP(t->object);
669 499 : java_lang_Thread jlt(object);
670 :
671 : /* set our priority */
672 :
673 499 : threads_set_thread_priority(t->impl.tid, jlt.get_priority());
674 :
675 : /* tell threads_startup_thread that we registered ourselves */
676 : /* CAUTION: *startup becomes invalid with this! */
677 :
678 499 : startup = NULL;
679 499 : 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.
689 499 : Hook::thread_start(t);
690 :
691 499 : DEBUGTHREADS("starting", t);
692 :
693 : /* find and run the Thread.run()V method if no other function was passed */
694 :
695 499 : if (function == NULL) {
696 10 : c = ThreadRuntime::get_thread_class_from_object(object);
697 :
698 10 : m = class_resolveclassmethod(c, utf8::run, utf8::void__void, c, true);
699 :
700 10 : if (m == NULL)
701 0 : vm_abort("threads_startup_thread: run() method not found in class");
702 :
703 10 : java_handle_t *h = ThreadRuntime::get_vmthread_handle(jlt);
704 :
705 : /* Run the thread. */
706 :
707 10 : (void) vm_call_method(m, h);
708 : }
709 : else {
710 : /* call passed function, e.g. finalizer_thread */
711 :
712 489 : (function)();
713 : }
714 :
715 151 : DEBUGTHREADS("stopping", t);
716 :
717 : // Hook point just after the threads initial method returned.
718 151 : Hook::thread_end(t);
719 :
720 : /* We ignore the return value. */
721 :
722 151 : (void) thread_detach_current_thread();
723 :
724 151 : 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 :
740 499 : void threads_impl_thread_start(threadobject *thread, functionptr f)
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 499 : startup.thread = thread;
752 499 : startup.function = f; /* maybe we don't call Thread.run()V */
753 499 : startup.psem = &sem;
754 499 : startup.psem_first = &sem_first;
755 :
756 499 : threads_sem_init(&sem, 0, 0);
757 499 : threads_sem_init(&sem_first, 0, 0);
758 :
759 : /* Initialize thread attributes. */
760 :
761 499 : result = pthread_attr_init(&attr);
762 :
763 499 : if (result != 0)
764 0 : os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
765 :
766 499 : result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
767 :
768 499 : if (result != 0)
769 0 : os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
770 :
771 : /* initialize thread stacksize */
772 :
773 499 : result = pthread_attr_setstacksize(&attr, opt_stacksize);
774 :
775 499 : if (result != 0)
776 0 : os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
777 :
778 : /* create the thread */
779 :
780 499 : result = pthread_create(&(thread->impl.tid), &attr, threads_startup_thread, &startup);
781 :
782 499 : if (result != 0)
783 0 : os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
784 :
785 : /* destroy the thread attributes */
786 :
787 499 : result = pthread_attr_destroy(&attr);
788 :
789 499 : if (result != 0)
790 0 : 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 499 : threads_sem_post(&sem_first);
795 :
796 : /* wait here until the thread has entered itself into the thread list */
797 :
798 499 : threads_sem_wait(&sem);
799 :
800 : /* cleanup */
801 :
802 499 : sem_destroy(&sem);
803 499 : sem_destroy(&sem_first);
804 499 : }
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 :
817 0 : void threads_set_thread_priority(threadobject *t, int priority)
818 : {
819 0 : threads_set_thread_priority(t->impl.tid, priority);
820 0 : }
821 :
822 :
823 662 : static void threads_set_thread_priority(pthread_t tid, int priority)
824 : {
825 : struct sched_param schedp;
826 : int policy;
827 :
828 662 : pthread_getschedparam(tid, &policy, &schedp);
829 662 : schedp.sched_priority = priority;
830 662 : pthread_setschedparam(tid, policy, &schedp);
831 662 : }
832 :
833 :
834 : /**
835 : * Detaches the current thread from the VM.
836 : *
837 : * @return true on success, false otherwise
838 : */
839 282 : bool thread_detach_current_thread(void)
840 : {
841 282 : threadobject* t = thread_get_current();
842 :
843 : /* Sanity check. */
844 :
845 282 : assert(t != NULL);
846 :
847 : /* If the given thread has already been detached, this operation
848 : is a no-op. */
849 :
850 282 : if (thread_is_attached(t) == false)
851 0 : return true;
852 :
853 282 : DEBUGTHREADS("detaching", t);
854 :
855 282 : java_handle_t* object = LLNI_WRAP(t->object);
856 282 : java_lang_Thread jlt(object);
857 :
858 : #if defined(ENABLE_JAVASE)
859 282 : 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 :
865 282 : java_handle_t* e = exceptions_get_and_clear_exception();
866 :
867 282 : 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 :
872 0 : java_handle_t *handler = ThreadRuntime::get_thread_exception_handler(jlt);
873 :
874 : classinfo* c;
875 : java_handle_t* h;
876 :
877 0 : if (handler != NULL) {
878 0 : LLNI_class_get(handler, c);
879 0 : h = (java_handle_t *) handler;
880 : }
881 : else {
882 0 : LLNI_class_get(group, c);
883 0 : h = (java_handle_t *) group;
884 : }
885 :
886 : methodinfo* m = class_resolveclassmethod(c,
887 : utf8::uncaughtException,
888 : utf8::java_lang_Thread_java_lang_Throwable__V,
889 : NULL,
890 0 : true);
891 :
892 0 : if (m == NULL)
893 0 : return false;
894 :
895 0 : (void) vm_call_method(m, h, object, e);
896 :
897 0 : if (exceptions_get_exception())
898 0 : return false;
899 : }
900 :
901 : /* XXX TWISTI: should all threads be in a ThreadGroup? */
902 :
903 : /* Remove thread from the thread group. */
904 :
905 282 : if (group != NULL) {
906 : classinfo* c;
907 272 : LLNI_class_get(group, c);
908 :
909 272 : methodinfo *m = ThreadRuntime::get_threadgroup_remove_method(c);
910 :
911 272 : if (m == NULL)
912 0 : return false;
913 :
914 272 : (void) vm_call_method(m, group, object);
915 :
916 272 : if (exceptions_get_exception())
917 0 : return false;
918 :
919 : // Clear the ThreadGroup in the Java thread object (Mauve
920 : // test: gnu/testlet/java/lang/Thread/getThreadGroup).
921 272 : jlt.set_group(NULL);
922 : }
923 : #endif
924 :
925 : /* Thread has terminated. */
926 :
927 282 : thread_set_state_terminated(t);
928 :
929 : /* Notify all threads waiting on this thread. These are joining
930 : this thread. */
931 :
932 : /* XXX Care about exceptions? */
933 282 : (void) lock_monitor_enter(jlt.get_handle());
934 :
935 282 : lock_notify_all_object(jlt.get_handle());
936 :
937 : /* XXX Care about exceptions? */
938 282 : (void) lock_monitor_exit(jlt.get_handle());
939 :
940 282 : t->waitmutex->lock();
941 282 : t->impl.tid = 0;
942 282 : t->waitmutex->unlock();
943 :
944 : {
945 282 : MutexLocker lock(ThreadList::get()->mutex());
946 :
947 : /* Free the internal thread data-structure. */
948 :
949 282 : thread_free(t);
950 :
951 : /* Signal that this thread has finished and leave the mutex. */
952 :
953 282 : cond_join->signal();
954 : }
955 :
956 282 : t->suspendmutex->lock();
957 282 : t->suspendmutex->unlock();
958 :
959 282 : 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 0 : static void threads_suspend_self()
971 : {
972 0 : threadobject* thread = THREADOBJECT;
973 :
974 0 : DEBUGTHREADS("suspending", thread);
975 :
976 : // Mark thread as suspended.
977 0 : assert(!thread->suspended);
978 0 : assert(thread->suspend_reason != SUSPEND_REASON_NONE);
979 0 : thread->suspended = true;
980 :
981 : // Acknowledge the suspension.
982 0 : thread->suspendcond->broadcast();
983 :
984 : #if defined(ENABLE_GC_CACAO)
985 : // If we are stopping the world, we should send a global ack.
986 : if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
987 : threads_sem_post(&suspend_ack);
988 : #endif
989 :
990 : // Release the suspension mutex and wait till we are resumed.
991 0 : while (thread->suspend_reason != SUSPEND_REASON_NONE)
992 0 : 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.
997 : if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
998 : threads_sem_post(&suspend_ack);
999 : #endif
1000 :
1001 : // Mark thread as not suspended.
1002 0 : assert(thread->suspended);
1003 0 : assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1004 0 : thread->suspended = false;
1005 :
1006 0 : DEBUGTHREADS("resuming", thread);
1007 0 : }
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 : */
1018 0 : bool threads_suspend_thread(threadobject *thread, SuspendReason reason)
1019 : {
1020 : // Sanity check.
1021 0 : assert(reason != SUSPEND_REASON_NONE);
1022 :
1023 : // Guard this with the suspension mutex.
1024 0 : MutexLocker ml(*thread->suspendmutex);
1025 :
1026 : // Check if thread is already suspended.
1027 0 : if (thread->suspended)
1028 0 : return false;
1029 :
1030 : // Check if thread is in the process of suspending.
1031 0 : if (thread->suspend_reason != SUSPEND_REASON_NONE)
1032 0 : return false;
1033 :
1034 : // Set the reason for suspending the thread.
1035 0 : thread->suspend_reason = reason;
1036 :
1037 0 : if (thread == THREADOBJECT) {
1038 : // We already hold the suspension mutex and can suspend ourselves
1039 : // immediately without using signals at all.
1040 0 : threads_suspend_self();
1041 : }
1042 : else {
1043 : // Send the suspend signal to the other thread.
1044 0 : if (!thread->impl.tid)
1045 0 : return false;
1046 0 : if (pthread_kill(thread->impl.tid, SIGUSR1) != 0)
1047 0 : os::abort_errno("threads_suspend_thread: pthread_kill failed");
1048 :
1049 : // Wait for the thread to acknowledge the suspension.
1050 0 : while (!thread->suspended)
1051 0 : thread->suspendcond->wait(thread->suspendmutex);
1052 : }
1053 :
1054 0 : 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 : */
1065 0 : bool threads_resume_thread(threadobject *thread, SuspendReason reason)
1066 : {
1067 : // Sanity check.
1068 0 : assert(thread != THREADOBJECT);
1069 0 : assert(reason != SUSPEND_REASON_NONE);
1070 :
1071 : // Guard this with the suspension mutex.
1072 0 : MutexLocker ml(*thread->suspendmutex);
1073 :
1074 : // Check if thread really is suspended.
1075 0 : if (!thread->suspended)
1076 0 : return false;
1077 :
1078 : // Threads can only be resumed for the same reason they were suspended.
1079 0 : if (thread->suspend_reason != reason)
1080 0 : return false;
1081 :
1082 : // Clear the reason for suspending the thread.
1083 0 : thread->suspend_reason = SUSPEND_REASON_NONE;
1084 :
1085 : // Tell everyone that the thread should resume.
1086 0 : thread->suspendcond->broadcast();
1087 :
1088 0 : return true;
1089 : }
1090 :
1091 :
1092 : /**
1093 : * Acknowledges the suspension of the current thread.
1094 : */
1095 0 : void threads_suspend_ack()
1096 : {
1097 0 : threadobject* thread = THREADOBJECT;
1098 :
1099 : // Guard this with the suspension mutex.
1100 0 : MutexLocker ml(*thread->suspendmutex);
1101 :
1102 : // Suspend ourselves while holding the suspension mutex.
1103 0 : threads_suspend_self();
1104 0 : }
1105 :
1106 :
1107 : /* threads_join_all_threads ****************************************************
1108 :
1109 : Join all non-daemon threads.
1110 :
1111 : *******************************************************************************/
1112 :
1113 131 : void threads_join_all_threads(void)
1114 : {
1115 : threadobject *t;
1116 :
1117 : /* get current thread */
1118 :
1119 131 : t = THREADOBJECT;
1120 :
1121 : /* This thread is waiting for all non-daemon threads to exit. */
1122 :
1123 131 : thread_set_state_waiting(t);
1124 :
1125 : /* enter join mutex */
1126 :
1127 131 : MutexLocker lock(ThreadList::get()->mutex());
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 262 : while (ThreadList::get()->get_number_of_non_daemon_threads() > 1)
1134 0 : ThreadList::get()->wait_cond(cond_join);
1135 131 : }
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 8 : 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 8 : (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 8 : 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 8 : if (gettimeofday(&tvnow, NULL) != 0)
1180 0 : vm_abort("gettimeofday failed: %s\n", strerror(errno));
1181 :
1182 : /* convert it to a timespec */
1183 :
1184 8 : tsnow.tv_sec = tvnow.tv_sec;
1185 8 : tsnow.tv_nsec = tvnow.tv_usec * 1000;
1186 :
1187 : /* compare current time with the given timespec */
1188 :
1189 8 : 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 20011 : static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1207 : {
1208 : // Acquire the waitmutex.
1209 20011 : t->waitmutex->lock();
1210 :
1211 : /* wait on waitcond */
1212 :
1213 20015 : if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1214 : /* with timeout */
1215 12 : while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1216 : && threads_current_time_is_earlier_than(wakeupTime))
1217 : {
1218 4 : if (parking)
1219 0 : thread_set_state_timed_parked(t);
1220 : else
1221 4 : thread_set_state_timed_waiting(t);
1222 :
1223 4 : t->waitcond->timedwait(t->waitmutex, wakeupTime);
1224 :
1225 4 : thread_set_state_runnable(t);
1226 : }
1227 : }
1228 : else {
1229 : /* no timeout */
1230 40021 : while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1231 7 : if (parking)
1232 0 : thread_set_state_parked(t);
1233 : else
1234 7 : thread_set_state_waiting(t);
1235 :
1236 7 : t->waitcond->wait(t->waitmutex);
1237 :
1238 7 : thread_set_state_runnable(t);
1239 : }
1240 : }
1241 :
1242 20011 : if (parking)
1243 0 : t->park_permit = false;
1244 :
1245 : // Release the waitmutex.
1246 20011 : t->waitmutex->unlock();
1247 20011 : }
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 :
1262 20010 : void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1263 : s4 nanos)
1264 : {
1265 : struct timespec wakeupTime;
1266 :
1267 : /* calculate the the (latest) wakeup time */
1268 :
1269 20010 : threads_calc_absolute_time(&wakeupTime, millis, nanos);
1270 :
1271 : /* wait */
1272 :
1273 20010 : threads_wait_with_timeout(thread, &wakeupTime, false);
1274 20010 : }
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 20011 : 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 20011 : if (!millis && !nanos)
1295 20007 : break;
1296 : struct timeval tv;
1297 4 : gettimeofday(&tv, NULL);
1298 4 : s8 secs = tv.tv_sec + millis / 1000;
1299 4 : if (secs > INT32_MAX) // integer overflow
1300 0 : break;
1301 4 : tv.tv_sec = secs;
1302 4 : millis %= 1000;
1303 4 : long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1304 4 : tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1305 4 : if (tm->tv_sec < tv.tv_sec) // integer overflow
1306 0 : break;
1307 4 : tm->tv_nsec = nsec % 1000000000;
1308 4 : return;
1309 : } while (0);
1310 20007 : tm->tv_sec = 0;
1311 20007 : 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 :
1327 20000 : void threads_thread_interrupt(threadobject *t)
1328 : {
1329 : /* Signal the thread a "waitcond" and tell it that it has been
1330 : interrupted. */
1331 :
1332 20000 : t->waitmutex->lock();
1333 :
1334 20000 : DEBUGTHREADS("interrupted", t);
1335 :
1336 : /* Interrupt blocking system call using a signal. */
1337 :
1338 20000 : if (t->impl.tid)
1339 20000 : pthread_kill(t->impl.tid, Signal_INTERRUPT_SYSTEM_CALL);
1340 :
1341 20000 : t->waitcond->signal();
1342 :
1343 20000 : t->interrupted = true;
1344 :
1345 20000 : t->waitmutex->unlock();
1346 20000 : }
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 1 : void threads_sleep(int64_t millis, int32_t nanos)
1356 : {
1357 : threadobject *t;
1358 : struct timespec wakeupTime;
1359 : bool interrupted;
1360 :
1361 1 : if (millis < 0) {
1362 : /* exceptions_throw_illegalargumentexception(); */
1363 0 : exceptions_throw_illegalargumentexception();
1364 0 : return;
1365 : }
1366 :
1367 1 : t = thread_get_current();
1368 :
1369 1 : if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1370 : /* Clear interrupted flag (Mauve test:
1371 : gnu/testlet/java/lang/Thread/interrupt). */
1372 :
1373 0 : thread_set_interrupted(t, false);
1374 :
1375 : /* exceptions_throw_interruptedexception("sleep interrupted"); */
1376 0 : exceptions_throw_interruptedexception();
1377 0 : 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 1 : if (millis == 0 && nanos == 0) {
1386 0 : threads_yield();
1387 : }
1388 : else {
1389 1 : threads_calc_absolute_time(&wakeupTime, millis, nanos);
1390 :
1391 1 : threads_wait_with_timeout(t, &wakeupTime, false);
1392 :
1393 1 : interrupted = thread_is_interrupted(t);
1394 :
1395 1 : if (interrupted) {
1396 0 : thread_set_interrupted(t, false);
1397 :
1398 : // An other exception could have been thrown
1399 : // (e.g. ThreadDeathException).
1400 0 : if (!exceptions_get_exception())
1401 0 : exceptions_throw_interruptedexception();
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 0 : void threads_park(bool absolute, int64_t nanos)
1415 : {
1416 : threadobject *t;
1417 : struct timespec wakeupTime;
1418 :
1419 0 : t = thread_get_current();
1420 :
1421 0 : if (absolute) {
1422 0 : wakeupTime.tv_nsec = 0;
1423 0 : wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1424 : }
1425 : else
1426 0 : threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1427 :
1428 0 : threads_wait_with_timeout(t, &wakeupTime, true);
1429 0 : }
1430 :
1431 : /**
1432 : * Unpark the specified thread.
1433 : *
1434 : * @param t The thread to unpark.
1435 : */
1436 0 : void threads_unpark(threadobject *t)
1437 : {
1438 0 : t->waitmutex->lock();
1439 :
1440 0 : t->waitcond->signal();
1441 :
1442 0 : t->park_permit = true;
1443 :
1444 0 : t->waitmutex->unlock();
1445 0 : }
1446 :
1447 :
1448 : /* threads_yield ***************************************************************
1449 :
1450 : Yield to the scheduler.
1451 :
1452 : *******************************************************************************/
1453 :
1454 0 : void threads_yield(void)
1455 : {
1456 0 : sched_yield();
1457 0 : }
1458 :
1459 :
1460 : /***
1461 : * Return the tid of a thread.
1462 : */
1463 0 : intptr_t threads_get_tid(threadobject *t) {
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 0 : 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 : */
|