[Q] thread->interrupt_flag が適切に排他制御されていないように見える

kosaki$B$G$9(B

Ruby VM internal
$B$K>$7$$J}!9$K<ALd$G$9!#8=:_!"(Bthread->interrupt_flag$B$O$I$&$d$C$FGSB>@)8f$5$l$k%G%6%$%s$K$J$C$F$$$^$9$G$7$g$&$+!)(B

$B$H$$$$$^$9$N$O(B

$B#1!%%S%C%H%^%9%/$H$7$F;H$C$F$$$k$N$GGSB>@)8f$7$J$$$H%U%i%0$,%m%9%H$7$F$($i$$;v$K$J$j$=$&(B

#define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02)
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01)
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ((th)->interrupt_flag |=
0x04)
#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)

$B#2!%3d$j9~$_=hM}$G%U%i%0$r%j%;%C%H$9$k2U=j$G$O(BGVL$B$7$+$H$C$F$J$$(B

static void
rb_threadptr_execute_interrupts_rec(rb_thread_t *th, int sched_depth)
{
(snip)

while (th->interrupt_flag) {
    enum rb_thread_status status = th->status;
    int timer_interrupt = th->interrupt_flag & 0x01;
    int finalizer_interrupt = th->interrupt_flag & 0x04;
    th->interrupt_flag = 0;

$B#3!%%?%$%^!<%9%l%C%I$O(BTIMER_INTERRUPT
bit$B$rN)$F$k;~$K!"(Btimer_thread_lock $B$7$+<h$C$F$J$$(B

static void
timer_thread_function(void *arg)
{
rb_vm_t vm = GET_VM(); / TODO: fix me for Multi-VM */

/* for time slice */
RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread);

$B#4!%(Bthread.c $B$G$O(B RUBY_VM_SET_INTERRUPT$B8F$V$H$-$K(B
thread->interrupt_lock $B<h$k$,(B
cont.c $B$G$O<h$i$J$$(B

$B#5!%(Bgc.c$B$b(B RUBY_VM_SET_FINALIZER_INTERRUPT
$B8F$V$H$-$KFC$K%m%C%/$r<h$i$J$$(B

$B$H$$$&!"$J$+$J$+@09g@-$,$H$l$F$$$J$5$=$&$J>u67$K$J$C$F$$$=$&$@$+$i$G$9!#$J$K$+8+Mn$H$7$F$$$^$9$G$7$g$&$+!)(B

$B!t(B $B0l=V!"$9$Y$F(B
interrupt_lock$B$G<i$k$N$,$$$$$N$+$J!#$H;W$C$?$N$G$9$,$h$/9M$($?$i(B
native_mutex_lock()$B4X?t$,(B
$B!t(B thread.c $B0J30$+$i$O8F$Y$J$$$N$G$7$?!#(B

$B!!$5$5$@$G$9!%(B

(2011/05/09 6:19), SASADA Koichi wrote:

$B!!(Btimer_thread $B$N(B flag $B$O!$<B$O(B lost
$B$7$F$b$"$s$^$jLdBj$J$$!J$A$g$C$H%9(B
$B%1%8%e!<%j%s%0$,CY$l$k$@$1!K$C$F$s$G8=:_$N;EMM$K$7$F$$$k!J%m%C%/$r<h$i$J(B
$B$$!K$N$G$9$,!$B>$,@_Dj$7$?$b$N$r(B reset $B$7$F$7$^$&2DG=@-$,$"$k!J6qBNE*$K(B
$B$O(B signal $B2s$j$H%P%C%F%#%s%0$9$k!K!$$H$$$N$O$^$:$$$+$b$7$l$^$;$s$M!%$I$&(B
$B$7$h!%(B

$B!!(B(1) $BMn$H$7$F$b$^$!=d$j=d$C$F2?$H$+$J$k7O$H!$(B(2)
$BMn$H$7$A$c$$$1$J$$7O$r(B
$BJ,$1$^$9$+$M$(!%(B

$B!!:#5$$E$-$^$7$?$,!$7k6I!V$A$g$C$H%7%0%J%kG[Aw$,CY$l$k!W$@$1$J$N$G!$A4It(B
(1)
$B$KJ,N`$7$F$b$$$$$h$&$J5$$,$7$F$-$^$7$?!%$J$N$G!$8=>u$O!VBg$-$JLdBj$O(B
$B5/$-$J$$$N$G$O$J$$$+!WGI!%(B

$B!!$5$5$@$G$9!%(B

(2011/05/08 20:23), KOSAKI Motohiro wrote:

Ruby VM internal

$B$K>$7$$J}!9$K<ALd$G$9!#8=:_!"(Bthread->interrupt_flag$B$O$I$&$d$C$FGSB>@)8f$5$l$k%G%6%$%s$K$J$C$F$$$^$9$G$7$g$&$+!)(B

$B!!>$7$$$+$I$&$+$O5?Ld$G$9$,!$(Bth->interrupt_flag $B$r:n$j$^$7$?!%(B

$B!!4pK\E*$K!$(Bth->interrupt_flag $B$rO.$k?M$O(B GVL
$B<h$C$F$k$N$G!$GSB>@)8f=PMh(B
$B$F$k$H;W$C$F$?$s$@$1$I!$$^$:$$!)(B

$B!!(BGVL $B<h$C$F$J$$$N$O(B timer_thread $B$@$1$I!$(Btimer_thread
$B$,@_Dj$9$k;~(B
$B$K!$(Bor
$B$r@_Dj$7$h$&$H$7$F!$$=$3$G$^$:$$$3$H$,5/$3$k2DG=@-$,$"$k$N$+(B
$B$J!%(Btimer_thread_lock
$B$C$F$N$b!$@N$O<h$C$F$$$J$+$C$?$h$&$J!J3P$($F$$$J$$!K!%(B

$B!!(Btimer_thread $B$N(B flag $B$O!$<B$O(B lost
$B$7$F$b$"$s$^$jLdBj$J$$!J$A$g$C$H%9(B
$B%1%8%e!<%j%s%0$,CY$l$k$@$1!K$C$F$s$G8=:_$N;EMM$K$7$F$$$k!J%m%C%/$r<h$i$J(B
$B$$!K$N$G$9$,!$B>$,@_Dj$7$?$b$N$r(B reset
$B$7$F$7$^$&2DG=@-$,$"$k!J6qBNE*$K(B
$B$O(B signal
$B2s$j$H%P%C%F%#%s%0$9$k!K!$$H$$$N$O$^$:$$$+$b$7$l$^$;$s$M!%$I$&(B
$B$7$h!%(B

$B!!(B(1) $BMn$H$7$F$b$^$!=d$j=d$C$F2?$H$+$J$k7O$H!$(B(2)
$BMn$H$7$A$c$$$1$J$$7O$r(B
$BJ,$1$^$9$+$M$(!%(B

(1)
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01)
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ((th)->interrupt_flag |=
0x04)

(2)
#define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02)

$B!!$5$5$@$G$9!%(B

(2011/05/09 11:02), KOSAKI Motohiro wrote:

$B$3$A$i$OM}2r$,DI$$$D$+$J$+$C$?$N$GJdB-$r$*4j$$$7$FNI$$$G$9$+!)(B
RUBY_VM_SET_INTERRUPT()
$B$,%m%9%H$7$?$H$-$K!"8e$+$i%U%i%0$rN)$FD>$7$F$/$l$k?M$O(B
$B$I$J$?$G$7$g$&$+!)(B

$B!!$($($H!$(Bset_interrupt
$B$O%m%9%H$7$F$b!$Dj4|E*$K%9%1%8%e!<%i$,%7%0%J%k$,(B
$BFO$$$F$$$k$+%A%’%C%/$7$F$$$k$N$GBg>fIW$@$H;W$$$^$7$?!%(B

        }, 0, 0);

$B$3$N>l9g!"(Binterrupt_flag $B$,(B0 $B$@$H(B
Ruby$B$N@$3&$KLa$C$F$-$F$/$l$J$5$=$&$G$9$,!"(B
$BBg>fIW$G$7$g$&$+!)(B

$B!!$?$@!$$3$NNc$r8+$F$$$k$HBg>fIW$8$c$J$$$G$9$M!%$J$K$d$C$F$s$@!$$3$l!%(B

$B$^$?!"%?%$%^!<%9%l%C%I$,Dj4|E*$K5/$3$7$F$/$l$k$N$O%a%$%s%9%l%C%I$@$1$J$N$G!"(B
$B%5%V%9%l%C%I$O(BRUBY_VM_CHECK_INTS() $B$,(Bfalse$B$rJV$7B3$1$k8B$j!"(B
rb_threadptr_execute_interrupts_rec() $B$^$GMh$J$$$N$G$O$J$$$N$+$H$$$&5?OG$,(B
$B$"$k$N$G$9$,!"$I$N%k!<%H$GC4J]$5$l$F$^$9$G$7$g$&$+!)(B

$B!!$"$l!$$=$&$@$C$?$C$1!d%a%$%s%9%l%C%I$@$1!%$=$s$J$3$H$J$$$h$&$J!%(B

$B!!$5$5$@$G$9!%(B

(2011/05/08 20:23), KOSAKI Motohiro wrote:

Ruby VM internal

$B$K>$7$$J}!9$K<ALd$G$9!#8=:_!"(Bthread->interrupt_flag$B$O$I$&$d$C$FGSB>@)8f$5$l$k%G%6%$%s$K$J$C$F$$$^$9$G$7$g$&$+!)(B

$B!!>$7$$$+$I$&$+$O5?Ld$G$9$,!$(Bth->interrupt_flag $B$r:n$j$^$7$?!%(B

$B$=$&$$$&$N$r>$7$$?M$H$$$&$N$G$9(B :slight_smile:

$B!!4pK\E*$K!$(Bth->interrupt_flag $B$rO.$k?M$O(B GVL
$B<h$C$F$k$N$G!$GSB>@)8f=PMh(B
$B$F$k$H;W$C$F$?$s$@$1$I!$$^$:$$!)(B

timer
thread$B$5$s$,$H$C$F$J$/$F!"H`$K$O(BGVL$B$r<h$k$H$$$&A*Br;h$O$J$5$=$&$@!#(B
$B$H$$$&$N$,(B first impression $B$G$7$?!#(B

$B!!(BGVL $B<h$C$F$J$$$N$O(B timer_thread $B$@$1$I!$(Btimer_thread
$B$,@_Dj$9$k;~(B
$B$K!$(Bor $B$r@_Dj$7$h$&$H$7$F!$$=$3$G$^$:$$$3$H$,5/$3$k2DG=@-$,$"$k$N$+(B
$B$J!%(Btimer_thread_lock
$B$C$F$N$b!$@N$O<h$C$F$$$J$+$C$?$h$&$J!J3P$($F$$$J$$!K!%(B

$B!!(Btimer_thread $B$N(B flag $B$O!$<B$O(B lost
$B$7$F$b$"$s$^$jLdBj$J$$!J$A$g$C$H%9(B
$B%1%8%e!<%j%s%0$,CY$l$k$@$1!K$C$F$s$G8=:_$N;EMM$K$7$F$$$k!J%m%C%/$r<h$i$J(B
$B$$!K$N$G$9$,!$B>$,@_Dj$7$?$b$N$r(B reset $B$7$F$7$^$&2DG=@-$,$"$k!J6qBNE*$K(B
$B$O(B signal $B2s$j$H%P%C%F%#%s%0$9$k!K!$$H$$$N$O$^$:$$$+$b$7$l$^$;$s$M!%$I$&(B
$B$7$h!%(B

$B$O$$!"$o$?$7$,?4G[$7$F$$$?$N$O8e<T$NJ}$G$9!#(B

$B!!(B(1) $BMn$H$7$F$b$^$!=d$j=d$C$F2?$H$+$J$k7O$H!$(B(2)
$BMn$H$7$A$c$$$1$J$$7O$r(B
$BJ,$1$^$9$+$M$(!%(B

(1)
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01)
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ((th)->interrupt_flag |= 0x04)

(2)
#define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02)

$B$o$?$7$O(B timer interrupt
$B$@$1J,$1$k$N$b!"$"$j$@$H;W$$$^$7$?$,$I$&$G$7$g$&$+!#(B
$BM}M3$O(B

$B#1!K%?%$%^!<%9%l%C%I$@$1$,(BGVL$B$r;}$D$3$H$,L5M}(B
$B#2!K%?%$%^!<3d$j9~$_$@$1$O!"$I$s$J>u67$G$b%m%9%H$7$F$bBg;v8N$O5/$-$J$$(B

$B$N#2$D$NFC<l@-$,$"$k$+$i$G$9!#9%ET9g$J$3$H$K!"%?%$%^!<%9%l%C%I$N(B
cond_timedwait
$B$,(Btimer_lock$B$r0E$K(Brelease$B$7!"$=$3$G(Brelease
barrier$B$,D%$i$l$k$N$G!"(B

$B!!:#5$$E$-$^$7$?$,!$7k6I!V$A$g$C$H%7%0%J%kG[Aw$,CY$l$k!W$@$1$J$N$G!$A4It(B
(1) $B$KJ,N`$7$F$b$$$$$h$&$J5$$,$7$F$-$^$7$?!%$J$N$G!$8=>u$O!VBg$-$JLdBj$O(B
$B5/$-$J$$$N$G$O$J$$$+!WGI!%(B

$B$3$A$i$OM}2r$,DI$$$D$+$J$+$C$?$N$GJdB-$r$*4j$$$7$FNI$$$G$9$+!)(B
RUBY_VM_SET_INTERRUPT()
$B$,%m%9%H$7$?$H$-$K!"8e$+$i%U%i%0$rN)$FD>$7$F$/$l$k?M$O(B
$B$I$J$?$G$7$g$&$+!)(B

$B$?$H$($P!"(B thread.c#do_select$B$K$O0J2<$N%k!<%W$,$"$j$^$9$,(B

#if defined(CYGWIN) || defined(_WIN32)
(snip)
BLOCKING_REGION({
do {
result = rb_fd_select(n, read, write, except, wait);
(snip)
}
} while (__th->interrupt_flag == 0);
}, 0, 0);

$B$3$N>l9g!"(Binterrupt_flag $B$,(B0 $B$@$H(B
Ruby$B$N@$3&$KLa$C$F$-$F$/$l$J$5$=$&$G$9$,!"(B
$BBg>fIW$G$7$g$&$+!)(B
$B$^$?!"%?%$%^!<%9%l%C%I$,Dj4|E*$K5/$3$7$F$/$l$k$N$O%a%$%s%9%l%C%I$@$1$J$N$G!"(B
$B%5%V%9%l%C%I$O(BRUBY_VM_CHECK_INTS() $B$,(Bfalse$B$rJV$7B3$1$k8B$j!"(B
rb_threadptr_execute_interrupts_rec()
$B$^$GMh$J$$$N$G$O$J$$$N$+$H$$$&5?OG$,(B
$B$"$k$N$G$9$,!"$I$N%k!<%H$GC4J]$5$l$F$^$9$G$7$g$&$+!)(B

        }, 0, 0);

$B$3$N>l9g!"(Binterrupt_flag $B$,(B0 $B$@$H(B
Ruby$B$N@$3&$KLa$C$F$-$F$/$l$J$5$=$&$G$9$,!"(B

$BBg>fIW$G$7$g$&$+!)(B

$B!!$?$@!$$3$NNc$r8+$F$$$k$HBg>fIW$8$c$J$$$G$9$M!%$J$K$d$C$F$s$@!$$3$l!%(B

WIN32$B$O(B ubf_select
$B$,$J$$$+$i!"?2$kB&$,(B100ms$B$K0l2s5/$-$F$-$F%]!<%j%s%0%A%’%C%/(B
$B$9$k$s$G$9$h!#$C$F!":n<T$N2DG=@-$,9b$$?M$K$7$?$j4i$G2r@b$9$k$N$C$F$9$4$/(B
$B$+$C$3$o$k$$!#(B

$B$?$@!"$3$N%m%8%C%/A4BN$r(Bwin32.c
$B$K0\F0$5$;$?$$!"$H$+!"%]!<%j%s%0$+$C$3$o$k$$$+$i(B
win32.c$B$G(Bselect$B$G?2$k$s$8$c$J$/!"(BWaitForMultipleObject()$B$G?2$F$*$$$F(B
win32$BMQ(B
ubf_select$B$G(BSetEvent$B$7$F5/$3$7$F$"$2$k$H$$$$$+$b!"$H$+$=$&$$$&C&@~5DO@$O(B
$B$"$k$+$b!#(B

$B$^$?!"%?%$%^!<%9%l%C%I$,Dj4|E*$K5/$3$7$F$/$l$k$N$O%a%$%s%9%l%C%I$@$1$J$N$G!"(B

$B%5%V%9%l%C%I$O(BRUBY_VM_CHECK_INTS() $B$,(Bfalse$B$rJV$7B3$1$k8B$j!"(B
rb_threadptr_execute_interrupts_rec() $B$^$GMh$J$$$N$G$O$J$$$N$+$H$$$&5?OG$,(B
$B$"$k$N$G$9$,!"$I$N%k!<%H$GC4J]$5$l$F$^$9$G$7$g$&$+!)(B

$B!!$"$l!$$=$&$@$C$?$C$1!d%a%$%s%9%l%C%I$@$1!%$=$s$J$3$H$J$$$h$&$J!%(B

$B$$$d!"$"$N!#JdB-$r$*4j$$$7$FNI$$$G$9$+!#$NJV;v$,$3$l$@$H(BESP$BG=NO$r(B
$BMW5a$5$l$F$k46$8$G$9!#%%9%1%F(B

static void
timer_thread_function(void *arg)
{
rb_vm_t vm = GET_VM(); / TODO: fix me for Multi-VM */

  /* for time slice */
  RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread);

  /* check signal */
  rb_threadptr_check_signal(vm->main_thread);

void
rb_threadptr_check_signal(rb_thread_t *mth)
{
int sig;

  /* mth must be main_thread */

  if (!mth->exec_signal && (sig = rb_get_next_signal()) > 0) {
      enum rb_thread_status prev_status = mth->status;
      thread_debug("main_thread: %s, sig: %d\n",
                   thread_status_name(prev_status), sig);
      mth->exec_signal = sig;
      if (mth->status != THREAD_KILLED) mth->status = 

THREAD_RUNNABLE;
rb_threadptr_interrupt(mth);
mth->status = prev_status;
}
}

$B$J$N$G!"%a%$%s%9%l%C%I$,Dj4|E*$K(B
rb_threadptr_interrupt()$B8F$P$l$F$k$N$O(B
$B<+L@$J$s$G$9$,!"B>$N%9%l%C%I$O$I$3$+$i$G$7$g$&$+!)(B

$B!!$5$5$@$G$9!%(B

(2011/05/09 13:11), KOSAKI Motohiro wrote:

$B$N$h$&$K$J$C$F$$$k$+$i!"(B(1)$B$H(B(2)$B$O(BRUBY_VM_INTERRUPTED()$B$r;H$C$F$$$J$$$N$G%;!<%U!#(B

(3)$B$O<!$N(Bgc$B$N;~$K$b$&0l2s%U%i%0$,N)$D$+$i%;!<%U$H$$$&$3$H$G$9$M!)(B

$B!!(BYES$B!%$=$&$$$&0U?^$G$7$?!%(B

$B$H$$$&$3$H$O4m$J$$$N$O(B RUBY_VM_SET_INTERRUPT()
$B$,%m%9%H$7$?$H$-$K!"%?%$%`%"%&%H$J$7$N(B
$B%9%j!<%W$r$7$F$$$F!"(Bvm->running_thread
$B$K$J$i$J$$$+$i!"%?%$%^!<%9%l%C%I$K(B
$B5/$3$7$FLc$($J$$%1!<%9$G$7$g$&$+!)(B

$B!!$A$g$C$H$=$NNc$,6qBNE*$K$Q$C$H$o$+$i$J$$$N$G$9$,!$(Bth->interrupt_flag
$B$r4F;k$7$F$$$k!$A0$N%a!<%k$G=P$7$F$b$i$C$?Nc$O4m81$=$&$G$9!%4m81$=$&!$$H(B
$B;W$&$N$@$1$I!$K\Ev$K4m81$J$N$+$O<B$O<+?H$,L5$$$N$G$9$,!%(B

$B<+8J2r7h$7$^$7$?(B

$B!!$"$l!$$=$&$@$C$?$C$1!d%a%$%s%9%l%C%I$@$1!%$=$s$J$3$H$J$$$h$&$J!%(B

$B$3$l$O$?$@$N$&$C$+$j$J$N$G!"$*$$$H$/$H$7$F(B
$B!J(BRUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread)
$B$J$N$G<+L@$@$C$?!K(B

  if (!mth->exec_signal && (sig = rb_get_next_signal()) > 0) {

$B$J$N$G!"%a%$%s%9%l%C%I$,Dj4|E*$K(B rb_threadptr_interrupt()$B8F$P$l$F$k$N$O(B
$B<+L@$J$s$G$9$,!"B>$N%9%l%C%I$O$I$3$+$i$G$7$g$&$+!)(B

$B%?%$%^!<%9%l%C%I$,(Brunning thread
$B$KG[Aw$5$l$F!"(Brb_threadptr_execute_interrupts_rec()$B$G(B

    /* signal handling */
    if (th->exec_signal) {
(1)
    }

    /* exception from another thread */
    if (th->thrown_errinfo) {
(2)

}

    if (finalizer_interrupt) {
(3)
        rb_gc_finalize_deferred();
    }

$B$N$h$&$K$J$C$F$$$k$+$i!"(B(1)$B$H(B(2)$B$O(BRUBY_VM_INTERRUPTED()$B$r;H$C$F$$$J$$$N$G%;!<%U!#(B
(3)$B$O<!$N(Bgc$B$N;~$K$b$&0l2s%U%i%0$,N)$D$+$i%;!<%U$H$$$&$3$H$G$9$M!)(B

$B$H$$$&$3$H$O4m$J$$$N$O(B RUBY_VM_SET_INTERRUPT()
$B$,%m%9%H$7$?$H$-$K!"%?%$%`%"%&%H$J$7$N(B
$B%9%j!<%W$r$7$F$$$F!"(Bvm->running_thread
$B$K$J$i$J$$$+$i!"%?%$%^!<%9%l%C%I$K(B
$B5/$3$7$FLc$($J$$%1!<%9$G$7$g$&$+!)(B

$B$H$$$&$3$H$O4m$J$$$N$O(B RUBY_VM_SET_INTERRUPT()
$B$,%m%9%H$7$?$H$-$K!"%?%$%`%"%&%H$J$7$N(B

$B%9%j!<%W$r$7$F$$$F!"(Bvm->running_thread
$B$K$J$i$J$$$+$i!"%?%$%^!<%9%l%C%I$K(B

$B5/$3$7$FLc$($J$$%1!<%9$G$7$g$&$+!)(B

$B!!$A$g$C$H$=$NNc$,6qBNE*$K$Q$C$H$o$+$i$J$$$N$G$9$,!$(Bth->interrupt_flag
$B$r4F;k$7$F$$$k!$A0$N%a!<%k$G=P$7$F$b$i$C$?Nc$O4m81$=$&$G$9!%4m81$=$&!$$H(B
$B;W$&$N$@$1$I!$K\Ev$K4m81$J$N$+$O<B$O<+?H$,L5$$$N$G$9$,!%(B

$B$8$c$"%Q%C%A$D$/$k$+$i!"%Q%C%A$,1x$/$J$+$C$?$i(Baccept$B$7$F$/$@$5$$$h!#4m81$N(B
$B$"$j$J$7$r$"$l$3$lG:$`$h$j$b7z@_E*$G$9!#$-$C$H(B

$B$H$$$&$3$H$O4m$J$$$N$O(B RUBY_VM_SET_INTERRUPT()
$B$,%m%9%H$7$?$H$-$K!"%?%$%`%"%&%H$J$7$N(B

$B%9%j!<%W$r$7$F$$$F!"(Bvm->running_thread
$B$K$J$i$J$$$+$i!"%?%$%^!<%9%l%C%I$K(B

$B5/$3$7$FLc$($J$$%1!<%9$G$7$g$&$+!)(B

$B!!(B $B$A$g$C$H$=$NNc$,6qBNE*$K$Q$C$H$o$+$i$J$$$N$G$9$,!$(Bth->interrupt_flag
$B$r4F;k$7$F$$$k!$A0$N%a!<%k$G=P$7$F$b$i$C$?Nc$O4m81$=$&$G$9!%4m81$=$&!$$H(B
$B;W$&$N$@$1$I!$K\Ev$K4m81$J$N$+$O<B$O<+?H$,L5$$$N$G$9$,!%(B

$B$8$c$"%Q%C%A$D$/$k$+$i!"%Q%C%A$,1x$/$J$+$C$?$i(Baccept$B$7$F$/$@$5$$$h!#4m81$N(B

$B$"$j$J$7$r$"$l$3$lG:$`$h$j$b7z@_E*$G$9!#$-$C$H(B

$B$7$P$i$/9M$($?$H$3$m!"=q$-9~$_B&$G(B atomic ops
$B;H$($P==J,$H$$$&5$$,$7$F$-$^$7$?!#(B
$B$=$l$J$i!"(Breader$B$OB.EYDc2<#0$J$N$G%Q%U%)!<%^%s%9LdBj$,$*$3$j$h$&$,$J$$$7!#(B
Linux$B$G$7$+%F%9%H$7$F$^$;$s$,!"$3$s$J$b$s$G$I$&$G$7$g$&$+!)(B

$B$^$D$b$H(B $B$f$-$R$m$G$9(B

In message “Re: [ruby-dev:43527] Re: [Q] thread->interrupt_flag
$B$,E,@Z$KGSB>@)8f$5$l$F$$$J$$$h$&$K8+$($k(B”
on Wed, 11 May 2011 22:52:36 +0900, KOSAKI Motohiro
[email protected] writes:

|$B$7$P$i$/9M$($?$H$3$m!“=q$-9~$_B&$G(B atomic ops
$B;H$($P==J,$H$$$&5$$,$7$F$-$^$7$?!#(B
|$B$=$l$J$i!”(Breader$B$OB.EYDc2<#0$J$N$G%Q%U%)!<%^%s%9LdBj$,$*$3$j$h$&$,$J$$$7!#(B
|Linux$B$G$7$+%F%9%H$7$F$^$;$s$,!"$3$s$J$b$s$G$I$&$G$7$g$&$+!)(B

$B%3%_%C%H$7$F;n$7$^$7$g$&$h!#(Bnon-Linux$B$NJ}!"(Btrunk$B$r%F%9%H$7$F(B
$B$/$@$5$$$^$;$s$+!)(B

$B!!$5$5$@$G$9!%(B

(2011/05/11 22:52), KOSAKI Motohiro wrote:

$B$7$P$i$/9M$($?$H$3$m!"=q$-9~$_B&$G(B atomic ops
$B;H$($P==J,$H$$$&5$$,$7$F$-$^$7$?!#(B

$B$=$l$J$i!"(Breader$B$OB.EYDc2<#0$J$N$G%Q%U%)!<%^%s%9LdBj$,$*$3$j$h$&$,$J$$$7!#(B

Linux$B$G$7$+%F%9%H$7$F$^$;$s$,!"$3$s$J$b$s$G$I$&$G$7$g$&$+!)(B

$B!!(Batomic operation
$B$,==J,$K2>Dj$G$-$k$N$J$i!$$3$l$G$b$$$$$h$&$J5$$,$7$^$9!%(B

$B!!$A$J$_$K!$(Brb_atomic_t $B$O(B int
$B$G$$$$$N$+$7$i!$$H$A$g$C$H;W$C$?!J$$$d!$(B
$B$3$NJU$N>o<1$rCN$i$J$$$b$N$G!%(Brb_atomic_int_t
$B$8$c$J$$$s$@$J!$$C$F!K!%(B

$B!!<+J,$,;}$C$F$$$kBP0F$O!$(Binterrupt_flag
$B$O$"$/$^$G%R%s%H$H$7$F07$$!$2?(B
$B$+ITET9g$,$"$C$F$b8e$G%j%+%P!<$G$-$k>pJs$K$7$F$*$/!%>C$7$A$c9T$1$J$$>pJs(B
$B!J%7%0%J%k$NE~C#H=Dj$H$+!K$O!$JL$KMQ0U$7$F!$$=$l$r;2>H$7$J$/$F$O$$$1$J$$(B
$B%7%A%e%(!<%7%g%s!J(BGVL
$B$N30$G%7%0%J%k4F;k$H$+!K$O!$$=$C$A$b;2>H$9$k!$$H$$(B
$B$&$N$,$$$$$s$G$J$$$+$H;W$C$F$$$^$7$?$,!$J#;($G$9!%>.:j$5$s$NDs0F$O!$$=$N(B
$BE@$G(B interrupt_flag
$B$r%-%C%A%j$+$C$A$j4IM}$9$k!$$H$$$&0UL#$G$o$+$j$d$9$$(B
$B$H;W$$$^$9(B

$B$7$P$i$/9M$($?$H$3$m!"=q$-9~$_B&$G(B atomic ops
$B;H$($P==J,$H$$$&5$$,$7$F$-$^$7$?!#(B

$B$=$l$J$i!"(Breader$B$OB.EYDc2<#0$J$N$G%Q%U%)!<%^%s%9LdBj$,$*$3$j$h$&$,$J$$$7!#(B

Linux$B$G$7$+%F%9%H$7$F$^$;$s$,!"$3$s$J$b$s$G$I$&$G$7$g$&$+!)(B

$B!!(Batomic operation
$B$,==J,$K2>Dj$G$-$k$N$J$i!$$3$l$G$b$$$$$h$&$J5$$,$7$^$9!%(B

$B!!$A$J$_$K!$(Brb_atomic_t $B$O(B int
$B$G$$$$$N$+$7$i!$$H$A$g$C$H;W$C$?!J$$$d!$(B
$B$3$NJU$N>o<1$rCN$i$J$$$b$N$G!%(Brb_atomic_int_t $B$8$c$J$$$s$@$J!$$C$F!K!%(B

Windows $B$O(B LONG
$B$7$+%5%]!<%H$7$F$J$$$G$9$7!“87L)$JOC$r$9$k$H(Bsparc$B$H$+$O(B
$BL?Na%;%C%H$NET9g>e$?$7$+(Bint$B$NCf$G$b(B24bit$B$0$i$$$7$+;H$($J$$$O$:$J$N$G!”(B
$B7?L>$K(Bint$B$rF~$l$k$N$OH?BP$G$9!#(B

$B$"$H!"(B64bit$B$J(Batomic ops $B$O=PMh$J$$(B32bit
CPU$B$,B?$$$N$G!"(B32bit CPU$B$,LG$V$^$G(B
$B$"$s$^$j8!F$$K$$$l$?$/$J$$$H$+;W$C$F$^$9!#$4$K$g$4$K$g(B

$B!!<+J,$,;}$C$F$$$kBP0F$O!$(Binterrupt_flag $B$O$"$/$^$G%R%s%H$H$7$F07$$!$2?(B
$B$+ITET9g$,$"$C$F$b8e$G%j%+%P!<$G$-$k>pJs$K$7$F$*$/!%>C$7$A$c9T$1$J$$>pJs(B
$B!J%7%0%J%k$NE~C#H=Dj$H$+!K$O!$JL$KMQ0U$7$F!$$=$l$r;2>H$7$J$/$F$O$$$1$J$$(B
$B%7%A%e%(!<%7%g%s!J(BGVL $B$N30$G%7%0%J%k4F;k$H$+!K$O!$$=$C$A$b;2>H$9$k!$$H$$(B
$B$&$N$,$$$$$s$G$J$$$+$H;W$C$F$$$^$7$?$,!$J#;($G$9!%>.:j$5$s$NDs0F$O!$$=$N(B
$BE@$G(B interrupt_flag $B$r%-%C%A%j$+$C$A$j4IM}$9$k!$$H$$$&0UL#$G$o$+$j$d$9$$(B
$B$H;W$$$^$9(B

Windows$B$H(Bgcc
$B0J30$K$D$$$F$O!"$$$^$^$G$HF1$8F0:n$K$J$k$N$G!V:#$h$j0-$/$J$k$3$H$O$J$$!W(B
$B$H$$$&0UL#$G5vMFHO0O$+$J$H;W$C$F$^$7$?!#(B

$B$^$?!"(Batomic
ops$B$,%]!<%?%S%j%F%#!<$r2<$2$k2DG=@-$K$D$$$F$b9M$($^$7$?$,!"8=>u$9$G$K(B
signal $B=hM}$,(B atomic ops
$B$K0MB8$7$F$$$k0J>e!“0-2=$7$h$&$,$J$$$H;W$$$^$9!#$?$s$K4{CN$N(B
$BLdBj!JHs(BWindows$B$+$DHs(Bgcc$B4D6-$G$?$^$K%l!<%9%3%s%G%#%7%g%s$GHa$7$$;W$$$r$9$k!K$,D>$i$J$$$@$1$G$9!#$G!”%f!<%9%1!<%9$r9M$($F$_$F$b$=$&$$$&%W%i%C%H%U%)!<%`$G(B365$BF|(B
RoR$B$r$V$s2s$9$H$+$-$C$H$7$F$J$$$H;W$&$N$G!“eLdBj$J$$$G$7$g$&!#(Bbetter
awk $B$H$7$F;H$&8B$j!”$=$&$=$&Ev$?$j$^$;$s$G$9$7!#(B

$BJL0F$H$7$F!"#3$D$N%S%C%H%U%i%0$rJL$NJQ?t$K$7$F$7$^$&$H$$$&$N$,$"$C$?$N$G$9$,!"$5$5$@$5$s$+$i(B
IRC$B$G(B RUBY_VM_CHECK_INTS()
$B$G%m!<%IL?Na$,#2$DA}$($k$N$,5$$K$J$k$H;XE&$5$l$?$?$a(B
$BJQ99$7$?7P0^$,$"$j$^$9!#!J$,!"@5D>$$$&$H%m!<%IL?Na#2$D$C$F8m:9$@$H;W$&$s$G$9$h!K(B

$B:G8e$K$5$5$@$5$s$NDs0F$KBP$9$k8+2r$G$9$,!“BgI}$J%a%j%C%H$,8+$D$+$k$^$G$OH?BP$G$9!#(B
$B$=$&$$$&%H%j%C%-!<$J<BAu$O!V%;%-%e%j%F%#%$%7%e!<$,>e$,$C$F$-$?$+$i;j5^$+$D!”(BABI$B$r2u$5$J$$7A$GD>$5$J$$$H$$$1$J$$$1$INI$$0F$,$J$$!<!W$H$+$$$&>u67$G$7$+$?$J$/$d$k$b$N$G$"$C$F!"IaCJ$+$i$d$k$N$O$$$+$,$J$b$N$+$H;W$$$^$9!#$5$5$@$5$s$,M}2r$7$F$$$F$b!"JL$NC/$+$,$=$N$&$AA0Ds$r2u$9%3%_%C%H$9$k2DG=@-$,9b$$$H$$$&0UL#$G(B

$B!&!&!&$H!"$$$m$$$m$H@bF@:`NA$r$J$i$Y$F$_$^$7$?$,!"$I$&$7$F$bH?BP$H$$$&$N$G$"$l$P;d$O<j$r0z$-$^$9!#(B

$B$7$P$i$/9M$($?$H$3$m!"=q$-9~$_B&$G(B atomic ops
$B;H$($P==J,$H$$$&5$$,$7$F$-$^$7$?!#(B

$B$=$l$J$i!"(Breader$B$OB.EYDc2<#0$J$N$G%Q%U%)!<%^%s%9LdBj$,$*$3$j$h$&$,$J$$$7!#(B

Linux$B$G$7$+%F%9%H$7$F$^$;$s$,!"$3$s$J$b$s$G$I$&$G$7$g$&$+!)(B

Windows$B$H(B !HAVE_GCC_ATOMIC_BUILTINS
$B$G%F%9%H$7$?$H$3$m!"M=A[DL$j%P%0$,8+$D$+$C$?$N$G(B v2 $B$rAw$j$^$9!#(B

$BJQ99E@(B
$B!&(Bcommon.mk $B$K0MB84X78$rDI5-(B
$B!&(BWindows $B$G(B ATOMIC_OR $B%^%/%m$K(Btypo $B$,$"$C$?$N$r=$@5(B
$B!&(BWindows $B$G(B ATOMIC_OR $B$K(B InterlockedOr
$B$G$O$J$/!"(B_InterlockedOr $B$r(B
$B;H$&$h$&$K$7!"(B#pragma intrinsic(_InterlockedOr) $B$r$D$$$+(B
$B!J(BInterlockedOr $B$G%j%s%/$,DL$i$J$$M}M3$,$h$/$o$+$C$F$J$$!K(B
$B!&(Bruby_atomic_exchange $B$GLa$jCM$,4V0c$C$F$$$?$N$r=$@5(B

$B!!$5$5$@$G$9!%(B

(2011/05/11 22:54), Yukihiro M. wrote:

In message “Re: [ruby-dev:43527] Re: [Q] thread->interrupt_flag
$B$,E,@Z$KGSB>@)8f$5$l$F$$$J$$$h$&$K8+$($k(B”
on Wed, 11 May 2011 22:52:36 +0900, KOSAKI Motohiro
[email protected] writes:

|$B$7$P$i$/9M$($?$H$3$m!"=q$-9~$_B&$G(B atomic ops
$B;H$($P==J,$H$$$&5$$,$7$F$-$^$7$?!#(B

|$B$=$l$J$i!"(Breader$B$OB.EYDc2<#0$J$N$G%Q%U%)!<%^%s%9LdBj$,$*$3$j$h$&$,$J$$$7!#(B

|Linux$B$G$7$+%F%9%H$7$F$^$;$s$,!"$3$s$J$b$s$G$I$&$G$7$g$&$+!)(B

$B%3%_%C%H$7$F;n$7$^$7$g$&$h!#(Bnon-Linux$B$NJ}!"(Btrunk$B$r%F%9%H$7$F(B
$B$/$@$5$$$^$;$s$+!)(B

$B!!$3$NLdBj$O$A$g$C$HFC<l$J$N$G!$!V%F%9%H$7$FDL$C$?$i(BOK$B!W$J$b$N$G$O$J$$$H(B
$B;W$$$^$9!%0J2<!$M}M3!%(B

  1. $B:F8=$9$k$?$a$N%F%9%H$,$J$$(B

$B!!:#2s$NLdBj$O!$$“$k%l%”%1!<%9$K$*$$$F6%9g$NLdBj$,5/$3$j$&$k!$$H$$$&>.:j(B
$B$5$s$N;XE&$K4s$j$^$9!%$?$@$7!$%l%“%1!<%9$G$”$k$?$a!$I,$::F8=$9$k%F%9%H$O(B
$B$"$j$^$;$s!%$3$l$,$-$A$s$H@5$7$/<#$C$F$$$k$+$I$&$+$NH=CG$9$k$?$a$K$O!$L5(B
$BM}LpM}$=$&$$$&%7%A%e%(!<%7%g%s$r5/$3$9%F%9%H$r9M$($k$+!$%3!<%I$r8+$F3NG’(B
$B$9$k$7$+$J$$$H;W$$$^$9!%(B

  1. GCC/Windows $B0J30$N%W%i%C%H%[!<%`$G$O2r7h$7$F$$$J$$(B

$B!!:#2s$N%Q%C%A$O!$(Bgcc $B3HD%!$$b$7$/$O(B Windows $B$N(B atomic API
$B$rMQ$$$k$b$N(B
$B$K$J$C$F$$$^$9!J$A$J$_$K!$(Brb_atomic_t
$B$O!$%5%$%:;XDj$O4^$a$J$/$F$$$$$s$@(B
$B$m$&$+!K!%$=$N$?$a!$$3$l$i$r%5%]!<%H$7$F$$$J$$%W%i%C%H%[!<%`$G$O2r7h$7$J(B
$B$$$s$G$J$$$+$J!<!$$J$I$H;W$$$^$9!%$?$@!$(B1
$B$NM}M3$G$=$l$K5$$E$/2DG=@-$O>/(B
$B$J$$$N$G$O$J$$$+$H;W$$$^$9!%!!(B

$B!!$3$l$O!$$I$3$^$G4hD%$k$+!$$C$FOC$@$H$O;W$&$N$G$9$,!%(B