Bug #886

GC from blocking region

Added by ko1 (Koichi Sasada) over 3 years ago. Updated about 1 year ago.

[ruby-dev:37448]
Status:Closed Start date:
Priority:Low Due date:
Assignee:- % Done:

0%

Category:-
Target version:1.9.1 RC2
ruby -v:

Description

 ささだです.

U.Nakamura wrote::
> こんにちは、なかむら(う)です。
> 
> In message "[ruby-dev:37381] Re: Ruby開発ミーティングログ"
>     on Dec.11,2008 13:44:58, <usa@garbagecollect.jp> wrote:
>>> - Bug #755 [ruby-core:19946]: Windows specific. うささんに聞く (akr)
>> 対応パッチを作ってこの問題が解決するところまではたどり着いて
>> るのですが、メモリ関連のバグを仕込んでいるらしく別のテストで
>> [BUG]るようになってしまったので困っているところです。
>> 誰かパッチのバグを探してくれる人がいるならそのパッチを出しま
>> すが...
> 
> これ、原因わかりました。
> 
> blocking region内でGCが発生すると、blocing regionじゃないスレ
> ッド(なんか名前ないかな)のスタックが一切markされないため、そ
> のスレッドでスタック上にあるVALUEが回収されてしまいます。
> 対策としては、
> 
>  (1) blocking regionからGCが起こされたときはblocking regionじゃ
>      ないスレッドを止めてそのスレッドのスタックをmarkしてGCを
>      続行させる。
>        → 無理がありそう
> 
>  (2) blocking regionからGCを起こさせない
> 
>    (a) xmalloc等は使用禁止とする
>          → 面倒なのではないか
> 
>    (b) blocking regionからxmalloc等が呼ばれたときはメモリ確保
>        できなくてもGCしない
> 
> といったあたりがIRCでは出ました。

(c) blocking_region の中で,さらに ruby な環境にさわれる状態になり(GVL
を取得する),メモリ確保を行う,ということが考えられます.性能はもちろん
落ちますが(使いどころを間違えると,とてもとても遅くなります),どーして
も必要な場合は使う,ってことが出来るかと思います.

-- 
// SASADA Koichi at atdot dot net

History

Updated by usa (Usaku NAKAMURA) over 3 years ago

こんにちは、なかむら(う)です。

In message "[ruby-dev:37448] [Bug: trunk] GC from blocking region"
    on Dec.15,2008 22:44:31, <ko1@atdot.net> wrote:
> (c) blocking_region の中で,さらに ruby な環境にさわれる状態になり(GVL
> を取得する),メモリ確保を行う,ということが考えられます.性能はもちろん
> 落ちますが(使いどころを間違えると,とてもとても遅くなります),どーして
> も必要な場合は使う,ってことが出来るかと思います.

現状これができるAPIがないわけですが、追加できるものならすると
しても、いつ頃これが可能になりそうですか?


それでは。
-- 
U.Nakamura <usa@garbagecollect.jp>

Updated by ko1 (Koichi Sasada) over 3 years ago

 ささだです.

U.Nakamura wrote::
> In message "[ruby-dev:37448] [Bug: trunk] GC from blocking region"
>     on Dec.15,2008 22:44:31, <ko1@atdot.net> wrote:
>> (c) blocking_region の中で,さらに ruby な環境にさわれる状態になり(GVL
>> を取得する),メモリ確保を行う,ということが考えられます.性能はもちろん
>> 落ちますが(使いどころを間違えると,とてもとても遅くなります),どーして
>> も必要な場合は使う,ってことが出来るかと思います.
> 
> 現状これができるAPIがないわけですが、追加できるものならすると
> しても、いつ頃これが可能になりそうですか?

 作ってみました.これで動くかやってもらえませんか.あと,名前のセンスが
悪すぎるとか,そういう話もあるかと思うので,いい名前募集中です.

