ruby-trunk-changes r31448 - r31471

今日も kosaki さん無双。 lock 関係(というか条件変数)の修正が大量にありました。deadlock 検出の方法など背景も勉強しておかないとこのあたりの修正はきちんとレビューできないなぁという感じなので精進します。

nobu:r31448 2011-05-06 23:02:10 +0900

最近追加されたファイルに svn のプロパティを設定しています。

kosaki:r31449 2011-05-06 23:18:06 +0900

configure での nanosleep のチェックを削除しています。現在 nanosleep は利用されてされていないそうです。

kosaki:r31450 2011-05-06 23:58:38 +0900

rb_wait_for_single_fd で ppoll(2) が利用可能ならば poll(2) のかわりに ppoll(2) を利用するようにしています。 [ruby-core:36003] [Feature #4531]

kosaki:r31451 2011-05-07 01:47:38 +0900

rb_thread_cond_t は pthread_cond_t と同じものだったのを、pthread_cond_t * を含む構造体として別途定義して、clockid というメンバを追加しています。利用可能であれば pthread_condattr_setclock(3) で CLOCK_MONOTONIC を設定して pthread_cond_t を初期化するようにしています。これによりタイムアウトの判定に使うクロックを CLOCK_MONOTONIC に指定して、システム時刻の変更の影響を受けないようにしています。

svn:r31452 2011-05-07 01:47:44 +0900

version.h の日付更新。

kosaki:r31453 2011-05-07 01:56:06 +0900

r31451 では native_cond_initialize() の flags で RB_CONDATTR_CLOCK_MONOTONIC を指定されれば CLOCK_MONOTONIC を利用するようにしただけだったので、タイマースレッド用の timer_thread_cond を CLOCK_MONOTONIC を指定して初期化するようにしています。

kosaki:r31454 2011-05-07 02:39:32 +0900

native_cond_timedwait() に渡すタイムアウト時刻を計算する関数が似たものがいくつかあったのを native_cond_timeout() として定義してこれを利用するようにしています。クロックの種類が CLOCK_MONOTONIC の時は clock_gettime() を使って時刻を取得するようにしています。
また mutex_alloc() でも native_cond_initialize() に RB_CONDATTR_CLOCK_MONOTONIC を渡すようにしています。

kosaki:r31455 2011-05-07 02:50:23 +0900

RB_CONDATTR_CLOCK_MONOTONIC を常に定義するようにしています。 CLOCK_MONOTONIC が利用可能な時だけ定義していました。

akr:r31456 2011-05-07 03:14:25 +0900

pack/unpack の rdoc の "c" の項目を修正しています(char -> signed char)。

kosaki:r31457 2011-05-07 03:17:14 +0900

native_cond_timeout() でタイムアウト時刻の計算時にタイムアウトに負の時間が指定されたら ではなくて、オーバフローが発生した時のことを考慮して、time_t の最大秒数待つようにしています。
また native_thread_init() でも native_cond_initialize() に RB_CONDATTR_CLOCK_MONOTONIC を渡すようにしているので、これでおそらく全ての pthread_cond_t は(利用可能ならば) CLOCK_MONOTONIC の指定で生成されるようになっています。

kosaki:r31458 2011-05-07 12:43:27 +0900

pthread_win32.c でタイムアウト時刻の計算で nsec の値をそのまま usec に格納しているため 1000 倍の粒度になっていたのを修正。

kosaki:r31459 2011-05-07 15:17:59 +0900

thread_win32.c の cond_event_entry という HANDLE を linked list で管理している構造体を、単方向リストから双方向リストに変更して、タイムアウトが発生したものについてはリストから削除するようにしています。Windows で SEGV していた模様。

kosaki:r31460 2011-05-07 15:20:39 +0900

mutex_t の cond_waiting と cond_notified はタイムアウトつきの native_cond_timedwait() の呼び出し時には増減させないようにしています。 native_cond_signal() によらず抜けることがあるので、デッドロック検出が誤っていたようです。

kosaki:r31461 2011-05-07 15:22:39 +0900

デバッグ用のコードの消し忘れを除去。

nobu:r31462 2011-05-07 18:28:43 +0900

MONOTONIC_COND を利用できるかどうかの判定をより厳しくして、 clock_t 型が利用できるかどうかもチェックするようにしています。

kosaki:r31464 2011-05-07 22:22:12 +0900

r31460 で native_cond_timedwait() を呼ぶ時は cond_waiting/cond_notified を増減させないようにしていましたが、native_cond_timedwait() がタイムアウトで抜けた時に加算しておいた cond_waiting を減算して戻すようにするように変更しています。

kosaki:r31465 2011-05-07 22:36:08 +0900

rb_fd_init_copy() という rb_fdset_t の複製を作る API を追加して do_select() で利用するようにしています。

kosaki:r31466 2011-05-07 22:40:56 +0900

rb_fd_init() の引数の volatile 指示子を削除しています。

kosaki:r31467 2011-05-07 22:44:27 +0900

rb_fd_zero() で MEMZERO で fdset を初期化しているので、不要な FD_ZERO の呼び出しを削除しています。

nobu:r31468 2011-05-07 23:52:54 +0900

test/ruby/test_io.rb の test_readpartial_lock, test_read_lock において、別の Thread での IO#read や IO#readpartial の結果待ちのため 0 until s.size == 5 のようにループで待っているところを Thread.pass until s.size == 5 のように Thread.pass で明示的に別の Thread へ処理を空け渡すようにしています。

kosaki:r31469 2011-05-07 23:57:38 +0900

test/io/wait/test_io_wait.rb のテストは mswin ではスキップするようにしています。

kosaki:r31470 2011-05-08 00:17:22 +0900

test/io/wait/test_io_wait.rb は pipe を使っていたのが問題だったようなので、IO.pipe のかわりに Socket.pair で IO のペアを生成するようにして、mswin でも再度テストを有効にしています。

svn:r31471 2011-05-08 00:17:25 +0900

version.h の日付更新。