diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-28 00:35:22 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-28 00:35:22 +0000 |
commit | e432c526261848120b3f66c46e06bd2a4265c9bb (patch) | |
tree | e368dd5e6b164917caa8406f98b7a47b65832f24 /io.c | |
parent | 42cb4feda167bcab52d6d1d95f45c48b3eb62723 (diff) |
io.c: reduce IO.copy_stream stack usage on Linux
nogvl_copy_file_range and nogvl_copy_stream_sendfile each
used 344 bytes of stack before this change. Now, they are
inlined into nogvl_copy_stream_func which only uses 200 bytes
of stack.
"struct stat" is 144 bytes on my 64-bit Linux.
Note: this doesn't affect GC (yet) since GVL is released;
but increases safety if called from deep machine stacks.
It will affect GC if Thread::Light is merged.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 32 |
1 files changed, 17 insertions, 15 deletions
@@ -10848,22 +10848,23 @@ simple_copy_file_range(int in_fd, off_t *in_offset, int out_fd, off_t *out_offse static int nogvl_copy_file_range(struct copy_stream_struct *stp) { - struct stat src_stat, dst_stat; + struct stat sb; ssize_t ss; + off_t src_size; int ret; - off_t copy_length, src_offset, *src_offset_ptr; - ret = fstat(stp->src_fd, &src_stat); + ret = fstat(stp->src_fd, &sb); if (ret == -1) { stp->syserr = "fstat"; stp->error_no = errno; return -1; } - if (!S_ISREG(src_stat.st_mode)) + if (!S_ISREG(sb.st_mode)) return 0; - ret = fstat(stp->dst_fd, &dst_stat); + src_size = sb.st_size; + ret = fstat(stp->dst_fd, &sb); if (ret == -1) { stp->syserr = "fstat"; stp->error_no = errno; @@ -10889,10 +10890,10 @@ nogvl_copy_file_range(struct copy_stream_struct *stp) stp->error_no = errno; return -1; } - copy_length = src_stat.st_size - current_offset; + copy_length = src_size - current_offset; } else { - copy_length = src_stat.st_size - src_offset; + copy_length = src_size - src_offset; } } @@ -11003,31 +11004,32 @@ simple_sendfile(int out_fd, int in_fd, off_t *offset, off_t count) static int nogvl_copy_stream_sendfile(struct copy_stream_struct *stp) { - struct stat src_stat, dst_stat; + struct stat sb; ssize_t ss; int ret; - + off_t src_size; off_t copy_length; off_t src_offset; int use_pread; - ret = fstat(stp->src_fd, &src_stat); + ret = fstat(stp->src_fd, &sb); if (ret == -1) { stp->syserr = "fstat"; stp->error_no = errno; return -1; } - if (!S_ISREG(src_stat.st_mode)) + if (!S_ISREG(sb.st_mode)) return 0; - ret = fstat(stp->dst_fd, &dst_stat); + src_size = sb.st_size; + ret = fstat(stp->dst_fd, &sb); if (ret == -1) { stp->syserr = "fstat"; stp->error_no = errno; return -1; } #ifndef __linux__ - if ((dst_stat.st_mode & S_IFMT) != S_IFSOCK) + if ((sb.st_mode & S_IFMT) != S_IFSOCK) return 0; #endif @@ -11037,7 +11039,7 @@ nogvl_copy_stream_sendfile(struct copy_stream_struct *stp) copy_length = stp->copy_length; if (copy_length == (off_t)-1) { if (use_pread) - copy_length = src_stat.st_size - src_offset; + copy_length = src_size - src_offset; else { off_t cur; errno = 0; @@ -11047,7 +11049,7 @@ nogvl_copy_stream_sendfile(struct copy_stream_struct *stp) stp->error_no = errno; return -1; } - copy_length = src_stat.st_size - cur; + copy_length = src_size - cur; } } |