raw_fd_ostream: Add a SetUseAtomicWrites() method (uses writev).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124771 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2011-02-03 03:32:32 +00:00
parent 3e46293c27
commit b0cfa6cab8
2 changed files with 35 additions and 3 deletions

View File

@ -301,6 +301,10 @@ class raw_fd_ostream : public raw_ostream {
///
bool Error;
/// Controls whether the stream should attempt to use atomic writes, when
/// possible.
bool UseAtomicWrites;
uint64_t pos;
/// write_impl - See raw_ostream::write_impl.
@ -361,6 +365,16 @@ public:
/// position to the offset specified from the beginning of the file.
uint64_t seek(uint64_t off);
/// SetUseAtomicWrite - Set the stream to attempt to use atomic writes for
/// individual output routines where possible.
///
/// Note that because raw_ostream's are typically buffered, this flag is only
/// sensible when used on unbuffered streams which will flush their output
/// immediately.
void SetUseAtomicWrites(bool Value) {
UseAtomicWrites = Value;
}
virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
bool bg=false);
virtual raw_ostream &resetColor();

View File

@ -32,6 +32,9 @@
#if defined(HAVE_FCNTL_H)
# include <fcntl.h>
#endif
#if defined(HAVE_SYS_UIO_H) && defined(HAVE_WRITEV)
# include <sys/uio.h>
#endif
#if defined(__CYGWIN__)
#include <io.h>
@ -375,7 +378,9 @@ void format_object_base::home() {
/// stream should be immediately destroyed; the string will be empty
/// if no error occurred.
raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
unsigned Flags) : Error(false), pos(0) {
unsigned Flags)
: Error(false), UseAtomicWrites(false), pos(0)
{
assert(Filename != 0 && "Filename is null");
// Verify that we don't have both "append" and "excl".
assert((!(Flags & F_Excl) || !(Flags & F_Append)) &&
@ -426,7 +431,7 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
/// ShouldClose is true, this closes the file when the stream is destroyed.
raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
: raw_ostream(unbuffered), FD(fd),
ShouldClose(shouldClose), Error(false) {
ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) {
#ifdef O_BINARY
// Setting STDOUT and STDERR to binary mode is necessary in Win32
// to avoid undesirable linefeed conversion.
@ -467,7 +472,20 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
pos += Size;
do {
ssize_t ret = ::write(FD, Ptr, Size);
ssize_t ret;
// Check whether we should attempt to use atomic writes.
if (BUILTIN_EXPECT(!UseAtomicWrites, true)) {
ret = ::write(FD, Ptr, Size);
} else {
// Use ::writev() where available.
#if defined(HAVE_WRITEV)
struct iovec IOV = { (void*) Ptr, Size };
ret = ::writev(FD, &IOV, 1);
#else
ret = ::write(FD, Ptr, Size);
#endif
}
if (ret < 0) {
// If it's a recoverable error, swallow it and retry the write.