0001-interrupt-flag.patch

Motohiro KOSAKI, 05/23/2011 09:46 AM

Download (7.53 KB)

View differences:

atomic.h
1
#ifndef RUBY_ATOMIC_H
2
#define RUBY_ATOMIC_H
3

  
4
#ifdef _WIN32
5
#pragma intrinsic(_InterlockedOr)
6
typedef LONG rb_atomic_t;
7

  
8
# define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
9
# define ATOMIC_INC(var) InterlockedIncrement(&(var))
10
# define ATOMIC_DEC(var) InterlockedDecrement(&(var))
11
# define ATOMIC_OR(var, val) _InterlockedOr(&(var), (val))
12
# define ATOMIC_EXCHANGE(var, val) InterlockedExchange(&(var), (val))
13

  
14
#elif defined HAVE_GCC_ATOMIC_BUILTINS
15
/* @shyouhei hack to support atomic operations in case of gcc. Gcc
16
 * has its own pseudo-insns to support them.  See info, or
17
 * http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html */
18

  
19
typedef unsigned int rb_atomic_t; /* Anything OK */
20
# define ATOMIC_SET(var, val)  __sync_lock_test_and_set(&(var), (val))
21
# define ATOMIC_INC(var) __sync_fetch_and_add(&(var), 1)
22
# define ATOMIC_DEC(var) __sync_fetch_and_sub(&(var), 1)
23
# define ATOMIC_OR(var, val) __sync_or_and_fetch(&(var), (val))
24
# define ATOMIC_EXCHANGE(var, val) __sync_lock_test_and_set(&(var), (val))
25

  
26
#else
27
typedef int rb_atomic_t;
28
extern rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val);
29

  
30
# define ATOMIC_SET(var, val) ((var) = (val))
31
# define ATOMIC_INC(var) (++(var))
32
# define ATOMIC_DEC(var) (--(var))
33
# define ATOMIC_OR(var, val) ((var) |= (val))
34
# define ATOMIC_EXCHANGE(var, val) ruby_atomic_exchange(&(var), (val))
35
#endif
36

  
37
#endif /* RUBY_ATOMIC_H */
common.mk
614 614
gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
615 615
  {$(VPATH)}regex.h $(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
616 616
  {$(VPATH)}gc.h {$(VPATH)}io.h {$(VPATH)}eval_intern.h {$(VPATH)}util.h \
617
  {$(VPATH)}debug.h
617
  {$(VPATH)}debug.h {$(VPATH)}atomic.h
618 618
hash.$(OBJEXT): {$(VPATH)}hash.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h
619 619
inits.$(OBJEXT): {$(VPATH)}inits.c $(RUBY_H_INCLUDES)
620 620
io.$(OBJEXT): {$(VPATH)}io.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
......
669 669
safe.$(OBJEXT): {$(VPATH)}safe.c $(RUBY_H_INCLUDES) \
670 670
  $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h
671 671
signal.$(OBJEXT): {$(VPATH)}signal.c $(RUBY_H_INCLUDES) \
672
  $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h
672
  $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h {$(VPATH)}atomic.h
673 673
sprintf.$(OBJEXT): {$(VPATH)}sprintf.c $(RUBY_H_INCLUDES) {$(VPATH)}re.h \
674 674
  {$(VPATH)}regex.h {$(VPATH)}vsnprintf.c $(ENCODING_H_INCLUDES)
675 675
st.$(OBJEXT): {$(VPATH)}st.c {$(VPATH)}config.h {$(VPATH)}defines.h \
......
682 682
struct.$(OBJEXT): {$(VPATH)}struct.c $(RUBY_H_INCLUDES)
683 683
thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \
684 684
  $(RUBY_H_INCLUDES) {$(VPATH)}gc.h $(VM_CORE_H_INCLUDES) \
685
  {$(VPATH)}debug.h {$(VPATH)}thread_$(THREAD_MODEL).c
685
  {$(VPATH)}debug.h {$(VPATH)}thread_$(THREAD_MODEL).c {$(VPATH)}atomic.h
686 686
transcode.$(OBJEXT): {$(VPATH)}transcode.c $(RUBY_H_INCLUDES) \
687 687
  $(ENCODING_H_INCLUDES) {$(VPATH)}transcode_data.h
688 688
cont.$(OBJEXT): {$(VPATH)}cont.c $(RUBY_H_INCLUDES) \
689 689
  $(VM_CORE_H_INCLUDES) {$(VPATH)}gc.h {$(VPATH)}eval_intern.h \
690
  {$(VPATH)}debug.h
690
  {$(VPATH)}debug.h {$(VPATH)}atomic.h
691 691
time.$(OBJEXT): {$(VPATH)}time.c $(RUBY_H_INCLUDES) \
692 692
  $(ENCODING_H_INCLUDES) {$(VPATH)}timev.h
693 693
util.$(OBJEXT): {$(VPATH)}util.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h
signal.c
16 16
#include <signal.h>
17 17
#include <stdio.h>
18 18
#include <errno.h>
19
#include "atomic.h"
19 20

  
20
#ifdef _WIN32
21
typedef LONG rb_atomic_t;
22

  
23
# define ATOMIC_TEST(var) InterlockedExchange(&(var), 0)
24
# define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
25
# define ATOMIC_INC(var) InterlockedIncrement(&(var))
26
# define ATOMIC_DEC(var) InterlockedDecrement(&(var))
27

  
28
#elif defined HAVE_GCC_ATOMIC_BUILTINS
29
/* @shyouhei hack to support atomic operations in case of gcc. Gcc
30
 * has its own pseudo-insns to support them.  See info, or
31
 * http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html */
32

  
33
typedef unsigned int rb_atomic_t; /* Anything OK */
34
# define ATOMIC_TEST(var) __sync_lock_test_and_set(&(var), 0)
35
# define ATOMIC_SET(var, val)  __sync_lock_test_and_set(&(var), (val))
36
# define ATOMIC_INC(var) __sync_fetch_and_add(&(var), 1)
37
# define ATOMIC_DEC(var) __sync_fetch_and_sub(&(var), 1)
38

  
39
#else
40
typedef int rb_atomic_t;
41

  
42
# define ATOMIC_TEST(var) ((var) ? ((var) = 0, 1) : 0)
43
# define ATOMIC_SET(var, val) ((var) = (val))
44
# define ATOMIC_INC(var) (++(var))
45
# define ATOMIC_DEC(var) (--(var))
21
#if !defined(_WIN32) && !defined(HAVE_GCC_ATOMIC_BUILTINS)
22
rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val)
23
{
24
    rb_atomic_t old = *ptr;
25
    *ptr = val;
26
    return old;
27
}
46 28
#endif
47 29

  
48 30
#if defined(__BEOS__) || defined(__HAIKU__)
thread.c
1289 1289
static void
1290 1290
rb_threadptr_execute_interrupts_rec(rb_thread_t *th, int sched_depth)
1291 1291
{
1292
    rb_atomic_t interrupt;
1293

  
1292 1294
    if (GET_VM()->main_thread == th) {
1293 1295
	while (rb_signal_buff_size() && !th->exec_signal) native_thread_yield();
1294 1296
    }
1295 1297

  
1296 1298
    if (th->raised_flag) return;
1297 1299

  
1298
    while (th->interrupt_flag) {
1300
    while ((interrupt = ATOMIC_EXCHANGE(th->interrupt_flag, 0)) != 0) {
1299 1301
	enum rb_thread_status status = th->status;
1300
	int timer_interrupt = th->interrupt_flag & 0x01;
1301
	int finalizer_interrupt = th->interrupt_flag & 0x04;
1302
	int timer_interrupt = interrupt & 0x01;
1303
	int finalizer_interrupt = interrupt & 0x04;
1302 1304

  
1303 1305
	th->status = THREAD_RUNNABLE;
1304
	th->interrupt_flag = 0;
1305 1306

  
1306 1307
	/* signal handling */
1307 1308
	if (th->exec_signal) {
vm_core.h
22 22
#include "vm_opts.h"
23 23
#include "id.h"
24 24
#include "method.h"
25
#include "atomic.h"
25 26

  
26 27
#if   defined(_WIN32)
27 28
#include "thread_win32.h"
......
430 431
    VALUE thrown_errinfo;
431 432
    int exec_signal;
432 433

  
433
    int interrupt_flag;
434
    rb_atomic_t interrupt_flag;
434 435
    rb_thread_lock_t interrupt_lock;
435 436
    struct rb_unblock_callback unblock;
436 437
    VALUE locking_mutex;
......
687 688
#error "unsupported thread model"
688 689
#endif
689 690

  
690
#define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02)
691
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01)
692
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ((th)->interrupt_flag |= 0x04)
691
#define RUBY_VM_SET_TIMER_INTERRUPT(th)		ATOMIC_OR((th)->interrupt_flag, 0x01)
692
#define RUBY_VM_SET_INTERRUPT(th)		ATOMIC_OR((th)->interrupt_flag, 0x02)
693
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th)	ATOMIC_OR((th)->interrupt_flag, 0x04)
693 694
#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)
694 695

  
695 696
int rb_signal_buff_size(void);
696
-