summaryrefslogtreecommitdiff
path: root/thread_sync.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-25 06:58:35 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-25 06:58:35 +0000
commitb0253a7569ffbf58fd3a61500aacd7369cce36dd (patch)
treee346ca1c7085143ad0ba9f1d167d1fe4b5ce394c /thread_sync.c
parent7c31c2738c7d02e5a9ac6167c650cb8a5411321d (diff)
thread.c: use rb_hrtime_t scalar for high-resolution time operations
Relying on "struct timespec" was too annoying API-wise and used more stack space. "double" was a bit wacky w.r.t rounding in the past, so now we'll switch to using a 64-bit type. Unsigned 64-bit integer is able to give us over nearly 585 years of range with nanoseconds. This range is good enough for the Linux kernel internal time representation, so it ought to be good enough for us. This reduces the stack usage of functions while GVL is held (and thus subject to marking) on x86-64 Linux (with ppoll): rb_wait_for_single_fd 120 => 104 do_select 120 => 88 [ruby-core:88582] [Misc #15014] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64533 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread_sync.c')
-rw-r--r--thread_sync.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/thread_sync.c b/thread_sync.c
index 76632ebe5f..4ed559ad67 100644
--- a/thread_sync.c
+++ b/thread_sync.c
@@ -248,8 +248,8 @@ do_mutex_lock(VALUE self, int interruptible_p)
while (mutex->th != th) {
enum rb_thread_status prev_status = th->status;
- struct timespec *timeout = 0;
- struct timespec ts = { 0, 100000000 }; /* 100ms */
+ rb_hrtime_t *timeout = 0;
+ rb_hrtime_t rel = rb_msec2hrtime(100);
th->status = THREAD_STOPPED_FOREVER;
th->locking_mutex = self;
@@ -261,7 +261,7 @@ do_mutex_lock(VALUE self, int interruptible_p)
*/
if ((vm_living_thread_num(th->vm) == th->vm->sleeper) &&
!patrol_thread) {
- timeout = &ts;
+ timeout = &rel;
patrol_thread = th;
}
@@ -458,8 +458,9 @@ rb_mutex_sleep_forever(VALUE time)
static VALUE
rb_mutex_wait_for(VALUE time)
{
- struct timespec *t = (struct timespec*)time;
- sleep_timespec(GET_THREAD(), *t, 0); /* permit spurious check */
+ rb_hrtime_t *rel = (rb_hrtime_t *)time;
+ /* permit spurious check */
+ sleep_hrtime(GET_THREAD(), *rel, 0);
return Qnil;
}
@@ -472,16 +473,17 @@ rb_mutex_sleep(VALUE self, VALUE timeout)
if (!NIL_P(timeout)) {
t = rb_time_interval(timeout);
}
+
rb_mutex_unlock(self);
beg = time(0);
if (NIL_P(timeout)) {
rb_ensure(rb_mutex_sleep_forever, Qnil, mutex_lock_uninterruptible, self);
}
else {
- struct timespec ts;
- VALUE tsp = (VALUE)timespec_for(&ts, &t);
+ rb_hrtime_t rel = rb_timeval2hrtime(&t);
- rb_ensure(rb_mutex_wait_for, tsp, mutex_lock_uninterruptible, self);
+ rb_ensure(rb_mutex_wait_for, (VALUE)&rel,
+ mutex_lock_uninterruptible, self);
}
RUBY_VM_CHECK_INTS_BLOCKING(GET_EC());
end = time(0) - beg;