ruby-changes:47908
From: nobu <ko1@a...>
Date: Tue, 26 Sep 2017 13:13:42 +0900 (JST)
Subject: [ruby-changes:47908] nobu:r60027 (trunk): Release gvl while doing (f)stat
nobu 2017-09-26 13:13:37 +0900 (Tue, 26 Sep 2017) New Revision: 60027 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60027 Log: 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@w...> at [ruby-core:83012], with using `rb_thread_io_blocking_region` for `fstat`. [Bug #13941] Modified files: trunk/common.mk trunk/file.c Index: common.mk =================================================================== --- common.mk (revision 60026) +++ common.mk (revision 60027) @@ -1757,6 +1757,7 @@ file.$(OBJEXT): {$(VPATH)}onigmo.h https://github.com/ruby/ruby/blob/trunk/common.mk#L1757 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 Index: file.c =================================================================== --- file.c (revision 60026) +++ file.c (revision 60027) @@ -27,6 +27,7 @@ https://github.com/ruby/ruby/blob/trunk/file.c#L27 #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) https://github.com/ruby/ruby/blob/trunk/file.c#L1023 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/