1 | //===-- Shared memory RPC server instantiation ------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_LIBC_UTILS_GPU_SERVER_RPC_SERVER_H |
10 | #define LLVM_LIBC_UTILS_GPU_SERVER_RPC_SERVER_H |
11 | |
12 | #include <stdint.h> |
13 | |
14 | #ifdef __cplusplus |
15 | extern "C" { |
16 | #endif |
17 | |
18 | /// The maximum number of ports that can be opened for any server. |
19 | const uint64_t RPC_MAXIMUM_PORT_COUNT = 4096; |
20 | |
21 | /// The symbol name associated with the client for use with the LLVM C library |
22 | /// implementation. |
23 | const char *const rpc_client_symbol_name = "__llvm_libc_rpc_client" ; |
24 | |
25 | /// status codes. |
26 | typedef enum { |
27 | RPC_STATUS_SUCCESS = 0x0, |
28 | RPC_STATUS_CONTINUE = 0x1, |
29 | RPC_STATUS_ERROR = 0x1000, |
30 | RPC_STATUS_UNHANDLED_OPCODE = 0x1001, |
31 | RPC_STATUS_INVALID_LANE_SIZE = 0x1002, |
32 | } rpc_status_t; |
33 | |
34 | /// A struct containing an opaque handle to an RPC port. This is what allows the |
35 | /// server to communicate with the client. |
36 | typedef struct rpc_port_s { |
37 | uint64_t handle; |
38 | uint32_t lane_size; |
39 | } rpc_port_t; |
40 | |
41 | /// A fixed-size buffer containing the payload sent from the client. |
42 | typedef struct rpc_buffer_s { |
43 | uint64_t data[8]; |
44 | } rpc_buffer_t; |
45 | |
46 | /// An opaque handle to an RPC server that can be attached to a device. |
47 | typedef struct rpc_device_s { |
48 | uintptr_t handle; |
49 | } rpc_device_t; |
50 | |
51 | /// A function used to allocate \p bytes for use by the RPC server and client. |
52 | /// The memory should support asynchronous and atomic access from both the |
53 | /// client and server. |
54 | typedef void *(*rpc_alloc_ty)(uint64_t size, void *data); |
55 | |
56 | /// A function used to free the \p ptr previously allocated. |
57 | typedef void (*rpc_free_ty)(void *ptr, void *data); |
58 | |
59 | /// A callback function provided with a \p port to communicate with the RPC |
60 | /// client. This will be called by the server to handle an opcode. |
61 | typedef void (*rpc_opcode_callback_ty)(rpc_port_t port, void *data); |
62 | |
63 | /// A callback function to use the port to receive or send a \p buffer. |
64 | typedef void (*rpc_port_callback_ty)(rpc_buffer_t *buffer, void *data); |
65 | |
66 | /// Initialize the server for a given device and return it in \p device. |
67 | rpc_status_t rpc_server_init(rpc_device_t *rpc_device, uint64_t num_ports, |
68 | uint32_t lane_size, rpc_alloc_ty alloc, |
69 | void *data); |
70 | |
71 | /// Shut down the server for a given device. |
72 | rpc_status_t rpc_server_shutdown(rpc_device_t rpc_device, rpc_free_ty dealloc, |
73 | void *data); |
74 | |
75 | /// Queries the RPC clients at least once and performs server-side work if there |
76 | /// are any active requests. Runs until all work on the server is completed. |
77 | rpc_status_t rpc_handle_server(rpc_device_t rpc_device); |
78 | |
79 | /// Register a callback to handle an opcode from the RPC client. The associated |
80 | /// data must remain accessible as long as the user intends to handle the server |
81 | /// with this callback. |
82 | rpc_status_t rpc_register_callback(rpc_device_t rpc_device, uint16_t opcode, |
83 | rpc_opcode_callback_ty callback, void *data); |
84 | |
85 | /// Obtain a pointer to a local client buffer that can be copied directly to the |
86 | /// other process using the address stored at the rpc client symbol name. |
87 | const void *rpc_get_client_buffer(rpc_device_t device); |
88 | |
89 | /// Returns the size of the client in bytes to be used for a memory copy. |
90 | uint64_t rpc_get_client_size(); |
91 | |
92 | /// Use the \p port to send a buffer using the \p callback. |
93 | void rpc_send(rpc_port_t port, rpc_port_callback_ty callback, void *data); |
94 | |
95 | /// Use the \p port to send \p bytes using the \p callback. The input is an |
96 | /// array of at least the configured lane size. |
97 | void rpc_send_n(rpc_port_t port, const void *const *src, uint64_t *size); |
98 | |
99 | /// Use the \p port to recieve a buffer using the \p callback. |
100 | void rpc_recv(rpc_port_t port, rpc_port_callback_ty callback, void *data); |
101 | |
102 | /// Use the \p port to recieve \p bytes using the \p callback. The inputs is an |
103 | /// array of at least the configured lane size. The \p alloc function allocates |
104 | /// memory for the recieved bytes. |
105 | void rpc_recv_n(rpc_port_t port, void **dst, uint64_t *size, rpc_alloc_ty alloc, |
106 | void *data); |
107 | |
108 | /// Use the \p port to receive and send a buffer using the \p callback. |
109 | void rpc_recv_and_send(rpc_port_t port, rpc_port_callback_ty callback, |
110 | void *data); |
111 | |
112 | #ifdef __cplusplus |
113 | } |
114 | #endif |
115 | |
116 | #endif |
117 | |