5
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
+ //
9
+ // This file is intended to be used externally as part of the `shared/`
10
+ // interface. For that purpose, we manually define a few options normally
11
+ // handled by the libc build system.
12
+ //
13
+ // ===----------------------------------------------------------------------===//
14
+
15
+ #ifndef LLVM_LIBC_SRC___SUPPORT_RPC_RPC_SERVER_H
16
+ #define LLVM_LIBC_SRC___SUPPORT_RPC_RPC_SERVER_H
8
17
9
18
// Workaround for missing __has_builtin in < GCC 10.
10
19
#ifndef __has_builtin
11
20
#define __has_builtin (x ) 0
12
21
#endif
13
22
23
+ // Configs for using the LLVM libc writer interface.
24
+ #define LIBC_COPT_USE_C_ASSERT
25
+ #define LIBC_COPT_MEMCPY_USE_EMBEDDED_TINY
26
+ #define LIBC_COPT_ARRAY_ARG_LIST
27
+ #define LIBC_COPT_PRINTF_DISABLE_WRITE_INT
28
+ #define LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
29
+ #define LIBC_COPT_PRINTF_DISABLE_STRERROR
30
+
31
+ // The 'long double' type is 8 byte
32
+ #define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
33
+
14
34
#include " shared/rpc.h"
15
35
#include " shared/rpc_opcodes.h"
16
36
17
- #include " src/__support/CPP/type_traits.h"
18
37
#include " src/__support/arg_list.h"
19
38
#include " src/stdio/printf_core/converter.h"
20
39
#include " src/stdio/printf_core/parser.h"
21
40
#include " src/stdio/printf_core/writer.h"
22
41
23
- #include < stdio.h >
24
- #include < stdlib.h >
42
+ #include " hdr/stdio_overlay.h "
43
+ #include " hdr/stdlib_overlay.h "
25
44
26
- namespace LIBC_NAMESPACE {
45
+ namespace LIBC_NAMESPACE_DECL {
46
+ namespace internal {
27
47
28
48
// Minimal replacement for 'std::vector' that works for trivial types.
29
49
template <typename T> class TempVector {
@@ -35,68 +55,66 @@ template <typename T> class TempVector {
35
55
size_t capacity;
36
56
37
57
public:
38
- TempVector () : data(nullptr ), current(0 ), capacity(0 ) {}
58
+ LIBC_INLINE TempVector () : data(nullptr ), current(0 ), capacity(0 ) {}
39
59
40
- ~TempVector () { free (data); }
60
+ LIBC_INLINE ~TempVector () { free (data); }
41
61
42
- void push_back (const T &value) {
62
+ LIBC_INLINE void push_back (const T &value) {
43
63
if (current == capacity)
44
64
grow ();
45
65
data[current] = T (value);
46
66
++current;
47
67
}
48
68
49
- void push_back (T &&value) {
69
+ LIBC_INLINE void push_back (T &&value) {
50
70
if (current == capacity)
51
71
grow ();
52
72
data[current] = T (static_cast <T &&>(value));
53
73
++current;
54
74
}
55
75
56
- void pop_back () { --current; }
76
+ LIBC_INLINE void pop_back () { --current; }
57
77
58
- bool empty () { return current == 0 ; }
78
+ LIBC_INLINE bool empty () { return current == 0 ; }
59
79
60
- size_t size () { return current; }
80
+ LIBC_INLINE size_t size () { return current; }
61
81
62
- T &operator [](size_t index) { return data[index ]; }
82
+ LIBC_INLINE T &operator [](size_t index) { return data[index ]; }
63
83
64
- T &back () { return data[current - 1 ]; }
84
+ LIBC_INLINE T &back () { return data[current - 1 ]; }
65
85
66
86
private:
67
- void grow () {
87
+ LIBC_INLINE void grow () {
68
88
size_t new_capacity = capacity ? capacity * 2 : 1 ;
69
89
void *new_data = realloc (data, new_capacity * sizeof (T));
70
- if (!new_data)
71
- abort ();
72
90
data = static_cast <T *>(new_data);
73
91
capacity = new_capacity;
74
92
}
75
93
};
76
94
77
95
struct TempStorage {
78
- char *alloc (size_t size) {
96
+ LIBC_INLINE char *alloc (size_t size) {
79
97
storage.push_back (reinterpret_cast <char *>(malloc (size)));
80
98
return storage.back ();
81
99
}
82
100
83
- ~TempStorage () {
101
+ LIBC_INLINE ~TempStorage () {
84
102
for (size_t i = 0 ; i < storage.size (); ++i)
85
103
free (storage[i]);
86
104
}
87
105
88
106
TempVector<char *> storage;
89
107
};
90
108
91
- enum Stream {
92
- File = 0 ,
93
- Stdin = 1 ,
94
- Stdout = 2 ,
95
- Stderr = 3 ,
96
- };
97
-
98
109
// Get the associated stream out of an encoded number.
99
- LIBC_INLINE ::FILE *to_stream (uintptr_t f) {
110
+ LIBC_INLINE static ::FILE *to_stream (uintptr_t f) {
111
+ enum Stream {
112
+ File = 0 ,
113
+ Stdin = 1 ,
114
+ Stdout = 2 ,
115
+ Stderr = 3 ,
116
+ };
117
+
100
118
::FILE *stream = reinterpret_cast <FILE *>(f & ~0x3ull );
101
119
Stream type = static_cast <Stream>(f & 0x3ull );
102
120
if (type == Stdin)
@@ -109,7 +127,8 @@ LIBC_INLINE ::FILE *to_stream(uintptr_t f) {
109
127
}
110
128
111
129
template <bool packed, uint32_t num_lanes>
112
- static void handle_printf (rpc::Server::Port &port, TempStorage &temp_storage) {
130
+ LIBC_INLINE static void handle_printf (rpc::Server::Port &port,
131
+ TempStorage &temp_storage) {
113
132
FILE *files[num_lanes] = {nullptr };
114
133
// Get the appropriate output stream to use.
115
134
if (port.get_opcode () == LIBC_PRINTF_TO_STREAM ||
@@ -268,7 +287,8 @@ static void handle_printf(rpc::Server::Port &port, TempStorage &temp_storage) {
268
287
}
269
288
}
270
289
271
- results[lane] = fwrite (buffer, 1 , writer.get_chars_written (), files[lane]);
290
+ results[lane] = static_cast <int >(
291
+ fwrite (buffer, 1 , writer.get_chars_written (), files[lane]));
272
292
if (results[lane] != writer.get_chars_written () || ret == -1 )
273
293
results[lane] = -1 ;
274
294
}
@@ -282,7 +302,7 @@ static void handle_printf(rpc::Server::Port &port, TempStorage &temp_storage) {
282
302
}
283
303
284
304
template <uint32_t num_lanes>
285
- rpc::Status handle_port_impl (rpc::Server::Port &port) {
305
+ LIBC_INLINE static rpc::Status handle_port_impl (rpc::Server::Port &port) {
286
306
TempStorage temp_storage;
287
307
288
308
switch (port.get_opcode ()) {
@@ -333,8 +353,9 @@ rpc::Status handle_port_impl(rpc::Server::Port &port) {
333
353
void *data[num_lanes] = {nullptr };
334
354
port.recv ([&](rpc::Buffer *buffer, uint32_t id) {
335
355
data[id] = temp_storage.alloc (buffer->data [0 ]);
336
- const char *str = fgets (reinterpret_cast <char *>(data[id]),
337
- buffer->data [0 ], to_stream (buffer->data [1 ]));
356
+ const char *str = ::fgets (reinterpret_cast <char *>(data[id]),
357
+ static_cast <int >(buffer->data [0 ]),
358
+ to_stream (buffer->data [1 ]));
338
359
sizes[id] = !str ? 0 : __builtin_strlen (str) + 1 ;
339
360
});
340
361
port.send_n (data, sizes);
@@ -353,9 +374,9 @@ rpc::Status handle_port_impl(rpc::Server::Port &port) {
353
374
break ;
354
375
}
355
376
case LIBC_CLOSE_FILE: {
356
- port.recv_and_send ([&](rpc::Buffer *buffer, uint32_t id ) {
377
+ port.recv_and_send ([&](rpc::Buffer *buffer, uint32_t ) {
357
378
FILE *file = reinterpret_cast <FILE *>(buffer->data [0 ]);
358
- buffer->data [0 ] = fclose (file);
379
+ buffer->data [0 ] = :: fclose (file);
359
380
});
360
381
break ;
361
382
}
@@ -498,21 +519,28 @@ rpc::Status handle_port_impl(rpc::Server::Port &port) {
498
519
return rpc::RPC_SUCCESS;
499
520
}
500
521
501
- } // namespace LIBC_NAMESPACE
522
+ } // namespace internal
523
+ } // namespace LIBC_NAMESPACE_DECL
502
524
525
+ namespace LIBC_NAMESPACE_DECL {
503
526
namespace rpc {
504
- // The implementation of this function currently lives in the utility directory
505
- // at 'utils/gpu/server/rpc_server.cpp'.
506
- rpc::Status handle_libc_opcodes (rpc::Server::Port &port, uint32_t num_lanes) {
527
+
528
+ // Handles any opcode generated from the 'libc' client code.
529
+ LIBC_INLINE ::rpc::Status handle_libc_opcodes (::rpc::Server::Port &port,
530
+ uint32_t num_lanes) {
507
531
switch (num_lanes) {
508
532
case 1 :
509
- return LIBC_NAMESPACE ::handle_port_impl<1 >(port);
533
+ return internal ::handle_port_impl<1 >(port);
510
534
case 32 :
511
- return LIBC_NAMESPACE ::handle_port_impl<32 >(port);
535
+ return internal ::handle_port_impl<32 >(port);
512
536
case 64 :
513
- return LIBC_NAMESPACE ::handle_port_impl<64 >(port);
537
+ return internal ::handle_port_impl<64 >(port);
514
538
default :
515
- return rpc::RPC_ERROR;
539
+ return :: rpc::RPC_ERROR;
516
540
}
517
541
}
542
+
518
543
} // namespace rpc
544
+ } // namespace LIBC_NAMESPACE_DECL
545
+
546
+ #endif // LLVM_LIBC_SRC___SUPPORT_RPC_RPC_SERVER_H
0 commit comments