diff options
| author | Joseph Huber <35342157+jhuber6@users.noreply.github.com> | 2023-10-19 17:00:01 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-19 17:00:01 -0400 |
| commit | a39215768b58bb39716820959cedf82c76648770 (patch) | |
| tree | e29c443194ccda2529a317150dd0355ee25000cd /libc/src/stdio/gpu | |
| parent | 049993eae6bef539ac4bca7ddeede78282e496d9 (diff) | |
[libc] Rework the 'fgets' implementation on the GPU (#69635)
Summary:
The `fgets` function as implemented is not functional currently when
called with multiple threads. This is because we rely on reapeatedly
polling the character to detect EOF. This doesn't work when there are
multiple threads that may with to poll the characters. this patch pulls
out the logic into a standalone RPC call to handle this in a single
operation such that calling it from multiple threads functions as
expected. It also makes it less slow because we no longer make N RPC
calls for N characters.
Diffstat (limited to 'libc/src/stdio/gpu')
| -rw-r--r-- | libc/src/stdio/gpu/fgets.cpp | 28 |
1 files changed, 12 insertions, 16 deletions
diff --git a/libc/src/stdio/gpu/fgets.cpp b/libc/src/stdio/gpu/fgets.cpp index 4cabd15001a7..5ea4bdcdc9e0 100644 --- a/libc/src/stdio/gpu/fgets.cpp +++ b/libc/src/stdio/gpu/fgets.cpp @@ -22,24 +22,20 @@ LLVM_LIBC_FUNCTION(char *, fgets, if (count < 1) return nullptr; - // This implementation is very slow as it makes multiple RPC calls. - unsigned char c = '\0'; - int i = 0; - for (; i < count - 1 && c != '\n'; ++i) { - auto r = file::read(stream, &c, 1); - if (r != 1) - break; - - str[i] = c; - } - - bool has_error = LIBC_NAMESPACE::ferror(stream); - bool has_eof = LIBC_NAMESPACE::feof(stream); - - if (has_error || (i == 0 && has_eof)) + uint64_t recv_size; + void *buf = nullptr; + rpc::Client::Port port = rpc::client.open<RPC_READ_FGETS>(); + port.send([=](rpc::Buffer *buffer) { + buffer->data[0] = count; + buffer->data[1] = file::from_stream(stream); + }); + port.recv_n(&buf, &recv_size, + [&](uint64_t) { return reinterpret_cast<void *>(str); }); + port.close(); + + if (recv_size == 0) return nullptr; - str[i] = '\0'; return str; } |
