Backport #8065

r39688 - test_queue.rb (test_thr_kill): reduce iterations from 2000 to 250. のバックポート

Added by Motohiro KOSAKI about 1 year ago. Updated about 1 year ago.

[ruby-dev:47156]
Status:Closed
Priority:Normal
Assignee:Tomoyuki Chikanaga

Description

現在、uniprocessor環境で testthrkillを実行すると、ほぼ必ず失敗します。原因はコミットログにも書いたのですが
以下の様なスクリプトがあるとき、

totalcount.times do |i|
open("test
thrkillcount", "w") {|f| f.puts i }
queue = Queue.new
r, w = IO.pipe
th = Thread.start {
queue.push(nil)
r.read 1
}
queue.pop
th.kill
th.join
end

ほぼ確実に、

1、Thread.start
2.Queue.pop
3,ここでコンテキストスイッチ
4,Queue.push
5.r.readの処理の途中で gvlrelease()
6.ここでコンテキストスイッチ
7.th.kill -> ubf
select -> pthread_kill(SIGVTALARM) とくるが、
別に、ブロッキングシステムコールで寝ているわけではないので
サブスレッドには影響ない
8.th.join
9.ここでコンテキストスイッチ
10.read(2) を呼ぶ
11.ここで動いているスレッドが一旦いなくなる
12.100msec後にtimer threadがSIGVTALARMを再送、read()が解除される

と動くので、30秒間では300回しかループが回りません。

状況証拠的に [Bug #7521] の原因だと見ています。確証はないので、別チケットにしましたが。


Related issues

Related to ruby-trunk - Bug #7521: test_thr_kill(TestQueue) fails Closed 12/06/2012

Associated revisions

Revision 39728
Added by Tomoyuki Chikanaga about 1 year ago

merge revision(s) 39688: [Backport #8065]

* test/thread/test_queue.rb (TestQueue#test_thr_kill): reduce
  iterations from 2000 to 250. When running on uniprocessor
  systems, every th.kill needs TIME_QUANTUM_USEC time (i.e.
  100msec on posix systems). Because, "r.read 1" is 3 steps
  operations that 1) release GVL 2) read 3) acquire gvl and
  (1) invoke context switch to main thread. and then, main
  thread's th.kill resume (1), but not (2). Thus read interrupt
  need TIME_QUANTUM_USEC. Then maximum iteration is 30sec/100msec
  = 300.

History

#1 Updated by Tomoyuki Chikanaga about 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r39728.
Motohiro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 39688: [Backport #8065]

* test/thread/test_queue.rb (TestQueue#test_thr_kill): reduce
  iterations from 2000 to 250. When running on uniprocessor
  systems, every th.kill needs TIME_QUANTUM_USEC time (i.e.
  100msec on posix systems). Because, "r.read 1" is 3 steps
  operations that 1) release GVL 2) read 3) acquire gvl and
  (1) invoke context switch to main thread. and then, main
  thread's th.kill resume (1), but not (2). Thus read interrupt
  need TIME_QUANTUM_USEC. Then maximum iteration is 30sec/100msec
  = 300.

Also available in: Atom PDF