[libc-commits] [libc] 31d4f06 - [libc][NFC] Cleanup the GPU file I/O utility header (#65680)

via libc-commits libc-commits at lists.llvm.org
Fri Sep 8 12:15:56 PDT 2023


Author: Joseph Huber
Date: 2023-09-08T14:15:53-05:00
New Revision: 31d4f0692f690cff30d50eeb46513f8c9c9eb720

URL: https://github.com/llvm/llvm-project/commit/31d4f0692f690cff30d50eeb46513f8c9c9eb720
DIFF: https://github.com/llvm/llvm-project/commit/31d4f0692f690cff30d50eeb46513f8c9c9eb720.diff

LOG: [libc][NFC] Cleanup the GPU file I/O utility header (#65680)

Summary:
The GPU uses separate implementations to perform file IO. This is all
done through the RPC interface and we kept it minimal such that we could
treat a `stdin`, `stdout`, or `stderr` handle from the CPU correctly on
the GPU. The RPC implementation uses different opcodes for whether or
not we are using one of the standard streams. This is so we do not need
to initialize anything to access the CPU's standard stream, because the
server knows that it should print to `stdout` if it gets the `STDOUT`
variant of the opcode. It also saves us an RPC call, which are expensive
relatively  speaking. This patch simply cleans up this interface to make
them all use a common function. This is done in preparation to implement
some more file IO functions like getc or putc.

Added: 
    

Modified: 
    libc/src/stdio/gpu/file.h

Removed: 
    


################################################################################
diff  --git a/libc/src/stdio/gpu/file.h b/libc/src/stdio/gpu/file.h
index 0ca1df8708a3f7e..77817e070680ec9 100644
--- a/libc/src/stdio/gpu/file.h
+++ b/libc/src/stdio/gpu/file.h
@@ -1,4 +1,4 @@
-//===--- GPU helper functions--------------------===//
+//===--- GPU helper functions for file I/O using RPC ----------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -14,35 +14,17 @@
 namespace __llvm_libc {
 namespace file {
 
-LIBC_INLINE uint64_t write_to_stdout(const void *data, size_t size) {
+template <uint16_t opcode>
+LIBC_INLINE uint64_t write_impl(::FILE *file, const void *data, size_t size) {
   uint64_t ret = 0;
-  rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STDOUT>();
-  port.send_n(data, size);
-  port.recv([&](rpc::Buffer *buffer) {
-    ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
-  });
-  port.close();
-  return ret;
-}
+  rpc::Client::Port port = rpc::client.open<opcode>();
 
-LIBC_INLINE uint64_t write_to_stderr(const void *data, size_t size) {
-  uint64_t ret = 0;
-  rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STDERR>();
-  port.send_n(data, size);
-  port.recv([&](rpc::Buffer *buffer) {
-    ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
-  });
-  port.close();
-  return ret;
-}
+  if constexpr (opcode == RPC_WRITE_TO_STREAM) {
+    port.send([&](rpc::Buffer *buffer) {
+      buffer->data[0] = reinterpret_cast<uintptr_t>(file);
+    });
+  }
 
-LIBC_INLINE uint64_t write_to_stream(uintptr_t file, const void *data,
-                                     size_t size) {
-  uint64_t ret = 0;
-  rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STREAM>();
-  port.send([&](rpc::Buffer *buffer) {
-    reinterpret_cast<uintptr_t *>(buffer->data)[0] = file;
-  });
   port.send_n(data, size);
   port.recv([&](rpc::Buffer *buffer) {
     ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
@@ -51,33 +33,24 @@ LIBC_INLINE uint64_t write_to_stream(uintptr_t file, const void *data,
   return ret;
 }
 
-LIBC_INLINE uint64_t write(FILE *f, const void *data, size_t size) {
+LIBC_INLINE uint64_t write(::FILE *f, const void *data, size_t size) {
   if (f == stdout)
-    return write_to_stdout(data, size);
+    return write_impl<RPC_WRITE_TO_STDOUT>(f, data, size);
   else if (f == stderr)
-    return write_to_stderr(data, size);
+    return write_impl<RPC_WRITE_TO_STDERR>(f, data, size);
   else
-    return write_to_stream(reinterpret_cast<uintptr_t>(f), data, size);
-}
-
-LIBC_INLINE uint64_t read_from_stdin(void *buf, size_t size) {
-  uint64_t ret = 0;
-  uint64_t recv_size;
-  rpc::Client::Port port = rpc::client.open<RPC_READ_FROM_STDIN>();
-  port.send([=](rpc::Buffer *buffer) { buffer->data[0] = size; });
-  port.recv_n(&buf, &recv_size, [&](uint64_t) { return buf; });
-  port.recv([&](rpc::Buffer *buffer) { ret = buffer->data[0]; });
-  port.close();
-  return ret;
+    return write_impl<RPC_WRITE_TO_STREAM>(f, data, size);
 }
 
-LIBC_INLINE uint64_t read_from_stream(uintptr_t file, void *buf, size_t size) {
+template <uint16_t opcode>
+LIBC_INLINE uint64_t read_from_stream(::FILE *file, void *buf, size_t size) {
   uint64_t ret = 0;
   uint64_t recv_size;
-  rpc::Client::Port port = rpc::client.open<RPC_READ_FROM_STREAM>();
+  rpc::Client::Port port = rpc::client.open<opcode>();
   port.send([=](rpc::Buffer *buffer) {
     buffer->data[0] = size;
-    buffer->data[1] = file;
+    if constexpr (opcode == RPC_READ_FROM_STREAM)
+      buffer->data[1] = reinterpret_cast<uintptr_t>(file);
   });
   port.recv_n(&buf, &recv_size, [&](uint64_t) { return buf; });
   port.recv([&](rpc::Buffer *buffer) { ret = buffer->data[0]; });
@@ -85,11 +58,11 @@ LIBC_INLINE uint64_t read_from_stream(uintptr_t file, void *buf, size_t size) {
   return ret;
 }
 
-LIBC_INLINE uint64_t read(FILE *f, void *data, size_t size) {
+LIBC_INLINE uint64_t read(::FILE *f, void *data, size_t size) {
   if (f == stdin)
-    return read_from_stdin(data, size);
+    return read_from_stream<RPC_READ_FROM_STDIN>(f, data, size);
   else
-    return read_from_stream(reinterpret_cast<uintptr_t>(f), data, size);
+    return read_from_stream<RPC_READ_FROM_STREAM>(f, data, size);
 }
 
 } // namespace file


        


More information about the libc-commits mailing list