Skip to content

Commit

Permalink
[libc][NFC] Add some missing comments to the RPC implementation
Browse files Browse the repository at this point in the history
Summary:
These comments were accidentally dropped from the committed version. Add
them back in.
  • Loading branch information
jhuber6 committed Mar 20, 2023
1 parent cc69d58 commit ae30ae2
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 14 deletions.
5 changes: 3 additions & 2 deletions libc/src/__support/OSUtil/gpu/io.cpp
Expand Up @@ -16,14 +16,15 @@ namespace __llvm_libc {
void write_to_stderr(const char *msg) {
uint64_t length = internal::string_length(msg) + 1;
uint64_t buffer_len = sizeof(rpc::Buffer) - sizeof(uint64_t);
for (uint64_t i = 0; i < length; i += buffer_len)
for (uint64_t i = 0; i < length; i += buffer_len) {
rpc::client.run(
[&](rpc::Buffer *buffer) {
buffer->data[0] = rpc::Opcode::PRINT_TO_STDERR;
inline_memcpy(reinterpret_cast<char *>(&buffer->data[1]), &msg[i],
(length > buffer_len ? buffer_len : length));
},
[](rpc::Buffer *) {});
[](rpc::Buffer *) { /* void */ });
}
}

} // namespace __llvm_libc
2 changes: 1 addition & 1 deletion libc/src/__support/OSUtil/gpu/quick_exit.cpp
Expand Up @@ -24,7 +24,7 @@ void quick_exit(int status) {
buffer->data[0] = rpc::Opcode::EXIT;
buffer->data[1] = status;
},
[](rpc::Buffer *) {});
[](rpc::Buffer *) { /* void */ });

#if defined(LIBC_TARGET_ARCH_IS_NVPTX)
asm("exit" ::: "memory");
Expand Down
29 changes: 19 additions & 10 deletions libc/src/__support/RPC/rpc.h
Expand Up @@ -5,6 +5,15 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements a remote procedure call mechanism to communicate between
// heterogeneous devices that can share an address space atomically. We provide
// a client and a server to facilitate the remote call. The client makes request
// to the server using a shared communication channel. We use separate atomic
// signals to indicate which side, the client or the server is in ownership of
// the buffer.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_SUPPORT_RPC_RPC_H
#define LLVM_LIBC_SRC_SUPPORT_RPC_RPC_H
Expand Down Expand Up @@ -55,7 +64,7 @@ struct Client : public Process {

/// The RPC server used to respond to the client.
struct Server : public Process {
template <typename W, typename C> bool run(W work, C clean);
template <typename W, typename C> bool handle(W work, C clean);
};

/// Run the RPC client protocol to communicate with the server. We perform the
Expand All @@ -68,27 +77,27 @@ template <typename F, typename U> void Client::run(F fill, U use) {
bool in = inbox->load(cpp::MemoryOrder::RELAXED);
bool out = outbox->load(cpp::MemoryOrder::RELAXED);
atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
// Write to buffer then to the outbox.
// Apply the \p fill to the buffer and signal the server.
if (!in & !out) {
fill(buffer);
atomic_thread_fence(cpp::MemoryOrder::RELEASE);
outbox->store(1, cpp::MemoryOrder::RELEASE);
out = 1;
}
// Wait for the result from the server.
// Wait for the server to work on the buffer and respond.
if (!in & out) {
while (!in)
in = inbox->load(cpp::MemoryOrder::RELAXED);
atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
}
// Read from the buffer and then write to outbox.
// Apply \p use to the buffer and signal the server.
if (in & out) {
use(buffer);
atomic_thread_fence(cpp::MemoryOrder::RELEASE);
outbox->store(0, cpp::MemoryOrder::RELEASE);
out = 0;
}
// Wait for server to complete the communication.
// Wait for the server to signal the end of the protocol.
if (in & !out) {
while (in)
in = inbox->load(cpp::MemoryOrder::RELAXED);
Expand All @@ -103,27 +112,27 @@ template <typename F, typename U> void Client::run(F fill, U use) {
/// - Apply \p work to the shared buffer and write 1 to the outbox.
/// - Wait until the inbox is 0.
/// - Apply \p clean to the shared buffer and write 0 to the outbox.
template <typename W, typename C> bool Server::run(W work, C clean) {
template <typename W, typename C> bool Server::handle(W work, C clean) {
bool in = inbox->load(cpp::MemoryOrder::RELAXED);
bool out = outbox->load(cpp::MemoryOrder::RELAXED);
atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
// No work to do, exit.
// There is no work to do, exit early.
if (!in & !out)
return false;
// Do work then write to the outbox.
// Apply \p work to the buffer and signal the client.
if (in & !out) {
work(buffer);
atomic_thread_fence(cpp::MemoryOrder::RELEASE);
outbox->store(1, cpp::MemoryOrder::RELEASE);
out = 1;
}
// Wait for the client to read the result.
// Wait for the client to use the buffer and respond.
if (in & out) {
while (in)
in = inbox->load(cpp::MemoryOrder::RELAXED);
atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
}
// Clean up the buffer and signal the client.
// Clean up the buffer and signal the end of the protocol.
if (!in & out) {
clean(buffer);
atomic_thread_fence(cpp::MemoryOrder::RELEASE);
Expand Down
2 changes: 1 addition & 1 deletion libc/utils/gpu/loader/amdgpu/Loader.cpp
Expand Up @@ -43,7 +43,7 @@ static __llvm_libc::rpc::Server server;
/// Queries the RPC client at least once and performs server-side work if there
/// are any active requests.
void handle_server() {
while (server.run(
while (server.handle(
[&](__llvm_libc::rpc::Buffer *buffer) {
switch (static_cast<__llvm_libc::rpc::Opcode>(buffer->data[0])) {
case __llvm_libc::rpc::Opcode::PRINT_TO_STDERR: {
Expand Down

0 comments on commit ae30ae2

Please sign in to comment.