summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-26 04:13:37 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-26 04:13:37 +0000
commit66c9d4f55e78765a3dcfbb8d56c1f36fd036c36f (patch)
treea285c8c3115093de20a4840d71c140e7ae267c1e
parentc57eb143ec15bf5e4664c2a317678f746a78846c (diff)
Release gvl while doing (f)stat
At the moment rb_stat function is blocking. This patch changes the behaviour to release the gvl while waiting for OS to return from f(stat). There is behaviour impact, but not significant (times are for 100000 iterations): $ ~/releaseruby_patch/bin/ruby bench.rb Rehearsal ------------------------------------------------ File.exist?: 0.036412 0.056616 0.093028 ( 0.093075) --------------------------------------- total: 0.093028sec user system total real File.exist?: 0.042953 0.049783 0.092736 ( 0.092804) $ ~/releaseruby_no_patch/bin/ruby bench.rb Rehearsal ------------------------------------------------ File.exist?: 0.056094 0.026293 0.082387 ( 0.082389) --------------------------------------- total: 0.082387sec user system total real File.exist?: 0.037250 0.046702 0.083952 ( 0.083956) Based on the patch by Wolf <wolf@wolfsden.cz> at [ruby-core:83012], with using `rb_thread_io_blocking_region` for `fstat`. [Bug #13941] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--common.mk1
-rw-r--r--file.c34
2 files changed, 33 insertions, 2 deletions
diff --git a/common.mk b/common.mk
index cda48c8179..39df70b3b0 100644
--- a/common.mk
+++ b/common.mk
@@ -1757,6 +1757,7 @@ file.$(OBJEXT): {$(VPATH)}onigmo.h
file.$(OBJEXT): {$(VPATH)}oniguruma.h
file.$(OBJEXT): {$(VPATH)}st.h
file.$(OBJEXT): {$(VPATH)}subst.h
+file.$(OBJEXT): {$(VPATH)}thread.h
file.$(OBJEXT): {$(VPATH)}util.h
gc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
gc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
diff --git a/file.c b/file.c
index f42d4f408c..deb666e096 100644
--- a/file.c
+++ b/file.c
@@ -27,6 +27,7 @@
#include "internal.h"
#include "ruby/io.h"
#include "ruby/util.h"
+#include "ruby/thread.h"
#include "dln.h"
#include "encindex.h"
@@ -1022,21 +1023,50 @@ rb_stat_inspect(VALUE self)
return str;
}
+typedef struct no_gvl_stat_data {
+ struct stat *st;
+ union {
+ const char *path;
+ int fd;
+ } file;
+} no_gvl_stat_data;
+
+static VALUE
+no_gvl_fstat(void *data)
+{
+ no_gvl_stat_data *arg = data;
+ return (VALUE)fstat(arg->file.fd, arg->st);
+}
+
+static void *
+no_gvl_stat(void * data)
+{
+ no_gvl_stat_data *arg = data;
+ return (void *)(VALUE)STAT(arg->file.path, arg->st);
+}
+
static int
rb_stat(VALUE file, struct stat *st)
{
VALUE tmp;
+ VALUE result;
+ no_gvl_stat_data data;
+ data.st = st;
tmp = rb_check_convert_type_with_id(file, T_FILE, "IO", idTo_io);
if (!NIL_P(tmp)) {
rb_io_t *fptr;
GetOpenFile(tmp, fptr);
- return fstat(fptr->fd, st);
+ data.file.fd = fptr->fd;
+ result = rb_thread_io_blocking_region(no_gvl_fstat, &data, fptr->fd);
+ return (int)result;
}
FilePathValue(file);
file = rb_str_encode_ospath(file);
- return STAT(StringValueCStr(file), st);
+ data.file.path = StringValueCStr(file);
+ result = (VALUE)rb_thread_call_without_gvl(no_gvl_stat, &data, RUBY_UBF_IO, NULL);
+ return (int)result;
}
#ifdef _WIN32