about summary refs log tree commit diff
path: root/src/libstd/rt/uv
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-25 10:36:09 -0700
committerbors <bors@rust-lang.org>2013-10-25 10:36:09 -0700
commitbaeed886aa64943ad48121cc3b57dabec12bc835 (patch)
tree28ba7cc4b0c36636e884dd6c45fcd612b25e2b37 /src/libstd/rt/uv
parentdeeca5d586bfaa4aa60246f671a8d611d38f6248 (diff)
parente8f72c38f4bf74e7291043917fdd0bae1404b407 (diff)
auto merge of #10060 : alexcrichton/rust/cached-stdout, r=brson
Almost all languages provide some form of buffering of the stdout stream, and
this commit adds this feature for rust. A handle to stdout is lazily initialized
in the Task structure as a buffered owned Writer trait object. The buffer
behavior depends on where stdout is directed to. Like C, this line-buffers the
stream when the output goes to a terminal (flushes on newlines), and also like C
this uses a fixed-size buffer when output is not directed at a terminal.

We may decide the fixed-size buffering is overkill, but it certainly does reduce
write syscall counts when piping output elsewhere. This is a *huge* benefit to
any code using logging macros or the printing macros. Formatting emits calls to
`write` very frequently, and to have each of them backed by a write syscall was
very expensive.

In a local benchmark of printing 10000 lines of "what" to stdout, I got the
following timings:

  when |  terminal   |  redirected
----------|---------------|--------
before |  0.575s     |   0.525s
after  |  0.197s     |   0.013s
  C    |  0.019s     |   0.004s

I can also confirm that we're buffering the output appropriately in both
situtations. We're still far slower than C, but I believe much of that has to do
with the "homing" that all tasks due, we're still performing an order of
magnitude more write syscalls than C does.
Diffstat (limited to 'src/libstd/rt/uv')
-rw-r--r--src/libstd/rt/uv/uvio.rs2
-rw-r--r--src/libstd/rt/uv/uvll.rs5
2 files changed, 4 insertions, 3 deletions
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index eee89365fb5..6709f0bff44 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -1782,7 +1782,7 @@ impl RtioTTY for UvTTY {
     }
 
     fn isatty(&self) -> bool {
-        unsafe { uvll::guess_handle(self.fd) == uvll::UV_TTY }
+        unsafe { uvll::guess_handle(self.fd) == uvll::UV_TTY as c_int }
     }
 }
 
diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs
index 75e6a0c6ca5..18e95c8966e 100644
--- a/src/libstd/rt/uv/uvll.rs
+++ b/src/libstd/rt/uv/uvll.rs
@@ -977,7 +977,8 @@ pub unsafe fn tty_get_winsize(tty: *uv_tty_t, width: *c_int,
     #[fixed_stack_segment]; #[inline(never)];
     rust_uv_tty_get_winsize(tty, width, height)
 }
-pub unsafe fn guess_handle(fd: c_int) -> uv_handle_type {
+// FIXME(#9613) this should return uv_handle_type, not a c_int
+pub unsafe fn guess_handle(fd: c_int) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
     rust_uv_guess_handle(fd)
 }
@@ -1148,7 +1149,7 @@ extern {
     fn rust_uv_tty_set_mode(tty: *uv_tty_t, mode: c_int) -> c_int;
     fn rust_uv_tty_get_winsize(tty: *uv_tty_t, width: *c_int,
                                height: *c_int) -> c_int;
-    fn rust_uv_guess_handle(fd: c_int) -> uv_handle_type;
+    fn rust_uv_guess_handle(fd: c_int) -> c_int;
 
     // XXX: see comments in addrinfo.rs
     // These should all really be constants...