[Ruby 1.9 - Bug #5439][Open] r33361以降sample/test.rb:systemがFになる

Issue #5439 has been reported by Naohisa G…


Bug #5439: r33361以降sample/test.rb:systemがFになる

Author: Naohisa G.
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: 1.9.x

r33361の変更により、ccでコンパイルすると、プログラム終了時にfinalizerが呼ばれなくなり、sample/test.rb:system
にFが出ます。
(Solaris 10, sparc, Sun Studio 11 にて確認)

% make test
(中略)
sample/test.rb:eval …
sample/test.rb:system .FFFF.F.
sample/test.rb:const …
(中略)
sample/test.rb:path …
sample/test.rb:gc …make: *** [yes-test-sample] Error 1

Fが出ているテストの1つは以下です。
test_ok(./miniruby -e 'print "foobar"' == ‘foobar’)

r33361の変更で、以下の文が2か所に追加されています。
if (ATOMIC_SET(finalizing, 1)) return;
マクロ ATOMIC_SET() は、gccの場合(ただしWindows以外)、

define ATOMIC_SET(var, val) __sync_lock_test_and_set(&(var), (val))

に展開され、http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html によるとこの関数は

returns the previous contents of *ptr.
つまり、その変数に以前セットされていた値を返しますが、
gccおよびWIN32以外(Solarisのccなど)では、

define ATOMIC_SET(var, val) ((var) = (val))

に展開される、つまり、新しく代入した値を返すため、
if (ATOMIC_SET(finalizing, 1)) return;
は、ATOMIC_SET(finalizing, 1)が必ず1を返すため、常にreturnしてしまいます。
このため、多くのfinalizerが呼ばれないままプログラムが終了し、rb_io_fptr_finalizeなどで行われているバッファのフラッシュも行われないためFになったと推測します。

Issue #5439 has been updated by Shyouhei U…

その他のコンパイラの場合はそれはそれで修正すべきと思いますが、sparc上のccにはatomic test and
setみたいなインストラクション(があるのか存じ上げませんが)を生成する方法はないのでしょうか?
あるのならそちらを使うようにするのが筋という気がします。

Bug #5439: r33361以降sample/test.rb:systemがFになる

Author: Naohisa G.
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: 1.9.x

r33361の変更により、ccでコンパイルすると、プログラム終了時にfinalizerが呼ばれなくなり、sample/test.rb:system
にFが出ます。
(Solaris 10, sparc, Sun Studio 11 にて確認)

% make test
(中略)
sample/test.rb:eval …
sample/test.rb:system .FFFF.F.
sample/test.rb:const …
(中略)
sample/test.rb:path …
sample/test.rb:gc …make: *** [yes-test-sample] Error 1

Fが出ているテストの1つは以下です。
test_ok(./miniruby -e 'print "foobar"' == ‘foobar’)

r33361の変更で、以下の文が2か所に追加されています。
if (ATOMIC_SET(finalizing, 1)) return;
マクロ ATOMIC_SET() は、gccの場合(ただしWindows以外)、

define ATOMIC_SET(var, val) __sync_lock_test_and_set(&(var), (val))

に展開され、http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html によるとこの関数は

returns the previous contents of *ptr.
つまり、その変数に以前セットされていた値を返しますが、
gccおよびWIN32以外(Solarisのccなど)では、

define ATOMIC_SET(var, val) ((var) = (val))

に展開される、つまり、新しく代入した値を返すため、
if (ATOMIC_SET(finalizing, 1)) return;
は、ATOMIC_SET(finalizing, 1)が必ず1を返すため、常にreturnしてしまいます。
このため、多くのfinalizerが呼ばれないままプログラムが終了し、rb_io_fptr_finalizeなどで行われているバッファのフラッシュも行われないためFになったと推測します。

Issue #5439 has been updated by Motohiro KOSAKI.

代入前の値を知りたいときは ATOMIC_EXCHANGE 使わないとダメ。

やらないといけないことが3つあって
1.ATOMIC_SETに void キャストいれて、戻り値使おうとしたらコンパイルエラーになるようにする
2.指摘されてる間違った ATOMIC_SEC を ATOMIC_EXCHANGEに変換
3.いまatomicに対応してるのはgccとVCだけなので、#if defined(__SUNPRO_CC) だったら
atomic_ops(9f) [opensolaris man page]
の命令つかって、atomicに動くように実装する

1と2はこちらでさっくり出来そうですが、3はこちらではコンパイルテストすら出来ないので
協力していただけると助かります

Bug #5439: r33361以降sample/test.rb:systemがFになる

Author: Naohisa G.
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: 1.9.x

r33361の変更により、ccでコンパイルすると、プログラム終了時にfinalizerが呼ばれなくなり、sample/test.rb:system
にFが出ます。
(Solaris 10, sparc, Sun Studio 11 にて確認)

% make test
(中略)
sample/test.rb:eval …
sample/test.rb:system .FFFF.F.
sample/test.rb:const …
(中略)
sample/test.rb:path …
sample/test.rb:gc …make: *** [yes-test-sample] Error 1

Fが出ているテストの1つは以下です。
test_ok(./miniruby -e 'print "foobar"' == ‘foobar’)

r33361の変更で、以下の文が2か所に追加されています。
if (ATOMIC_SET(finalizing, 1)) return;
マクロ ATOMIC_SET() は、gccの場合(ただしWindows以外)、

define ATOMIC_SET(var, val) __sync_lock_test_and_set(&(var), (val))

に展開され、http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html によるとこの関数は

returns the previous contents of *ptr.
つまり、その変数に以前セットされていた値を返しますが、
gccおよびWIN32以外(Solarisのccなど)では、

define ATOMIC_SET(var, val) ((var) = (val))

に展開される、つまり、新しく代入した値を返すため、
if (ATOMIC_SET(finalizing, 1)) return;
は、ATOMIC_SET(finalizing, 1)が必ず1を返すため、常にreturnしてしまいます。
このため、多くのfinalizerが呼ばれないままプログラムが終了し、rb_io_fptr_finalizeなどで行われているバッファのフラッシュも行われないためFになったと推測します。

Issue #5439 has been updated by Naohisa G…

3.いまatomicに対応してるのはgccとVCだけなので、#if defined(__SUNPRO_CC) だったら
atomic_ops(9f) [opensolaris man page] の命令つかって、atomicに動くように実装する

Solaris10ではヘッダの場所が #include <atomic.h>
となっているのがOpenSolarisと違いますが、関数の仕様は同じのようです。(もっとも、Solaris10 の atomic.h
を覗いたら、単に #include <sys/atomic.h> しているだけでしたが)

https://sites.google.com/a/diviware.com/unix/unix-page/solaris-page/solaris-man-pages/3c/atomic_ops

NetBSDなど他のOSにも同等/類似の関数があるようですので、configureで判別するほうが幸せかもしれません。
http://www.daemon-systems.org/man/atomic_ops.3.html


Bug #5439: r33361以降sample/test.rb:systemがFになる

Author: Naohisa G.
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: 1.9.x

r33361の変更により、ccでコンパイルすると、プログラム終了時にfinalizerが呼ばれなくなり、sample/test.rb:system
にFが出ます。
(Solaris 10, sparc, Sun Studio 11 にて確認)

% make test
(中略)
sample/test.rb:eval …
sample/test.rb:system .FFFF.F.
sample/test.rb:const …
(中略)
sample/test.rb:path …
sample/test.rb:gc …make: *** [yes-test-sample] Error 1

Fが出ているテストの1つは以下です。
test_ok(./miniruby -e 'print "foobar"' == ‘foobar’)

r33361の変更で、以下の文が2か所に追加されています。
if (ATOMIC_SET(finalizing, 1)) return;
マクロ ATOMIC_SET() は、gccの場合(ただしWindows以外)、

define ATOMIC_SET(var, val) __sync_lock_test_and_set(&(var), (val))

に展開され、http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html によるとこの関数は

returns the previous contents of *ptr.
つまり、その変数に以前セットされていた値を返しますが、
gccおよびWIN32以外(Solarisのccなど)では、

define ATOMIC_SET(var, val) ((var) = (val))

に展開される、つまり、新しく代入した値を返すため、
if (ATOMIC_SET(finalizing, 1)) return;
は、ATOMIC_SET(finalizing, 1)が必ず1を返すため、常にreturnしてしまいます。
このため、多くのfinalizerが呼ばれないままプログラムが終了し、rb_io_fptr_finalizeなどで行われているバッファのフラッシュも行われないためFになったと推測します。