mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
c57eb143ec
commit
66c9d4f55e
2 changed files with 33 additions and 2 deletions
|
@ -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
|
||||
|
|
34
file.c
34
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue