Skip to content

Commit b4d49fb

Browse files
authored
[libc] Remove RPC server API and use the header directly (llvm#117075)
Summary: This patch removes much of the `llvmlibc_rpc_server` interface. This pretty much deletes all of this code and just replaces it with including `rpc.h` directly. We still maintain the file to let `libc` handle the opcodes, since those depend on the `printf` impelmentation. This will need to be cleaned up more, but I don't want to put too much into a single patch.
1 parent 957c2ac commit b4d49fb

File tree

9 files changed

+344
-662
lines changed

9 files changed

+344
-662
lines changed

libc/shared/rpc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ namespace rpc {
4242
#define __scoped_atomic_thread_fence(ord, scp) __atomic_thread_fence(ord)
4343
#endif
4444

45+
/// Generic codes that can be used whem implementing the server.
46+
enum Status {
47+
SUCCESS = 0x0,
48+
ERROR = 0x1000,
49+
UNHANDLED_OPCODE = 0x1001,
50+
};
51+
4552
/// A fixed size channel used to communicate between the RPC client and server.
4653
struct Buffer {
4754
uint64_t data[8];

libc/utils/gpu/loader/Loader.h

Lines changed: 88 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "include/llvm-libc-types/rpc_opcodes_t.h"
1515
#include "include/llvm-libc-types/test_rpc_opcodes_t.h"
16+
#include "shared/rpc.h"
1617

1718
#include <cstddef>
1819
#include <cstdint>
@@ -103,129 +104,95 @@ inline void handle_error_impl(const char *file, int32_t line, const char *msg) {
103104
fprintf(stderr, "%s:%d:0: Error: %s\n", file, line, msg);
104105
exit(EXIT_FAILURE);
105106
}
106-
107-
inline void handle_error_impl(const char *file, int32_t line,
108-
rpc_status_t err) {
109-
fprintf(stderr, "%s:%d:0: Error: %d\n", file, line, err);
110-
exit(EXIT_FAILURE);
111-
}
112107
#define handle_error(X) handle_error_impl(__FILE__, __LINE__, X)
113108

114-
template <uint32_t lane_size>
115-
inline void register_rpc_callbacks(rpc_device_t device) {
116-
static_assert(lane_size == 32 || lane_size == 64, "Invalid Lane size");
117-
// Register the ping test for the `libc` tests.
118-
rpc_register_callback(
119-
device, static_cast<rpc_opcode_t>(RPC_TEST_INCREMENT),
120-
[](rpc_port_t port, void *data) {
121-
rpc_recv_and_send(
122-
port,
123-
[](rpc_buffer_t *buffer, void *data) {
124-
reinterpret_cast<uint64_t *>(buffer->data)[0] += 1;
125-
},
126-
data);
127-
},
128-
nullptr);
129-
130-
// Register the interface test callbacks.
131-
rpc_register_callback(
132-
device, static_cast<rpc_opcode_t>(RPC_TEST_INTERFACE),
133-
[](rpc_port_t port, void *data) {
134-
uint64_t cnt = 0;
135-
bool end_with_recv;
136-
rpc_recv(
137-
port,
138-
[](rpc_buffer_t *buffer, void *data) {
139-
*reinterpret_cast<bool *>(data) = buffer->data[0];
140-
},
141-
&end_with_recv);
142-
rpc_recv(
143-
port,
144-
[](rpc_buffer_t *buffer, void *data) {
145-
*reinterpret_cast<uint64_t *>(data) = buffer->data[0];
146-
},
147-
&cnt);
148-
rpc_send(
149-
port,
150-
[](rpc_buffer_t *buffer, void *data) {
151-
uint64_t &cnt = *reinterpret_cast<uint64_t *>(data);
152-
buffer->data[0] = cnt = cnt + 1;
153-
},
154-
&cnt);
155-
rpc_recv(
156-
port,
157-
[](rpc_buffer_t *buffer, void *data) {
158-
*reinterpret_cast<uint64_t *>(data) = buffer->data[0];
159-
},
160-
&cnt);
161-
rpc_send(
162-
port,
163-
[](rpc_buffer_t *buffer, void *data) {
164-
uint64_t &cnt = *reinterpret_cast<uint64_t *>(data);
165-
buffer->data[0] = cnt = cnt + 1;
166-
},
167-
&cnt);
168-
rpc_recv(
169-
port,
170-
[](rpc_buffer_t *buffer, void *data) {
171-
*reinterpret_cast<uint64_t *>(data) = buffer->data[0];
172-
},
173-
&cnt);
174-
rpc_recv(
175-
port,
176-
[](rpc_buffer_t *buffer, void *data) {
177-
*reinterpret_cast<uint64_t *>(data) = buffer->data[0];
178-
},
179-
&cnt);
180-
rpc_send(
181-
port,
182-
[](rpc_buffer_t *buffer, void *data) {
183-
uint64_t &cnt = *reinterpret_cast<uint64_t *>(data);
184-
buffer->data[0] = cnt = cnt + 1;
185-
},
186-
&cnt);
187-
rpc_send(
188-
port,
189-
[](rpc_buffer_t *buffer, void *data) {
190-
uint64_t &cnt = *reinterpret_cast<uint64_t *>(data);
191-
buffer->data[0] = cnt = cnt + 1;
192-
},
193-
&cnt);
194-
if (end_with_recv)
195-
rpc_recv(
196-
port,
197-
[](rpc_buffer_t *buffer, void *data) {
198-
*reinterpret_cast<uint64_t *>(data) = buffer->data[0];
199-
},
200-
&cnt);
201-
else
202-
rpc_send(
203-
port,
204-
[](rpc_buffer_t *buffer, void *data) {
205-
uint64_t &cnt = *reinterpret_cast<uint64_t *>(data);
206-
buffer->data[0] = cnt = cnt + 1;
207-
},
208-
&cnt);
209-
},
210-
nullptr);
211-
212-
// Register the stream test handler.
213-
rpc_register_callback(
214-
device, static_cast<rpc_opcode_t>(RPC_TEST_STREAM),
215-
[](rpc_port_t port, void *data) {
216-
uint64_t sizes[lane_size] = {0};
217-
void *dst[lane_size] = {nullptr};
218-
rpc_recv_n(
219-
port, dst, sizes,
220-
[](uint64_t size, void *) -> void * { return new char[size]; },
221-
nullptr);
222-
rpc_send_n(port, dst, sizes);
223-
for (uint64_t i = 0; i < lane_size; ++i) {
224-
if (dst[i])
225-
delete[] reinterpret_cast<uint8_t *>(dst[i]);
226-
}
227-
},
228-
nullptr);
109+
template <uint32_t num_lanes, typename Alloc, typename Free>
110+
inline uint32_t handle_server(rpc::Server &server, uint32_t index,
111+
Alloc &&alloc, Free &&free) {
112+
auto port = server.try_open(num_lanes, index);
113+
if (!port)
114+
return 0;
115+
index = port->get_index() + 1;
116+
117+
int status = rpc::SUCCESS;
118+
switch (port->get_opcode()) {
119+
case RPC_TEST_INCREMENT: {
120+
port->recv_and_send([](rpc::Buffer *buffer, uint32_t) {
121+
reinterpret_cast<uint64_t *>(buffer->data)[0] += 1;
122+
});
123+
break;
124+
}
125+
case RPC_TEST_INTERFACE: {
126+
bool end_with_recv;
127+
uint64_t cnt;
128+
port->recv([&](rpc::Buffer *buffer, uint32_t) {
129+
end_with_recv = buffer->data[0];
130+
});
131+
port->recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
132+
port->send([&](rpc::Buffer *buffer, uint32_t) {
133+
buffer->data[0] = cnt = cnt + 1;
134+
});
135+
port->recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
136+
port->send([&](rpc::Buffer *buffer, uint32_t) {
137+
buffer->data[0] = cnt = cnt + 1;
138+
});
139+
port->recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
140+
port->recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
141+
port->send([&](rpc::Buffer *buffer, uint32_t) {
142+
buffer->data[0] = cnt = cnt + 1;
143+
});
144+
port->send([&](rpc::Buffer *buffer, uint32_t) {
145+
buffer->data[0] = cnt = cnt + 1;
146+
});
147+
if (end_with_recv)
148+
port->recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
149+
else
150+
port->send([&](rpc::Buffer *buffer, uint32_t) {
151+
buffer->data[0] = cnt = cnt + 1;
152+
});
153+
154+
break;
155+
}
156+
case RPC_TEST_STREAM: {
157+
uint64_t sizes[num_lanes] = {0};
158+
void *dst[num_lanes] = {nullptr};
159+
port->recv_n(dst, sizes,
160+
[](uint64_t size) -> void * { return new char[size]; });
161+
port->send_n(dst, sizes);
162+
for (uint64_t i = 0; i < num_lanes; ++i) {
163+
if (dst[i])
164+
delete[] reinterpret_cast<uint8_t *>(dst[i]);
165+
}
166+
break;
167+
}
168+
case RPC_TEST_NOOP: {
169+
port->recv([&](rpc::Buffer *, uint32_t) {});
170+
break;
171+
}
172+
case RPC_MALLOC: {
173+
port->recv_and_send([&](rpc::Buffer *buffer, uint32_t) {
174+
buffer->data[0] = reinterpret_cast<uintptr_t>(alloc(buffer->data[0]));
175+
});
176+
break;
177+
}
178+
case RPC_FREE: {
179+
port->recv([&](rpc::Buffer *buffer, uint32_t) {
180+
free(reinterpret_cast<void *>(buffer->data[0]));
181+
});
182+
break;
183+
}
184+
default:
185+
status = libc_handle_rpc_port(&*port, num_lanes);
186+
break;
187+
}
188+
189+
// Handle all of the `libc` specific opcodes.
190+
if (status != rpc::SUCCESS)
191+
handle_error("Error handling RPC server");
192+
193+
port->close();
194+
195+
return index;
229196
}
230197

231198
#endif

0 commit comments

Comments
 (0)