Ruby  1.9.3p392(2013-02-22revision39386)
thread_pthread.c
Go to the documentation of this file.
1 /* -*-c-*- */
2 /**********************************************************************
3 
4  thread_pthread.c -
5 
6  $Author: usa $
7 
8  Copyright (C) 2004-2007 Koichi Sasada
9 
10 **********************************************************************/
11 
12 #ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
13 
14 #include "gc.h"
15 
16 #ifdef HAVE_SYS_RESOURCE_H
17 #include <sys/resource.h>
18 #endif
19 #ifdef HAVE_THR_STKSEGMENT
20 #include <thread.h>
21 #endif
22 #if HAVE_FCNTL_H
23 #include <fcntl.h>
24 #elif HAVE_SYS_FCNTL_H
25 #include <sys/fcntl.h>
26 #endif
27 
28 static void native_mutex_lock(pthread_mutex_t *lock);
29 static void native_mutex_unlock(pthread_mutex_t *lock);
30 static int native_mutex_trylock(pthread_mutex_t *lock);
31 static void native_mutex_initialize(pthread_mutex_t *lock);
32 static void native_mutex_destroy(pthread_mutex_t *lock);
33 static void native_cond_signal(rb_thread_cond_t *cond);
34 static void native_cond_broadcast(rb_thread_cond_t *cond);
35 static void native_cond_wait(rb_thread_cond_t *cond, pthread_mutex_t *mutex);
36 static void native_cond_initialize(rb_thread_cond_t *cond, int flags);
37 static void native_cond_destroy(rb_thread_cond_t *cond);
38 static pthread_t timer_thread_id;
39 
40 #define RB_CONDATTR_CLOCK_MONOTONIC 1
41 
42 #if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCKID_T) && \
43  defined(CLOCK_REALTIME) && defined(CLOCK_MONOTONIC) && defined(HAVE_CLOCK_GETTIME)
44 #define USE_MONOTONIC_COND 1
45 #else
46 #define USE_MONOTONIC_COND 0
47 #endif
48 
49 static void
50 gvl_acquire_common(rb_vm_t *vm)
51 {
52  if (vm->gvl.acquired) {
53 
54  vm->gvl.waiting++;
55  if (vm->gvl.waiting == 1) {
56  /* transit to polling mode */
58  }
59 
60  while (vm->gvl.acquired) {
61  native_cond_wait(&vm->gvl.cond, &vm->gvl.lock);
62  }
63 
64  vm->gvl.waiting--;
65 
66  if (vm->gvl.need_yield) {
67  vm->gvl.need_yield = 0;
68  native_cond_signal(&vm->gvl.switch_cond);
69  }
70  }
71 
72  vm->gvl.acquired = 1;
73 }
74 
75 static void
76 gvl_acquire(rb_vm_t *vm, rb_thread_t *th)
77 {
78  native_mutex_lock(&vm->gvl.lock);
79  gvl_acquire_common(vm);
80  native_mutex_unlock(&vm->gvl.lock);
81 }
82 
83 static void
84 gvl_release_common(rb_vm_t *vm)
85 {
86  vm->gvl.acquired = 0;
87  if (vm->gvl.waiting > 0)
88  native_cond_signal(&vm->gvl.cond);
89 }
90 
91 static void
92 gvl_release(rb_vm_t *vm)
93 {
94  native_mutex_lock(&vm->gvl.lock);
95  gvl_release_common(vm);
96  native_mutex_unlock(&vm->gvl.lock);
97 }
98 
99 static void
100 gvl_yield(rb_vm_t *vm, rb_thread_t *th)
101 {
102  native_mutex_lock(&vm->gvl.lock);
103 
104  gvl_release_common(vm);
105 
106  /* An another thread is processing GVL yield. */
107  if (UNLIKELY(vm->gvl.wait_yield)) {
108  while (vm->gvl.wait_yield)
109  native_cond_wait(&vm->gvl.switch_wait_cond, &vm->gvl.lock);
110  goto acquire;
111  }
112 
113  if (vm->gvl.waiting > 0) {
114  /* Wait until another thread task take GVL. */
115  vm->gvl.need_yield = 1;
116  vm->gvl.wait_yield = 1;
117  while (vm->gvl.need_yield)
118  native_cond_wait(&vm->gvl.switch_cond, &vm->gvl.lock);
119  vm->gvl.wait_yield = 0;
120  }
121  else {
122  native_mutex_unlock(&vm->gvl.lock);
123  sched_yield();
124  native_mutex_lock(&vm->gvl.lock);
125  }
126 
127  native_cond_broadcast(&vm->gvl.switch_wait_cond);
128  acquire:
129  gvl_acquire_common(vm);
130  native_mutex_unlock(&vm->gvl.lock);
131 }
132 
133 static void
134 gvl_init(rb_vm_t *vm)
135 {
136  native_mutex_initialize(&vm->gvl.lock);
137  native_cond_initialize(&vm->gvl.cond, RB_CONDATTR_CLOCK_MONOTONIC);
138  native_cond_initialize(&vm->gvl.switch_cond, RB_CONDATTR_CLOCK_MONOTONIC);
139  native_cond_initialize(&vm->gvl.switch_wait_cond, RB_CONDATTR_CLOCK_MONOTONIC);
140  vm->gvl.acquired = 0;
141  vm->gvl.waiting = 0;
142  vm->gvl.need_yield = 0;
143  vm->gvl.wait_yield = 0;
144 }
145 
146 static void
147 gvl_destroy(rb_vm_t *vm)
148 {
149  native_cond_destroy(&vm->gvl.switch_wait_cond);
150  native_cond_destroy(&vm->gvl.switch_cond);
151  native_cond_destroy(&vm->gvl.cond);
152  native_mutex_destroy(&vm->gvl.lock);
153 }
154 
155 static void
156 gvl_atfork(rb_vm_t *vm)
157 {
158  gvl_init(vm);
159  gvl_acquire(vm, GET_THREAD());
160 }
161 
162 #define NATIVE_MUTEX_LOCK_DEBUG 0
163 
164 static void
165 mutex_debug(const char *msg, pthread_mutex_t *lock)
166 {
167  if (NATIVE_MUTEX_LOCK_DEBUG) {
168  int r;
169  static pthread_mutex_t dbglock = PTHREAD_MUTEX_INITIALIZER;
170 
171  if ((r = pthread_mutex_lock(&dbglock)) != 0) {exit(EXIT_FAILURE);}
172  fprintf(stdout, "%s: %p\n", msg, (void *)lock);
173  if ((r = pthread_mutex_unlock(&dbglock)) != 0) {exit(EXIT_FAILURE);}
174  }
175 }
176 
177 static void
178 native_mutex_lock(pthread_mutex_t *lock)
179 {
180  int r;
181  mutex_debug("lock", lock);
182  if ((r = pthread_mutex_lock(lock)) != 0) {
183  rb_bug_errno("pthread_mutex_lock", r);
184  }
185 }
186 
187 static void
188 native_mutex_unlock(pthread_mutex_t *lock)
189 {
190  int r;
191  mutex_debug("unlock", lock);
192  if ((r = pthread_mutex_unlock(lock)) != 0) {
193  rb_bug_errno("pthread_mutex_unlock", r);
194  }
195 }
196 
197 static inline int
198 native_mutex_trylock(pthread_mutex_t *lock)
199 {
200  int r;
201  mutex_debug("trylock", lock);
202  if ((r = pthread_mutex_trylock(lock)) != 0) {
203  if (r == EBUSY) {
204  return EBUSY;
205  }
206  else {
207  rb_bug_errno("pthread_mutex_trylock", r);
208  }
209  }
210  return 0;
211 }
212 
213 static void
214 native_mutex_initialize(pthread_mutex_t *lock)
215 {
216  int r = pthread_mutex_init(lock, 0);
217  mutex_debug("init", lock);
218  if (r != 0) {
219  rb_bug_errno("pthread_mutex_init", r);
220  }
221 }
222 
223 static void
224 native_mutex_destroy(pthread_mutex_t *lock)
225 {
226  int r = pthread_mutex_destroy(lock);
227  mutex_debug("destroy", lock);
228  if (r != 0) {
229  rb_bug_errno("pthread_mutex_destroy", r);
230  }
231 }
232 
233 static void
234 native_cond_initialize(rb_thread_cond_t *cond, int flags)
235 {
236  int r;
237  pthread_condattr_t attr;
238 
239  pthread_condattr_init(&attr);
240 
241 #if USE_MONOTONIC_COND
242  cond->clockid = CLOCK_REALTIME;
243  if (flags & RB_CONDATTR_CLOCK_MONOTONIC) {
244  r = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
245  if (r == 0) {
246  cond->clockid = CLOCK_MONOTONIC;
247  }
248  }
249 #endif
250 
251  r = pthread_cond_init(&cond->cond, &attr);
252  pthread_condattr_destroy(&attr);
253  if (r != 0) {
254  rb_bug_errno("pthread_cond_init", r);
255  }
256 
257  return;
258  }
259 
260 static void
261 native_cond_destroy(rb_thread_cond_t *cond)
262 {
263  int r = pthread_cond_destroy(&cond->cond);
264  if (r != 0) {
265  rb_bug_errno("pthread_cond_destroy", r);
266  }
267 }
268 
269 /*
270  * In OS X 10.7 (Lion), pthread_cond_signal and pthread_cond_broadcast return
271  * EAGAIN after retrying 8192 times. You can see them in the following page:
272  *
273  * http://www.opensource.apple.com/source/Libc/Libc-763.11/pthreads/pthread_cond.c
274  *
275  * The following native_cond_signal and native_cond_broadcast functions
276  * need to retrying until pthread functions don't return EAGAIN.
277  */
278 
279 static void
280 native_cond_signal(rb_thread_cond_t *cond)
281 {
282  int r;
283  do {
284  r = pthread_cond_signal(&cond->cond);
285  } while (r == EAGAIN);
286  if (r != 0) {
287  rb_bug_errno("pthread_cond_signal", r);
288  }
289 }
290 
291 static void
292 native_cond_broadcast(rb_thread_cond_t *cond)
293 {
294  int r;
295  do {
296  r = pthread_cond_broadcast(&cond->cond);
297  } while (r == EAGAIN);
298  if (r != 0) {
299  rb_bug_errno("native_cond_broadcast", r);
300  }
301 }
302 
303 static void
304 native_cond_wait(rb_thread_cond_t *cond, pthread_mutex_t *mutex)
305 {
306  int r = pthread_cond_wait(&cond->cond, mutex);
307  if (r != 0) {
308  rb_bug_errno("pthread_cond_wait", r);
309  }
310 }
311 
312 static int
313 native_cond_timedwait(rb_thread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *ts)
314 {
315  int r;
316 
317  /*
318  * An old Linux may return EINTR. Even though POSIX says
319  * "These functions shall not return an error code of [EINTR]".
320  * http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html
321  * Let's hide it from arch generic code.
322  */
323  do {
324  r = pthread_cond_timedwait(&cond->cond, mutex, ts);
325  } while (r == EINTR);
326 
327  if (r != 0 && r != ETIMEDOUT) {
328  rb_bug_errno("pthread_cond_timedwait", r);
329  }
330 
331  return r;
332 }
333 
334 #if SIZEOF_TIME_T == SIZEOF_LONG
335 typedef unsigned long unsigned_time_t;
336 #elif SIZEOF_TIME_T == SIZEOF_INT
337 typedef unsigned int unsigned_time_t;
338 #elif SIZEOF_TIME_T == SIZEOF_LONG_LONG
339 typedef unsigned LONG_LONG unsigned_time_t;
340 #else
341 # error cannot find integer type which size is same as time_t.
342 #endif
343 
344 #define TIMET_MAX (~(time_t)0 <= 0 ? (time_t)((~(unsigned_time_t)0) >> 1) : (time_t)(~(unsigned_time_t)0))
345 
346 static struct timespec
347 native_cond_timeout(rb_thread_cond_t *cond, struct timespec timeout_rel)
348 {
349  int ret;
350  struct timeval tv;
351  struct timespec timeout;
352  struct timespec now;
353 
354 #if USE_MONOTONIC_COND
355  if (cond->clockid == CLOCK_MONOTONIC) {
356  ret = clock_gettime(cond->clockid, &now);
357  if (ret != 0)
358  rb_sys_fail("clock_gettime()");
359  goto out;
360  }
361 
362  if (cond->clockid != CLOCK_REALTIME)
363  rb_bug("unsupported clockid %d", cond->clockid);
364 #endif
365 
366  ret = gettimeofday(&tv, 0);
367  if (ret != 0)
368  rb_sys_fail(0);
369  now.tv_sec = tv.tv_sec;
370  now.tv_nsec = tv.tv_usec * 1000;
371 
372 #if USE_MONOTONIC_COND
373  out:
374 #endif
375  timeout.tv_sec = now.tv_sec;
376  timeout.tv_nsec = now.tv_nsec;
377  timeout.tv_sec += timeout_rel.tv_sec;
378  timeout.tv_nsec += timeout_rel.tv_nsec;
379 
380  if (timeout.tv_nsec >= 1000*1000*1000) {
381  timeout.tv_sec++;
382  timeout.tv_nsec -= 1000*1000*1000;
383  }
384 
385  if (timeout.tv_sec < now.tv_sec)
386  timeout.tv_sec = TIMET_MAX;
387 
388  return timeout;
389 }
390 
391 #define native_cleanup_push pthread_cleanup_push
392 #define native_cleanup_pop pthread_cleanup_pop
393 #ifdef HAVE_SCHED_YIELD
394 #define native_thread_yield() (void)sched_yield()
395 #else
396 #define native_thread_yield() ((void)0)
397 #endif
398 
399 #if defined(SIGVTALRM) && !defined(__CYGWIN__) && !defined(__SYMBIAN32__)
400 #define USE_SIGNAL_THREAD_LIST 1
401 #endif
402 #ifdef USE_SIGNAL_THREAD_LIST
403 static void add_signal_thread_list(rb_thread_t *th);
404 static void remove_signal_thread_list(rb_thread_t *th);
405 static rb_thread_lock_t signal_thread_list_lock;
406 #endif
407 
408 static pthread_key_t ruby_native_thread_key;
409 
410 static void
411 null_func(int i)
412 {
413  /* null */
414 }
415 
416 static rb_thread_t *
417 ruby_thread_from_native(void)
418 {
419  return pthread_getspecific(ruby_native_thread_key);
420 }
421 
422 static int
423 ruby_thread_set_native(rb_thread_t *th)
424 {
425  return pthread_setspecific(ruby_native_thread_key, th) == 0;
426 }
427 
428 static void native_thread_init(rb_thread_t *th);
429 
430 void
431 Init_native_thread(void)
432 {
433  rb_thread_t *th = GET_THREAD();
434 
435  pthread_key_create(&ruby_native_thread_key, NULL);
436  th->thread_id = pthread_self();
437  native_thread_init(th);
438 #ifdef USE_SIGNAL_THREAD_LIST
439  native_mutex_initialize(&signal_thread_list_lock);
440 #endif
441  posix_signal(SIGVTALRM, null_func);
442 }
443 
444 static void
445 native_thread_init(rb_thread_t *th)
446 {
447  native_cond_initialize(&th->native_thread_data.sleep_cond, RB_CONDATTR_CLOCK_MONOTONIC);
448  ruby_thread_set_native(th);
449 }
450 
451 static void
452 native_thread_destroy(rb_thread_t *th)
453 {
454  native_cond_destroy(&th->native_thread_data.sleep_cond);
455 }
456 
457 #define USE_THREAD_CACHE 0
458 
459 #if USE_THREAD_CACHE
460 static rb_thread_t *register_cached_thread_and_wait(void);
461 #endif
462 
463 #if defined HAVE_PTHREAD_GETATTR_NP || defined HAVE_PTHREAD_ATTR_GET_NP
464 #define STACKADDR_AVAILABLE 1
465 #elif defined HAVE_PTHREAD_GET_STACKADDR_NP && defined HAVE_PTHREAD_GET_STACKSIZE_NP
466 #define STACKADDR_AVAILABLE 1
467 #elif defined HAVE_THR_STKSEGMENT || defined HAVE_PTHREAD_STACKSEG_NP
468 #define STACKADDR_AVAILABLE 1
469 #elif defined HAVE_PTHREAD_GETTHRDS_NP
470 #define STACKADDR_AVAILABLE 1
471 #endif
472 
473 #ifdef STACKADDR_AVAILABLE
474 /*
475  * Get the initial address and size of current thread's stack
476  */
477 static int
478 get_stack(void **addr, size_t *size)
479 {
480 #define CHECK_ERR(expr) \
481  {int err = (expr); if (err) return err;}
482 #ifdef HAVE_PTHREAD_GETATTR_NP /* Linux */
483  pthread_attr_t attr;
484  size_t guard = 0;
486  CHECK_ERR(pthread_getattr_np(pthread_self(), &attr));
487 # ifdef HAVE_PTHREAD_ATTR_GETSTACK
488  CHECK_ERR(pthread_attr_getstack(&attr, addr, size));
489  STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + *size));
490 # else
491  CHECK_ERR(pthread_attr_getstackaddr(&attr, addr));
492  CHECK_ERR(pthread_attr_getstacksize(&attr, size));
493 # endif
494  CHECK_ERR(pthread_attr_getguardsize(&attr, &guard));
495  *size -= guard;
496  pthread_attr_destroy(&attr);
497 #elif defined HAVE_PTHREAD_ATTR_GET_NP /* FreeBSD, DragonFly BSD, NetBSD */
498  pthread_attr_t attr;
499  CHECK_ERR(pthread_attr_init(&attr));
500  CHECK_ERR(pthread_attr_get_np(pthread_self(), &attr));
501 # ifdef HAVE_PTHREAD_ATTR_GETSTACK
502  CHECK_ERR(pthread_attr_getstack(&attr, addr, size));
503  STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + *size));
504 # else
505  CHECK_ERR(pthread_attr_getstackaddr(&attr, addr));
506  CHECK_ERR(pthread_attr_getstacksize(&attr, size));
507  STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + *size));
508 # endif
509  pthread_attr_destroy(&attr);
510 #elif (defined HAVE_PTHREAD_GET_STACKADDR_NP && defined HAVE_PTHREAD_GET_STACKSIZE_NP) /* MacOS X */
511  pthread_t th = pthread_self();
512  *addr = pthread_get_stackaddr_np(th);
513  *size = pthread_get_stacksize_np(th);
514 #elif defined HAVE_THR_STKSEGMENT || defined HAVE_PTHREAD_STACKSEG_NP
515  stack_t stk;
516 # if defined HAVE_THR_STKSEGMENT /* Solaris */
517  CHECK_ERR(thr_stksegment(&stk));
518 # else /* OpenBSD */
519  CHECK_ERR(pthread_stackseg_np(pthread_self(), &stk));
520 # endif
521  *addr = stk.ss_sp;
522  *size = stk.ss_size;
523 #elif defined HAVE_PTHREAD_GETTHRDS_NP /* AIX */
524  pthread_t th = pthread_self();
525  struct __pthrdsinfo thinfo;
526  char reg[256];
527  int regsiz=sizeof(reg);
528  CHECK_ERR(pthread_getthrds_np(&th, PTHRDSINFO_QUERY_ALL,
529  &thinfo, sizeof(thinfo),
530  &reg, &regsiz));
531  *addr = thinfo.__pi_stackaddr;
532  *size = thinfo.__pi_stacksize;
533  STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + *size));
534 #else
535 #error STACKADDR_AVAILABLE is defined but not implemented.
536 #endif
537  return 0;
538 #undef CHECK_ERR
539 }
540 #endif
541 
542 static struct {
544  size_t stack_maxsize;
545  VALUE *stack_start;
546 #ifdef __ia64
547  VALUE *register_stack_start;
548 #endif
549 } native_main_thread;
550 
551 #ifdef STACK_END_ADDRESS
552 extern void *STACK_END_ADDRESS;
553 #endif
554 
555 #undef ruby_init_stack
556 void
557 ruby_init_stack(volatile VALUE *addr
558 #ifdef __ia64
559  , void *bsp
560 #endif
561  )
562 {
563  native_main_thread.id = pthread_self();
564 #ifdef STACK_END_ADDRESS
565  native_main_thread.stack_start = STACK_END_ADDRESS;
566 #else
567  if (!native_main_thread.stack_start ||
568  STACK_UPPER((VALUE *)(void *)&addr,
569  native_main_thread.stack_start > addr,
570  native_main_thread.stack_start < addr)) {
571  native_main_thread.stack_start = (VALUE *)addr;
572  }
573 #endif
574 #ifdef __ia64
575  if (!native_main_thread.register_stack_start ||
576  (VALUE*)bsp < native_main_thread.register_stack_start) {
577  native_main_thread.register_stack_start = (VALUE*)bsp;
578  }
579 #endif
580  {
581  size_t size = 0;
582  size_t space = 0;
583 #if defined(STACKADDR_AVAILABLE)
584  void* stackaddr;
586  get_stack(&stackaddr, &size);
587  space = STACK_DIR_UPPER((char *)addr - (char *)stackaddr, (char *)stackaddr - (char *)addr);
588 #elif defined(HAVE_GETRLIMIT)
589  struct rlimit rlim;
590  if (getrlimit(RLIMIT_STACK, &rlim) == 0) {
591  size = (size_t)rlim.rlim_cur;
592  }
593  space = size > 5 * 1024 * 1024 ? 1024 * 1024 : size / 5;
594 #endif
595  native_main_thread.stack_maxsize = size - space;
596  }
597 }
598 
599 #define CHECK_ERR(expr) \
600  {int err = (expr); if (err) {rb_bug_errno(#expr, err);}}
601 
602 static int
603 native_thread_init_stack(rb_thread_t *th)
604 {
605  rb_thread_id_t curr = pthread_self();
606 
607  if (pthread_equal(curr, native_main_thread.id)) {
608  th->machine_stack_start = native_main_thread.stack_start;
609  th->machine_stack_maxsize = native_main_thread.stack_maxsize;
610  }
611  else {
612 #ifdef STACKADDR_AVAILABLE
613  void *start;
614  size_t size;
615 
616  if (get_stack(&start, &size) == 0) {
617  th->machine_stack_start = start;
619  }
620 #else
621  rb_raise(rb_eNotImpError, "ruby engine can initialize only in the main thread");
622 #endif
623  }
624 #ifdef __ia64
625  th->machine_register_stack_start = native_main_thread.register_stack_start;
626  th->machine_stack_maxsize /= 2;
627  th->machine_register_stack_maxsize = th->machine_stack_maxsize;
628 #endif
629  return 0;
630 }
631 
632 #ifndef __CYGWIN__
633 #define USE_NATIVE_THREAD_INIT 1
634 #endif
635 
636 static void *
637 thread_start_func_1(void *th_ptr)
638 {
639 #if USE_THREAD_CACHE
640  thread_start:
641 #endif
642  {
643  rb_thread_t *th = th_ptr;
644 #if !defined USE_NATIVE_THREAD_INIT
645  VALUE stack_start;
646 #endif
647 
648 #if defined USE_NATIVE_THREAD_INIT
649  native_thread_init_stack(th);
650 #endif
651  native_thread_init(th);
652  /* run */
653 #if defined USE_NATIVE_THREAD_INIT
654  thread_start_func_2(th, th->machine_stack_start, rb_ia64_bsp());
655 #else
656  thread_start_func_2(th, &stack_start, rb_ia64_bsp());
657 #endif
658  }
659 #if USE_THREAD_CACHE
660  if (1) {
661  /* cache thread */
662  rb_thread_t *th;
663  if ((th = register_cached_thread_and_wait()) != 0) {
664  th_ptr = (void *)th;
665  th->thread_id = pthread_self();
666  goto thread_start;
667  }
668  }
669 #endif
670  return 0;
671 }
672 
673 struct cached_thread_entry {
674  volatile rb_thread_t **th_area;
676  struct cached_thread_entry *next;
677 };
678 
679 
680 #if USE_THREAD_CACHE
681 static pthread_mutex_t thread_cache_lock = PTHREAD_MUTEX_INITIALIZER;
682 struct cached_thread_entry *cached_thread_root;
683 
684 static rb_thread_t *
685 register_cached_thread_and_wait(void)
686 {
687  rb_thread_cond_t cond = { PTHREAD_COND_INITIALIZER, };
688  volatile rb_thread_t *th_area = 0;
689  struct cached_thread_entry *entry =
690  (struct cached_thread_entry *)malloc(sizeof(struct cached_thread_entry));
691 
692  struct timeval tv;
693  struct timespec ts;
694  gettimeofday(&tv, 0);
695  ts.tv_sec = tv.tv_sec + 60;
696  ts.tv_nsec = tv.tv_usec * 1000;
697 
698  pthread_mutex_lock(&thread_cache_lock);
699  {
700  entry->th_area = &th_area;
701  entry->cond = &cond;
702  entry->next = cached_thread_root;
703  cached_thread_root = entry;
704 
705  native_cond_timedwait(&cond, &thread_cache_lock, &ts);
706 
707  {
708  struct cached_thread_entry *e = cached_thread_root;
709  struct cached_thread_entry *prev = cached_thread_root;
710 
711  while (e) {
712  if (e == entry) {
713  if (prev == cached_thread_root) {
714  cached_thread_root = e->next;
715  }
716  else {
717  prev->next = e->next;
718  }
719  break;
720  }
721  prev = e;
722  e = e->next;
723  }
724  }
725 
726  free(entry); /* ok */
727  native_cond_destroy(&cond);
728  }
729  pthread_mutex_unlock(&thread_cache_lock);
730 
731  return (rb_thread_t *)th_area;
732 }
733 #endif
734 
735 static int
736 use_cached_thread(rb_thread_t *th)
737 {
738  int result = 0;
739 #if USE_THREAD_CACHE
740  struct cached_thread_entry *entry;
741 
742  if (cached_thread_root) {
743  pthread_mutex_lock(&thread_cache_lock);
744  entry = cached_thread_root;
745  {
746  if (cached_thread_root) {
747  cached_thread_root = entry->next;
748  *entry->th_area = th;
749  result = 1;
750  }
751  }
752  if (result) {
753  native_cond_signal(entry->cond);
754  }
755  pthread_mutex_unlock(&thread_cache_lock);
756  }
757 #endif
758  return result;
759 }
760 
761 enum {
762 #ifdef __SYMBIAN32__
763  RUBY_STACK_MIN_LIMIT = 64 * 1024, /* 64KB: Let's be slightly more frugal on mobile platform */
764 #else
765  RUBY_STACK_MIN_LIMIT = 512 * 1024, /* 512KB */
766 #endif
767  RUBY_STACK_SPACE_LIMIT = 1024 * 1024
768 };
769 
770 #ifdef PTHREAD_STACK_MIN
771 #define RUBY_STACK_MIN ((RUBY_STACK_MIN_LIMIT < PTHREAD_STACK_MIN) ? \
772  PTHREAD_STACK_MIN * 2 : RUBY_STACK_MIN_LIMIT)
773 #else
774 #define RUBY_STACK_MIN (RUBY_STACK_MIN_LIMIT)
775 #endif
776 #define RUBY_STACK_SPACE (RUBY_STACK_MIN/5 > RUBY_STACK_SPACE_LIMIT ? \
777  RUBY_STACK_SPACE_LIMIT : RUBY_STACK_MIN/5)
778 
779 static int
780 native_thread_create(rb_thread_t *th)
781 {
782  int err = 0;
783 
784  if (use_cached_thread(th)) {
785  thread_debug("create (use cached thread): %p\n", (void *)th);
786  }
787  else {
788  pthread_attr_t attr;
789  const size_t stack_size = RUBY_STACK_MIN;
790  const size_t space = RUBY_STACK_SPACE;
791 
792  th->machine_stack_maxsize = stack_size - space;
793 #ifdef __ia64
794  th->machine_stack_maxsize /= 2;
795  th->machine_register_stack_maxsize = th->machine_stack_maxsize;
796 #endif
797 
798  CHECK_ERR(pthread_attr_init(&attr));
799 
800 #ifdef PTHREAD_STACK_MIN
801  thread_debug("create - stack size: %lu\n", (unsigned long)stack_size);
802  CHECK_ERR(pthread_attr_setstacksize(&attr, stack_size));
803 #endif
804 
805 #ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
806  CHECK_ERR(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
807 #endif
808  CHECK_ERR(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
809 
810  err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
811  thread_debug("create: %p (%d)\n", (void *)th, err);
812  CHECK_ERR(pthread_attr_destroy(&attr));
813  }
814  return err;
815 }
816 
817 static void
818 native_thread_join(pthread_t th)
819 {
820  int err = pthread_join(th, 0);
821  if (err) {
822  rb_raise(rb_eThreadError, "native_thread_join() failed (%d)", err);
823  }
824 }
825 
826 
827 #if USE_NATIVE_THREAD_PRIORITY
828 
829 static void
830 native_thread_apply_priority(rb_thread_t *th)
831 {
832 #if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING > 0)
833  struct sched_param sp;
834  int policy;
835  int priority = 0 - th->priority;
836  int max, min;
837  pthread_getschedparam(th->thread_id, &policy, &sp);
838  max = sched_get_priority_max(policy);
839  min = sched_get_priority_min(policy);
840 
841  if (min > priority) {
842  priority = min;
843  }
844  else if (max < priority) {
845  priority = max;
846  }
847 
848  sp.sched_priority = priority;
849  pthread_setschedparam(th->thread_id, policy, &sp);
850 #else
851  /* not touched */
852 #endif
853 }
854 
855 #endif /* USE_NATIVE_THREAD_PRIORITY */
856 
857 static void
858 ubf_pthread_cond_signal(void *ptr)
859 {
860  rb_thread_t *th = (rb_thread_t *)ptr;
861  thread_debug("ubf_pthread_cond_signal (%p)\n", (void *)th);
862  native_cond_signal(&th->native_thread_data.sleep_cond);
863 }
864 
865 static void
866 native_sleep(rb_thread_t *th, struct timeval *timeout_tv)
867 {
868  struct timespec timeout;
869  pthread_mutex_t *lock = &th->interrupt_lock;
871 
872  if (timeout_tv) {
873  struct timespec timeout_rel;
874 
875  timeout_rel.tv_sec = timeout_tv->tv_sec;
876  timeout_rel.tv_nsec = timeout_tv->tv_usec * 1000;
877 
878  /* Solaris cond_timedwait() return EINVAL if an argument is greater than
879  * current_time + 100,000,000. So cut up to 100,000,000. This is
880  * considered as a kind of spurious wakeup. The caller to native_sleep
881  * should care about spurious wakeup.
882  *
883  * See also [Bug #1341] [ruby-core:29702]
884  * http://download.oracle.com/docs/cd/E19683-01/816-0216/6m6ngupgv/index.html
885  */
886  if (timeout_rel.tv_sec > 100000000) {
887  timeout_rel.tv_sec = 100000000;
888  timeout_rel.tv_nsec = 0;
889  }
890 
891  timeout = native_cond_timeout(cond, timeout_rel);
892  }
893 
895  {
896  pthread_mutex_lock(lock);
897  th->unblock.func = ubf_pthread_cond_signal;
898  th->unblock.arg = th;
899 
900  if (RUBY_VM_INTERRUPTED(th)) {
901  /* interrupted. return immediate */
902  thread_debug("native_sleep: interrupted before sleep\n");
903  }
904  else {
905  if (!timeout_tv)
906  native_cond_wait(cond, lock);
907  else
908  native_cond_timedwait(cond, lock, &timeout);
909  }
910  th->unblock.func = 0;
911  th->unblock.arg = 0;
912 
913  pthread_mutex_unlock(lock);
914  }
915  GVL_UNLOCK_END();
916 
917  thread_debug("native_sleep done\n");
918 }
919 
920 #ifdef USE_SIGNAL_THREAD_LIST
921 struct signal_thread_list {
922  rb_thread_t *th;
923  struct signal_thread_list *prev;
924  struct signal_thread_list *next;
925 };
926 
927 static struct signal_thread_list signal_thread_list_anchor = {
928  0, 0, 0,
929 };
930 
931 #define FGLOCK(lock, body) do { \
932  native_mutex_lock(lock); \
933  { \
934  body; \
935  } \
936  native_mutex_unlock(lock); \
937 } while (0)
938 
939 #if 0 /* for debug */
940 static void
941 print_signal_list(char *str)
942 {
943  struct signal_thread_list *list =
944  signal_thread_list_anchor.next;
945  thread_debug("list (%s)> ", str);
946  while(list){
947  thread_debug("%p (%p), ", list->th, list->th->thread_id);
948  list = list->next;
949  }
950  thread_debug("\n");
951 }
952 #endif
953 
954 static void
955 add_signal_thread_list(rb_thread_t *th)
956 {
958  FGLOCK(&signal_thread_list_lock, {
959  struct signal_thread_list *list =
960  malloc(sizeof(struct signal_thread_list));
961 
962  if (list == 0) {
963  fprintf(stderr, "[FATAL] failed to allocate memory\n");
964  exit(EXIT_FAILURE);
965  }
966 
967  list->th = th;
968 
969  list->prev = &signal_thread_list_anchor;
970  list->next = signal_thread_list_anchor.next;
971  if (list->next) {
972  list->next->prev = list;
973  }
974  signal_thread_list_anchor.next = list;
976  });
977  }
978 }
979 
980 static void
981 remove_signal_thread_list(rb_thread_t *th)
982 {
984  FGLOCK(&signal_thread_list_lock, {
985  struct signal_thread_list *list =
986  (struct signal_thread_list *)
988 
989  list->prev->next = list->next;
990  if (list->next) {
991  list->next->prev = list->prev;
992  }
994  list->th = 0;
995  free(list); /* ok */
996  });
997  }
998 }
999 
1000 static void
1001 ubf_select_each(rb_thread_t *th)
1002 {
1003  thread_debug("ubf_select_each (%p)\n", (void *)th->thread_id);
1004  if (th) {
1005  pthread_kill(th->thread_id, SIGVTALRM);
1006  }
1007 }
1008 
1009 static void
1010 ubf_select(void *ptr)
1011 {
1012  rb_thread_t *th = (rb_thread_t *)ptr;
1013  add_signal_thread_list(th);
1014  if (pthread_self() != timer_thread_id)
1015  rb_thread_wakeup_timer_thread(); /* activate timer thread */
1016  ubf_select_each(th);
1017 }
1018 
1019 static void
1020 ping_signal_thread_list(void) {
1021  if (signal_thread_list_anchor.next) {
1022  FGLOCK(&signal_thread_list_lock, {
1023  struct signal_thread_list *list;
1024 
1025  list = signal_thread_list_anchor.next;
1026  while (list) {
1027  ubf_select_each(list->th);
1028  list = list->next;
1029  }
1030  });
1031  }
1032 }
1033 
1034 static int
1035 check_signal_thread_list(void)
1036 {
1037  if (signal_thread_list_anchor.next)
1038  return 1;
1039  else
1040  return 0;
1041 }
1042 #else /* USE_SIGNAL_THREAD_LIST */
1043 static void add_signal_thread_list(rb_thread_t *th) { }
1044 static void remove_signal_thread_list(rb_thread_t *th) { }
1045 #define ubf_select 0
1046 static void ping_signal_thread_list(void) { return; }
1047 static int check_signal_thread_list(void) { return 0; }
1048 #endif /* USE_SIGNAL_THREAD_LIST */
1049 
1050 static int timer_thread_pipe[2] = {-1, -1};
1051 static int timer_thread_pipe_owner_process;
1052 
1053 #define TT_DEBUG 0
1054 
1055 #define WRITE_CONST(fd, str) (void)(write((fd),(str),sizeof(str)-1)<0)
1056 
1057 /* only use signal-safe system calls here */
1058 void
1060 {
1061  ssize_t result;
1062 
1063  /* already opened */
1064  if (timer_thread_pipe_owner_process == getpid()) {
1065  const char *buff = "!";
1066  retry:
1067  if ((result = write(timer_thread_pipe[1], buff, 1)) <= 0) {
1068  switch (errno) {
1069  case EINTR: goto retry;
1070  case EAGAIN:
1071 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1072  case EWOULDBLOCK:
1073 #endif
1074  break;
1075  default:
1076  rb_async_bug_errno("rb_thread_wakeup_timer_thread - write", errno);
1077  }
1078  }
1079  if (TT_DEBUG) WRITE_CONST(2, "rb_thread_wakeup_timer_thread: write\n");
1080  }
1081  else {
1082  /* ignore wakeup */
1083  }
1084 }
1085 
1086 /* VM-dependent API is not available for this function */
1087 static void
1088 consume_communication_pipe(void)
1089 {
1090 #define CCP_READ_BUFF_SIZE 1024
1091  /* buffer can be shared because no one refers to them. */
1092  static char buff[CCP_READ_BUFF_SIZE];
1093  ssize_t result;
1094 
1095  retry:
1096  result = read(timer_thread_pipe[0], buff, CCP_READ_BUFF_SIZE);
1097  if (result < 0) {
1098  switch (errno) {
1099  case EINTR: goto retry;
1100  default:
1101  rb_async_bug_errno("consume_communication_pipe: read\n", errno);
1102  }
1103  }
1104 }
1105 
1106 static void
1107 close_communication_pipe(void)
1108 {
1109  if (close(timer_thread_pipe[0]) < 0) {
1110  rb_bug_errno("native_stop_timer_thread - close(ttp[0])", errno);
1111  }
1112  if (close(timer_thread_pipe[1]) < 0) {
1113  rb_bug_errno("native_stop_timer_thread - close(ttp[1])", errno);
1114  }
1115  timer_thread_pipe[0] = timer_thread_pipe[1] = -1;
1116 }
1117 
1118 /* 100ms. 10ms is too small for user level thread scheduling
1119  * on recent Linux (tested on 2.6.35)
1120  */
1121 #define TIME_QUANTUM_USEC (100 * 1000)
1122 
1123 static void *
1124 thread_timer(void *p)
1125 {
1127  int result;
1128  struct timeval timeout;
1129 
1130  if (TT_DEBUG) WRITE_CONST(2, "start timer thread\n");
1131 
1132  while (system_working > 0) {
1133  fd_set rfds;
1134  int need_polling;
1135 
1136  /* timer function */
1137  ping_signal_thread_list();
1139  need_polling = check_signal_thread_list();
1140 
1141  if (TT_DEBUG) WRITE_CONST(2, "tick\n");
1142 
1143  /* wait */
1144  FD_ZERO(&rfds);
1145  FD_SET(timer_thread_pipe[0], &rfds);
1146 
1147  if (gvl->waiting > 0 || need_polling) {
1148  timeout.tv_sec = 0;
1149  timeout.tv_usec = TIME_QUANTUM_USEC;
1150 
1151  /* polling (TIME_QUANTUM_USEC usec) */
1152  result = select(timer_thread_pipe[0] + 1, &rfds, 0, 0, &timeout);
1153  }
1154  else {
1155  /* wait (infinite) */
1156  result = select(timer_thread_pipe[0] + 1, &rfds, 0, 0, 0);
1157  }
1158 
1159  if (result == 0) {
1160  /* maybe timeout */
1161  }
1162  else if (result > 0) {
1163  consume_communication_pipe();
1164  }
1165  else { /* result < 0 */
1166  switch (errno) {
1167  case EBADF:
1168  case EINVAL:
1169  case ENOMEM: /* from Linux man */
1170  case EFAULT: /* from FreeBSD man */
1171  rb_async_bug_errno("thread_timer: select", errno);
1172  default:
1173  /* ignore */;
1174  }
1175  }
1176  }
1177 
1178  if (TT_DEBUG) WRITE_CONST(2, "finish timer thread\n");
1179  return NULL;
1180 }
1181 
1182 static void
1183 rb_thread_create_timer_thread(void)
1184 {
1186 
1187  if (!timer_thread_id) {
1188  pthread_attr_t attr;
1189  int err;
1190 
1191  pthread_attr_init(&attr);
1192 #ifdef PTHREAD_STACK_MIN
1193  if (PTHREAD_STACK_MIN < 4096 * 3) {
1194  /* Allocate the machine stack for the timer thread
1195  * at least 12KB (3 pages). FreeBSD 8.2 AMD64 causes
1196  * machine stack overflow only with PTHREAD_STACK_MIN.
1197  */
1198  pthread_attr_setstacksize(&attr,
1199  4096 * 3 + (THREAD_DEBUG ? BUFSIZ : 0));
1200  }
1201  else {
1202  pthread_attr_setstacksize(&attr,
1203  PTHREAD_STACK_MIN + (THREAD_DEBUG ? BUFSIZ : 0));
1204  }
1205 #endif
1206 
1207  /* communication pipe with timer thread and signal handler */
1208  if (timer_thread_pipe_owner_process != getpid()) {
1209  if (timer_thread_pipe[0] != -1) {
1210  /* close pipe of parent process */
1211  close_communication_pipe();
1212  }
1213 
1214  err = pipe(timer_thread_pipe);
1215  if (err != 0) {
1216  rb_bug_errno("thread_timer: Failed to create communication pipe for timer thread", errno);
1217  }
1218  rb_update_max_fd(timer_thread_pipe[0]);
1219  rb_update_max_fd(timer_thread_pipe[1]);
1220 #if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(F_SETFL)
1221  {
1222  int oflags;
1223 #if defined(O_NONBLOCK)
1224  oflags = fcntl(timer_thread_pipe[1], F_GETFL);
1225  oflags |= O_NONBLOCK;
1226  fcntl(timer_thread_pipe[1], F_SETFL, oflags);
1227 #endif /* defined(O_NONBLOCK) */
1228 #if defined(FD_CLOEXEC)
1229  oflags = fcntl(timer_thread_pipe[0], F_GETFD);
1230  fcntl(timer_thread_pipe[0], F_SETFD, oflags | FD_CLOEXEC);
1231  oflags = fcntl(timer_thread_pipe[1], F_GETFD);
1232  fcntl(timer_thread_pipe[1], F_SETFD, oflags | FD_CLOEXEC);
1233 #endif /* defined(FD_CLOEXEC) */
1234  }
1235 #endif /* defined(HAVE_FCNTL) && defined(F_GETFL) && defined(F_SETFL) */
1236 
1237  /* validate pipe on this process */
1238  timer_thread_pipe_owner_process = getpid();
1239  }
1240 
1241  /* create timer thread */
1242  if (timer_thread_id) {
1243  rb_bug("rb_thread_create_timer_thread: Timer thread was already created\n");
1244  }
1245  err = pthread_create(&timer_thread_id, &attr, thread_timer, &GET_VM()->gvl);
1246  if (err != 0) {
1247  fprintf(stderr, "[FATAL] Failed to create timer thread (errno: %d)\n", err);
1248  exit(EXIT_FAILURE);
1249  }
1250  pthread_attr_destroy(&attr);
1251  }
1252 
1253  rb_disable_interrupt(); /* only timer thread recieve signal */
1254 }
1255 
1256 static int
1257 native_stop_timer_thread(int close_anyway)
1258 {
1259  int stopped;
1260  stopped = --system_working <= 0;
1261 
1262  if (TT_DEBUG) fprintf(stderr, "stop timer thread\n");
1263  if (stopped) {
1264  /* join */
1266  native_thread_join(timer_thread_id);
1267  if (TT_DEBUG) fprintf(stderr, "joined timer thread\n");
1268  timer_thread_id = 0;
1269 
1270  /* close communication pipe */
1271  if (close_anyway) {
1272  /* TODO: Uninstall all signal handlers or mask all signals.
1273  * This pass is cleaning phase (terminate ruby process).
1274  * To avoid such race, we skip to close communication
1275  * pipe. OS will close it at process termination.
1276  * It may not good practice, but pragmatic.
1277  * We remain it is TODO.
1278  */
1279  /* close_communication_pipe(); */
1280  }
1281  }
1282  return stopped;
1283 }
1284 
1285 static void
1286 native_reset_timer_thread(void)
1287 {
1288  if (TT_DEBUG) fprintf(stderr, "reset timer thread\n");
1289 }
1290 
1291 #ifdef HAVE_SIGALTSTACK
1292 int
1293 ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr)
1294 {
1295  void *base;
1296  size_t size;
1297  const size_t water_mark = 1024 * 1024;
1299 
1300  if (th) {
1301  size = th->machine_stack_maxsize;
1302  base = (char *)th->machine_stack_start - STACK_DIR_UPPER(0, size);
1303  }
1304 #ifdef STACKADDR_AVAILABLE
1305  else if (get_stack(&base, &size) == 0) {
1306  STACK_DIR_UPPER((void)(base = (char *)base + size), (void)0);
1307  }
1308 #endif
1309  else {
1310  return 0;
1311  }
1312  size /= 5;
1313  if (size > water_mark) size = water_mark;
1314  if (IS_STACK_DIR_UPPER()) {
1315  if (size > ~(size_t)base+1) size = ~(size_t)base+1;
1316  if (addr > base && addr <= (void *)((char *)base + size)) return 1;
1317  }
1318  else {
1319  if (size > (size_t)base) size = (size_t)base;
1320  if (addr > (void *)((char *)base - size) && addr <= base) return 1;
1321  }
1322  return 0;
1323 }
1324 #endif
1325 
1326 int
1327 rb_reserved_fd_p(int fd)
1328 {
1329  if (fd == timer_thread_pipe[0] ||
1330  fd == timer_thread_pipe[1]) {
1331  return 1;
1332  }
1333  else {
1334  return 0;
1335  }
1336 }
1337 
1338 #endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
1339