diff options
| author | Rui Ueyama <ruiu@google.com> | 2017-10-31 17:37:20 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2017-10-31 17:37:20 +0000 |
| commit | 412b29e4ed2aa2d62ef6e5abfc269ff265dc0d85 (patch) | |
| tree | fffc5eb46d288de193fa2176475b29f6bffb4bb4 /llvm/lib/Support/raw_ostream.cpp | |
| parent | 50baa593f1b5bcc014e855b81f0936190b12a9b4 (diff) | |
| download | bcm5719-llvm-412b29e4ed2aa2d62ef6e5abfc269ff265dc0d85.tar.gz bcm5719-llvm-412b29e4ed2aa2d62ef6e5abfc269ff265dc0d85.zip | |
[Support] Make the default chunk size of raw_fd_ostream to 1 GiB.
Previously, we call write(2) for each 32767 byte chunk. That is not
efficient because Linux can handle much larger write requests.
This patch changes the chunk size on Linux to 1 GiB.
This patch also changes the default chunks size to SSIZE_MAX. I think
that doesn't in practice change this function's behavior on any operating
system because SSIZE_MAX on 64-bit machine is unrealistically large,
and writing 2 GiB (SSIZE_MAX on 32-bit) on a 32-bit machine by a single
call of write(2) is also unrealistic, as the userspace is usually
limited to 2 GiB. That said, it is in general a good thing to do because
a write larger than SSIZE_MAX is implementation-defined in POSIX.
Differential Revision: https://reviews.llvm.org/D39444
llvm-svn: 317015
Diffstat (limited to 'llvm/lib/Support/raw_ostream.cpp')
| -rw-r--r-- | llvm/lib/Support/raw_ostream.cpp | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index d6b958d1844..e0261110308 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -578,24 +578,25 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { assert(FD >= 0 && "File already closed."); pos += Size; -#ifndef LLVM_ON_WIN32 + // The maximum write size is limited to SSIZE_MAX because a write + // greater than SSIZE_MAX is implementation-defined in POSIX. + // Since SSIZE_MAX is not portable, we use SIZE_MAX >> 1 instead. + size_t MaxWriteSize = SIZE_MAX >> 1; + #if defined(__linux__) - bool ShouldWriteInChunks = true; -#else - bool ShouldWriteInChunks = false; -#endif -#else + // It is observed that Linux returns EINVAL for a very large write (>2G). + // Make it a reasonably small value. + MaxWriteSize = 1024 * 1024 * 1024; +#elif defined(LLVM_ON_WIN32) // Writing a large size of output to Windows console returns ENOMEM. It seems // that, prior to Windows 8, WriteFile() is redirecting to WriteConsole(), and // the latter has a size limit (66000 bytes or less, depending on heap usage). - bool ShouldWriteInChunks = !!::_isatty(FD) && !RunningWindows8OrGreater(); + if (::_isatty(FD) && !RunningWindows8OrGreater()) + MaxWriteSize = 32767; #endif do { - size_t ChunkSize = Size; - if (ChunkSize > 32767 && ShouldWriteInChunks) - ChunkSize = 32767; - + size_t ChunkSize = std::min(Size, MaxWriteSize); ssize_t ret = ::write(FD, Ptr, ChunkSize); if (ret < 0) { |

