[#43610] Re: [ruby-list:48149] Re: requireが配列を取れたら便利だと思うんだけど.. — Hiroshi Nakamura <nakahiro@...>
cnVieS1saXN0GyRCJCskaTt9JEMkRk1oJF4kNyQ/ISMkRyRiQjMkKyRKJD0kJiEjGyhCCgoyMDEx
松田です。
卜部です
[#43620] Module#mix — Yukihiro Matsumoto <matz@...>
まつもと ゆきひろです
[#43634] [Ruby 1.9 - Bug #4835][Open] Compilation failure of ext/tk with recent ActiveTcl — Yuki Sonoda <yugui@...>
[#43643] DateTime.new! and DateTime.jd — Aaron Patterson <aaron.patterson@...>
こんにちは、アーロンです。
blocker はお前だろ。
まつもと ゆきひろです
> うーん、ただでさえ日英のコミュニケーション障壁があるのに、よ
2011/6/7 Tadayoshi Funaba <tadf@dotrb.org>:
皆さんってのに俺は入ってないみたいだな。
まつもと ゆきひろです
> Aaronが言ってる「リリース」は1.9.3のことだと思いますよ。
まつもと ゆきひろです
> Railsのリリースについては私は知りません。が、1.9.3のリリース
[#43645] Re: [ruby-core:36778] Re: 1.8.7 release next month — Urabe Shyouhei <shyouhei@...>
Moving to ruby-dev to understand strategies of backporting the Tk
永井@知能.九工大です.
卜部です。
永井@知能.九工大です.
[#43655] [Ruby 1.9 - Bug #4853][Assigned] ext/tk/extconf.rb fails on Mac OS X — Nobuyoshi Nakada <nobu@...>
[#43686] test.rb for make run — SASADA Koichi <ko1@...>
ささだです.
[#43700] [Ruby 1.9 - Bug #4866][Assigned] Macでmake checkするとIO.copy_streamでSEGV — Motohiro KOSAKI <kosaki.motohiro@...>
[#43710] Re: [ruby-changes:19939] kosaki:r31986 (trunk): * ext/tk/tcltklib.c (lib_eventloop_core): replace CHECK_INTS with — KOSAKI Motohiro <kosaki.motohiro@...>
永井さん
永井@知能.九工大です.
2011年6月12日0:00 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>:
[#43716] [Ruby 1.9 - Bug #3137] complex.rb changes exceptions of Math — Koichi Sasada <redmine@...>
[#43717] [Ruby 1.9 - Bug #3456] bisarre comma — Koichi Sasada <redmine@...>
まつもと ゆきひろです
メールにじかに反応したまつもとさんは読んでないと思うのでコメント#5を再掲
まつもと ゆきひろです
卜部です。
[#43743] [Ruby 1.9 - Feature #4871][Open] envのコンパクト化 — Kazuki Tsujimoto <kazuki@...>
[#43779] Re: [ruby-cvs:38869] nobu:r31690 (trunk): * gc.c (vm_xcalloc): use calloc provided by platforms. — Yutaka Kanemoto <kinpoco@...>
こんにちは。
金本と申します。
>> AIXでは0 size mallocでNULLが返るのでこまったことになっています。
ささだです.
[#43787] [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Kenta Murata <muraken@...>
まつもと ゆきひろです
もう結論が出てしまったようですが、これは、元々 lib/complex.rb にあった
=E3=82=80=E3=82=89=E3=81=9F=E3=81=A7=E3=81=99=E3=80=82
> complex.rb をロードすると Math が CMath 相当に置き換わりますから、
=E3=82=80=E3=82=89=E3=81=9F=E3=81=A7=E3=81=99=E3=80=82
まつもと ゆきひろです
=E3=82=80=E3=82=89=E3=81=9F=E3=81=A7=E3=81=99=E3=80=82
> これに相当する事をやっているのが complex.rb なので、
遠藤です。
> 定義域を増やすだけにしよう、ということですよね。賛成です。
2011年6月14日22:17 Tadayoshi Funaba <tadf@dotrb.org>:
> 互換性がないという点では同じ話だと思うのですが……。
2011年6月14日23:02 Tadayoshi Funaba <tadf@dotrb.org>:
> いやあ、5 月末の feature freeze 時点では -2 を返していたはずなんですが、
遠藤です。
[#43791] [Ruby 1.9 - Bug #4879][Open] test_new(OpenSSL::TestPKeyRSA) fails on Win32 — Akio Tajima <artonx@...>
[#43820] mysterious hang at busy loop after system() — Tanaka Akira <akr@...>
以下のようなプログラムが手元の環境のひとつでハングします。
[#43829] [Ruby 1.9 - Bug #4891][Open] Vector#normalize — Kenta Murata <muraken@...>
[#43852] [Ruby 1.9 - Bug #4909][Open] trapハンドラは再入されてはいけないのではないか? — Motohiro KOSAKI <kosaki.motohiro@...>
同意します。
[#43859] [Ruby 1.9 - Bug #4911][Open] timer_thread_function() が thead unsafe — Motohiro KOSAKI <kosaki.motohiro@...>
[#43861] Date/DateTimeの仕様について — "NARUSE, Yui" <naruse@...>
ふなばさん
[#43869] [Ruby 1.9 - Bug #4919][Open] OpenSSL::SSL::Sesssion#time= に Bignum を渡すと ArgumentError が発生する — Tomoyuki Chikanaga <nagachika00@...>
報告ありがとうございます。32bit環境で落ちるとか考えてませんでした。。。
[#43875] [Ruby 1.9 - Feature #4921][Assigned] Remove intern.h — Yui NARUSE <redmine@...>
[#43890] [Ruby 1.9 - Bug #4072] dRubyで作成したサーバプログラムがsleepしていてもexitしてしまう — Tomoyuki Chikanaga <nagachika00@...>
[#43902] [Ruby 1.9 - Bug #4926][Open] --gc-stress付きtest/ruby/enc/test_emoji.rbが失敗する — Kazuki Tsujimoto <kazuki@...>
[#44001] socket related errors on chkbuild — SASADA Koichi <ko1@...>
ささだです.
[ruby-dev:43835] Timer thread hack
ささだです. タイマスレッドの挙動を抑制するパッチを作成しました.もう,小崎さんのと ころにはあるかもしれませんが,とりあえず,ってことで. fork のことを考えていないので,まだ fork があるところだと動きません. 多分.それを除いた btest は動きました. どんなもんでしょうか.あとは,process.c のあたりを弄れば,と思っています. # select とか pipe を使ってスクラッチから書くのが,実は初めて. 経緯: 1. timer thread が定期的に動くのが気に入らない(電力的な意味とか) 2. 以前,セマフォで,そうじゃなくするパッチを書いた 3. MacOSX だとそれじゃうまくいかない(機能が足りない) 4. pipe hack でなんとかしよう(signal handler -> timer thread への通信) -- // SASADA Koichi at atdot dot net
Attachments (1)
Index: thread_win32.c
===================================================================
--- thread_win32.c (revision 32136)
+++ thread_win32.c (working copy)
@@ -717,14 +717,19 @@
timer_thread_func(void *dummy)
{
thread_debug("timer_thread\n");
- while (WaitForSingleObject(timer_thread_lock, TIME_QUANTUM_USEC/1000) ==
- WAIT_TIMEOUT) {
+ while (WaitForSingleObject(timer_thread_lock, TIME_QUANTUM_USEC/1000) == WAIT_TIMEOUT) {
timer_thread_function(dummy);
}
thread_debug("timer killed\n");
return 0;
}
+void
+rb_thread_wakeup_timer_thread(void)
+{
+ /* do nothing */
+}
+
static void
rb_thread_create_timer_thread(void)
{
Index: thread_pthread.c
===================================================================
--- thread_pthread.c (revision 32136)
+++ thread_pthread.c (working copy)
@@ -42,17 +42,23 @@
#define GVL_DEBUG 0
+void rb_thread_wakeup_timer_thread(void);
+
static void
__gvl_acquire(rb_vm_t *vm)
{
if (vm->gvl.acquired) {
+ if (vm->gvl.waiting == 0) rb_thread_wakeup_timer_thread();
+
vm->gvl.waiting++;
while (vm->gvl.acquired) {
native_cond_wait(&vm->gvl.cond, &vm->gvl.lock);
}
vm->gvl.waiting--;
+ if (vm->gvl.waiting == 0) rb_thread_wakeup_timer_thread();
+
if (vm->gvl.need_yield) {
vm->gvl.need_yield = 0;
native_cond_signal(&vm->gvl.switch_cond);
@@ -982,47 +988,76 @@
#endif /* USE_SIGNAL_THREAD_LIST */
static pthread_t timer_thread_id;
-static rb_thread_cond_t timer_thread_cond;
-static pthread_mutex_t timer_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static int timer_thread_pipe[2];
+void
+rb_thread_wakeup_timer_thread(void)
+{
+ /* already opened */
+ if (timer_thread_pipe[1]) {
+ const char *buff = "x";
+ int err;
+ if ((err = write(timer_thread_pipe[1], buff, 1)) <= 0) {
+ rb_bug_errno("rb_thread_signal_interrupt: write", errno);
+ }
+ }
+}
+
/* 100ms. 10ms is too small for user level thread scheduling
* on recent Linux (tested on 2.6.35)
*/
#define TIME_QUANTUM_USEC (100 * 1000)
static void *
-thread_timer(void *dummy)
+thread_timer(void *p)
{
- struct timespec timeout_10ms;
- struct timespec timeout;
+ rb_global_vm_lock_t *gvl = (rb_global_vm_lock_t *)p;
+ const struct timeval time_quantum = {
+ 0, TIME_QUANTUM_USEC
+ };
- timeout_10ms.tv_sec = 0;
- timeout_10ms.tv_nsec = TIME_QUANTUM_USEC * 1000;
+ fprintf(stderr, "start timer thread\n");
- native_mutex_lock(&timer_thread_lock);
- native_cond_broadcast(&timer_thread_cond);
- timeout = native_cond_timeout(&timer_thread_cond, timeout_10ms);
-
while (system_working > 0) {
int err;
- err = native_cond_timedwait(&timer_thread_cond, &timer_thread_lock,
- &timeout);
+ fd_set rfds;
+ FD_ZERO(&rfds);
+ FD_SET(timer_thread_pipe[0], &rfds);
+
+ if (gvl->waiting > 0) {
+ struct timeval timeout = time_quantum;
+ err = select(timer_thread_pipe[0] + 1, &rfds, 0, 0, &timeout); /* polling (TIME_QUANTUM_USEC usec) */
+ }
+ else {
+ err = select(timer_thread_pipe[0] + 1, &rfds, 0, 0, 0); /* infinite */
+ }
+
if (err == 0) {
- /*
- * Spurious wakeup or native_stop_timer_thread() was called.
- * We need to recheck a system_working state.
- */
+ /* timeout? */
}
- else if (err == ETIMEDOUT) {
- ping_signal_thread_list();
- timer_thread_function(dummy);
- timeout = native_cond_timeout(&timer_thread_cond, timeout_10ms);
+ else if (err > 0) {
+ /* receive signal */
+ char buff[1];
+ if (read(timer_thread_pipe[0], buff, 1) != 1) {
+ rb_bug_errno("thread_timer: read", errno);
+ }
}
- else
- rb_bug_errno("thread_timer/timedwait", err);
+ else { /* err < 0 */
+ if (errno == EINTR) {
+ /* interrupted. ignore */
+ }
+ else {
+ rb_bug_errno("thread_timer: select", errno);
+ }
+ }
+
+ /* timer function */
+ ping_signal_thread_list();
+ timer_thread_function(0);
+ fprintf(stderr, "tick\n");
}
- native_mutex_unlock(&timer_thread_lock);
+
return NULL;
}
@@ -1036,20 +1071,24 @@
int err;
pthread_attr_init(&attr);
- native_cond_initialize(&timer_thread_cond, RB_CONDATTR_CLOCK_MONOTONIC);
#ifdef PTHREAD_STACK_MIN
pthread_attr_setstacksize(&attr,
PTHREAD_STACK_MIN + (THREAD_DEBUG ? BUFSIZ : 0));
#endif
- native_mutex_lock(&timer_thread_lock);
- err = pthread_create(&timer_thread_id, &attr, thread_timer, 0);
+
+ /* communication pipe with timer thread and signal handler */
+ err = pipe(timer_thread_pipe);
if (err != 0) {
- native_mutex_unlock(&timer_thread_lock);
+ fprintf(stderr, "[FATAL] Failed to create communication pipe for timer thread (errno: %d)\n", err);
+ exit(EXIT_FAILURE);
+ }
+
+ /* create timer thread */
+ err = pthread_create(&timer_thread_id, &attr, thread_timer, &GET_VM()->gvl);
+ if (err != 0) {
fprintf(stderr, "[FATAL] Failed to create timer thread (errno: %d)\n", err);
exit(EXIT_FAILURE);
}
- native_cond_wait(&timer_thread_cond, &timer_thread_lock);
- native_mutex_unlock(&timer_thread_lock);
}
rb_disable_interrupt(); /* only timer thread recieve signal */
}
@@ -1058,15 +1097,13 @@
native_stop_timer_thread(void)
{
int stopped;
- native_mutex_lock(&timer_thread_lock);
stopped = --system_working <= 0;
if (stopped) {
- native_cond_signal(&timer_thread_cond);
- }
- native_mutex_unlock(&timer_thread_lock);
- if (stopped) {
+ rb_thread_wakeup_timer_thread();
native_thread_join(timer_thread_id);
}
+ if (close(timer_thread_pipe[0]) < 0) { rb_bug_errno("native_stop_timer_thread: close(ttp[0])", errno); }
+ if (close(timer_thread_pipe[1]) < 0) { rb_bug_errno("native_stop_timer_thread: close(ttp[1])", errno); }
return stopped;
}
Index: signal.c
===================================================================
--- signal.c (revision 32136)
+++ signal.c (working copy)
@@ -501,11 +501,14 @@
#endif
#endif
+void rb_thread_wakeup_timer_thread(void);
+
static RETSIGTYPE
sighandler(int sig)
{
ATOMIC_INC(signal_buff.cnt[sig]);
ATOMIC_INC(signal_buff.size);
+ rb_thread_wakeup_timer_thread();
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
ruby_signal(sig, sighandler);
#endif