summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-09 13:41:19 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-09 13:41:19 +0000
commita14682906f063617ce22969dd100a512fe63ba33 (patch)
treeb27897d65ee8f8da1987de36125d64842dfecc06
parent6372357ad51ccbf909d36c6516229d3be0f30043 (diff)
* thread.c (sleep_forever): wait until timed out. [ruby-core:17270]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17976 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog9
-rw-r--r--thread.c40
-rw-r--r--thread_pthread.c17
-rw-r--r--thread_win32.c24
4 files changed, 48 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index 423dea433b..4017bd26e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,12 @@
+Wed Jul 9 22:41:16 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * thread.c (sleep_forever): wait until timed out. [ruby-core:17270]
+
Wed Jul 9 20:58:16 2008 Tanaka Akira <akr@fsij.org>
* array.c (rb_ary_fill): don't raise even if length is negative.
[ruby-core:17483], [ruby-core:17661]
-Wed Jul 9 20:36:31 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
-
- * thread_{pthread,win32}.c (native_sleep): wait until timed out.
- [ruby-core:17270]
-
Wed Jul 9 20:18:50 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in (rb_cv_va_args_macro): check for __VA_ARGS__.
diff --git a/thread.c b/thread.c
index d0787b20a2..50748a8e14 100644
--- a/thread.c
+++ b/thread.c
@@ -718,9 +718,47 @@ sleep_forever(rb_thread_t *th, int deadlockable)
}
static void
+getclockofday(struct timeval *tp)
+{
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ tp->tv_sec = ts.tv_sec;
+ tp->tv_usec = ts.tv_nsec / 1000;
+ } else
+#endif
+ {
+ gettimeofday(tp, NULL);
+ }
+}
+
+static void
sleep_timeval(rb_thread_t *th, struct timeval tv)
{
- native_sleep(th, &tv, 0);
+ struct timeval to, tvn;
+
+ getclockofday(&to);
+ to.tv_sec += tv.tv_sec;
+ if ((to.tv_usec += tv.tv_usec) >= 1000000) {
+ to.tv_sec++;
+ to.tv_usec -= 1000000;
+ }
+
+ for (;;) {
+ native_sleep(th, &tv, 0);
+ getclockofday(&tvn);
+ if (to.tv_sec < tvn.tv_sec) break;
+ if (to.tv_sec == tvn.tv_sec && to.tv_usec <= tvn.tv_usec) break;
+ thread_debug("sleep_timeval: %ld.%.6ld > %ld.%.6ld\n",
+ (long)to.tv_sec, to.tv_usec,
+ (long)tvn.tv_sec, tvn.tv_usec);
+ tv.tv_sec = to.tv_sec - tvn.tv_sec;
+ if ((tv.tv_usec = to.tv_usec - tvn.tv_usec) < 0) {
+ --tv.tv_sec;
+ tv.tv_usec += 1000000;
+ }
+ }
}
void
diff --git a/thread_pthread.c b/thread_pthread.c
index c6aca1d464..4787823b3d 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -496,7 +496,6 @@ static void
native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
{
int prev_status = th->status;
- int retry = 0;
struct timespec ts;
struct timeval tvn;
@@ -520,7 +519,6 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
}
thread_debug("native_sleep %ld\n", tv ? tv->tv_sec : -1);
- sleep_again:
GVL_UNLOCK_BEGIN();
{
pthread_mutex_lock(&th->interrupt_lock);
@@ -532,7 +530,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
thread_debug("native_sleep: interrupted before sleep\n");
}
else {
- if (tv == 0 || (!retry && ts.tv_sec < tvn.tv_sec /* overflow */)) {
+ if (tv == 0 || ts.tv_sec < tvn.tv_sec /* overflow */ ) {
int r;
thread_debug("native_sleep: pthread_cond_wait start\n");
r = pthread_cond_wait(&th->native_thread_data.sleep_cond,
@@ -542,7 +540,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
}
else {
int r;
- thread_debug("native_sleep: pthread_cond_timedwait start (%ld.%.9ld)\n",
+ thread_debug("native_sleep: pthread_cond_timedwait start (%ld, %ld)\n",
(unsigned long)ts.tv_sec, ts.tv_nsec);
r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond,
&th->interrupt_lock, &ts);
@@ -560,17 +558,6 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
th->status = prev_status;
if (!tv && deadlockable) th->vm->sleeper--;
RUBY_VM_CHECK_INTS();
- if (tv) {
- gettimeofday(&tvn, NULL);
- if (ts.tv_sec > tvn.tv_sec ||
- (ts.tv_sec == tvn.tv_sec && ts.tv_nsec > tvn.tv_usec * 1000)) {
- thread_debug("native_sleep: %ld.%.9ld > %ld.%.6ld\n",
- (long)ts.tv_sec, ts.tv_nsec,
- (long)tvn.tv_sec, tvn.tv_usec);
- retry = 1;
- goto sleep_again;
- }
- }
thread_debug("native_sleep done\n");
}
diff --git a/thread_win32.c b/thread_win32.c
index 54f7546130..a810fb3622 100644
--- a/thread_win32.c
+++ b/thread_win32.c
@@ -207,17 +207,9 @@ static void
native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
{
int prev_status = th->status;
- int retry = 0;
- DWORD msec, ret;
- struct timeval tvn, limit;
+ DWORD msec;
if (tv) {
- gettimeofday(&limit, NULL);
- limit.tv_sec += tv->tv_sec;
- if ((limit.tv_usec += tv->tv_usec) >= 1000000) {
- limit.tv_sec += limit.tv_usec / 1000000;
- limit.tv_usec %= 1000000;
- }
msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
}
else {
@@ -233,9 +225,10 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
th->status = THREAD_STOPPED;
}
- sleep_again:
GVL_UNLOCK_BEGIN();
{
+ DWORD ret;
+
native_mutex_lock(&th->interrupt_lock);
th->unblock.func = ubf_handle;
th->unblock.arg = th;
@@ -259,17 +252,6 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
th->status = prev_status;
if (!tv && deadlockable) th->vm->sleeper--;
RUBY_VM_CHECK_INTS();
- if (tv) {
- gettimeofday(&tvn, NULL);
- if (limit.tv_sec > tvn.tv_sec ||
- (limit.tv_sec == tvn.tv_sec && limit.tv_usec > tvn.tv_usec)) {
- thread_debug("native_sleep: %ld.%.6ld > %ld.%.6ld\n",
- (long)limit.tv_sec, limit.tv_usec,
- (long)tvn.tv_sec, tvn.tv_usec);
- retry = 1;
- goto sleep_again;
- }
- }
}
static int