注意:
- rb_thread_call_with_gvl() に渡す関数の返値は VALUE だと
  mark されないことがあるので,VALUE の受け渡しは基本的にしない


 ちなみに,[ruby-dev:37448] で示した解決策は穴があって,xmalloc したメ
モリは xfree しなければならないという制約があります.なので,以下のよう
にするのがよいのではないかと思います.

 (a) malloc 試行 -> 失敗
 (b) rb_thread_call_with_gvl() を使って GC を強制発生
 (c) malloc 試行 -> 失敗
 (d) C レベルでの資源を回収(後始末)
 (e) rb_thread_call_with_gvl() で呼び出した関数中で NoMemoryError 発生

Index: vm_core.h
===================================================================
--- vm_core.h	(リビジョン 20894)
+++ vm_core.h	(作業コピー)
@@ -363,6 +363,7 @@ typedef struct rb_thread_struct
     int slice;

     native_thread_data_t native_thread_data;
+    void *blocking_region_buffer;

     VALUE thgroup;
     VALUE value;
Index: thread.c
===================================================================
--- thread.c	(リビジョン 20894)
+++ thread.c	(作業コピー)
@@ -947,6 +947,7 @@ static inline void
 blocking_region_begin(rb_thread_t *th, struct rb_blocking_region_buffer
*region,
 		      rb_unblock_function_t *func, void *arg)
 {
+    th->blocking_region_buffer = region;
     region->prev_status = th->status;
     set_unblock_function(th, func, arg, &region->oldubf);
     th->status = THREAD_STOPPED;
@@ -1033,6 +1034,32 @@ rb_thread_blocking_region(
     }, ubf, data2);

     return val;
+}
+
+/* alias of rb_thread_blocking_region() */
+VALUE
+rb_thread_call_without_gvl(
+    rb_blocking_function_t *func, void *data1,
+    rb_unblock_function_t *ubf, void *data2)
+{
+    return rb_thread_blocking_region(func, data1, ubf, data2);
+}
+
+void *
+rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
+{
+    rb_thread_t *th = ruby_thread_from_native();
+    struct rb_blocking_region_buffer *brb =
+      (struct rb_blocking_region_buffer *)th->blocking_region_buffer;
+    struct rb_unblock_callback prev_unblock = th->unblock;
+    void *r;
+
+    blocking_region_end(th, brb);
+    /* enter to the Ruby world */
+    r = (*func)(data1);
+    /* levae from Ruby world */
+    blocking_region_begin(th, brb, prev_unblock.func, prev_unblock.arg);
+    return r;
 }

 /*


-- 
// SASADA Koichi at atdot dot net

Updated by usa (Usaku NAKAMURA) over 3 years ago

こんにちは、なかむら(う)です。

In message "[ruby-dev:37531] Re: [Bug: trunk] GC from blocking region"
    on Dec.22,2008 09:37:09, <ko1@atdot.net> wrote:
>  作ってみました.これで動くかやってもらえませんか.あと,名前のセンスが
> 悪すぎるとか,そういう話もあるかと思うので,いい名前募集中です.

rb_thread_from_native()がNULLを返して死にまくりでした。


それでは。
-- 
U.Nakamura <usa@garbagecollect.jp>

Updated by ko1 (Koichi Sasada) over 3 years ago

 ささだです.

U.Nakamura wrote::
> In message "[ruby-dev:37531] Re: [Bug: trunk] GC from blocking region"
>     on Dec.22,2008 09:37:09, <ko1@atdot.net> wrote:
>>  作ってみました.これで動くかやってもらえませんか.あと,名前のセンスが
>> 悪すぎるとか,そういう話もあるかと思うので,いい名前募集中です.
> 
> rb_thread_from_native()がNULLを返して死にまくりでした。

 なかださん,この辺ってどうなってましたっけ.

-- 
// SASADA Koichi at atdot dot net

Updated by yugui (Yuki Sonoda) over 3 years ago

  • Target version set to 1.9.1 RC2

Updated by yugui (Yuki Sonoda) over 3 years ago

  • Status changed from Open to Closed

Also available in: Atom PDF