[#43610] Re: [ruby-list:48149] Re: requireが配列を取れたら便利だと思うんだけど.. — Hiroshi Nakamura <nakahiro@...>

cnVieS1saXN0GyRCJCskaTt9JEMkRk1oJF4kNyQ/ISMkRyRiQjMkKyRKJD0kJiEjGyhCCgoyMDEx

12 messages 2011/06/02

[#43643] DateTime.new! and DateTime.jd — Aaron Patterson <aaron.patterson@...>

こんにちは、アーロンです。

25 messages 2011/06/07
[#43647] Re: DateTime.new! and DateTime.jd — Tadayoshi Funaba <tadf@...> 2011/06/07

blocker はお前だろ。

[#43648] Re: DateTime.new! and DateTime.jd — Yukihiro Matsumoto <matz@...> 2011/06/07

まつもと ゆきひろです

[#43651] Re: DateTime.new! and DateTime.jd — Tadayoshi Funaba <tadf@...> 2011/06/07

> うーん、ただでさえ日英のコミュニケーション障壁があるのに、よ

[#43653] Re: DateTime.new! and DateTime.jd — Aaron Patterson <aaron.patterson@...> 2011/06/07

2011/6/7 Tadayoshi Funaba <tadf@dotrb.org>:

[#43657] Re: DateTime.new! and DateTime.jd — Tadayoshi Funaba <tadf@...> 2011/06/07

皆さんってのに俺は入ってないみたいだな。

[#43661] Re: DateTime.new! and DateTime.jd — Yukihiro Matsumoto <matz@...> 2011/06/07

まつもと ゆきひろです

[#43662] Re: DateTime.new! and DateTime.jd — Tadayoshi Funaba <tadf@...> 2011/06/07

> Aaronが言ってる「リリース」は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

13 messages 2011/06/07

[#43787] [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Kenta Murata <muraken@...>

24 messages 2011/06/13
[#43788] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Yukihiro Matsumoto <matz@...> 2011/06/13

まつもと ゆきひろです

[#43789] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Tadayoshi Funaba <tadf@...> 2011/06/13

もう結論が出てしまったようですが、これは、元々 lib/complex.rb にあった

[#43794] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Kenta Murata <muraken@...> 2011/06/13

=E3=82=80=E3=82=89=E3=81=9F=E3=81=A7=E3=81=99=E3=80=82

[#43795] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Tadayoshi Funaba <tadf@...> 2011/06/13

> complex.rb をロードすると Math が CMath 相当に置き換わりますから、

[#43797] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Kenta Murata <muraken@...> 2011/06/14

=E3=82=80=E3=82=89=E3=81=9F=E3=81=A7=E3=81=99=E3=80=82

[#43799] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Yukihiro Matsumoto <matz@...> 2011/06/14

まつもと ゆきひろです

[#43800] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Kenta Murata <muraken@...> 2011/06/14

=E3=82=80=E3=82=89=E3=81=9F=E3=81=A7=E3=81=99=E3=80=82

[#43803] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Tadayoshi Funaba <tadf@...> 2011/06/14

> これに相当する事をやっているのが complex.rb なので、

[#43806] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Yusuke ENDOH <mame@...> 2011/06/14

遠藤です。

[#43807] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Tadayoshi Funaba <tadf@...> 2011/06/14

> 定義域を増やすだけにしよう、ということですよね。賛成です。

[#43809] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Yusuke ENDOH <mame@...> 2011/06/14

2011年6月14日22:17 Tadayoshi Funaba <tadf@dotrb.org>:

[#43810] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Tadayoshi Funaba <tadf@...> 2011/06/14

> 互換性がないという点では同じ話だと思うのですが……。

[#43811] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Yusuke ENDOH <mame@...> 2011/06/14

2011年6月14日23:02 Tadayoshi Funaba <tadf@dotrb.org>:

[#43812] Re: [Ruby 1.9 - Feature #4878][Open] CMath に frexp, ldexp, hypot の3関数は不要ではないか — Tadayoshi Funaba <tadf@...> 2011/06/14

> いやあ、5 月末の feature freeze 時点では -2 を返していたはずなんですが、

[#43852] [Ruby 1.9 - Bug #4909][Open] trapハンドラは再入されてはいけないのではないか? — Motohiro KOSAKI <kosaki.motohiro@...>

11 messages 2011/06/20

[ruby-dev:43835] Timer thread hack

From: SASADA Koichi <ko1@...>
Date: 2011-06-16 21:55:37 UTC
List: ruby-dev #43835
 ささだです.

 タイマスレッドの挙動を抑制するパッチを作成しました.もう,小崎さんのと
ころにはあるかもしれませんが,とりあえず,ってことで.

 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)

timer_thread_hack.patch (6.29 KB, text/x-diff)
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

In This Thread

Prev Next