Skip to content

Commit 9a99afb

Browse files
committed
[libc] Use string_view for write_to_stderr
This patch makes use of `cpp::string_view` instead of `const char*` for `write_to_stderr`. This helps sending non null-terminated buffers such as a single character, `cpp::string_view` or `cpp::string`. It also fizes the gpu version that had several bugs (See https://reviews.llvm.org/D145913#4236641). Differential Revision: https://reviews.llvm.org/D147375
1 parent b95913e commit 9a99afb

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

libc/src/__support/OSUtil/gpu/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ add_object_library(
88
io.h
99
DEPENDS
1010
libc.src.__support.common
11+
libc.src.__support.CPP.string_view
1112
libc.src.__support.RPC.rpc_client
13+
libc.src.string.memory_utils.memcpy_implementation
1214
)

libc/src/__support/OSUtil/gpu/io.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,40 @@
88

99
#include "io.h"
1010

11+
#include "src/__support/CPP/string_view.h"
1112
#include "src/__support/RPC/rpc_client.h"
12-
#include "src/string/string_utils.h"
13+
#include "src/string/memory_utils/memcpy_implementations.h"
1314

1415
namespace __llvm_libc {
1516

16-
void write_to_stderr(const char *msg) {
17-
uint64_t length = internal::string_length(msg) + 1;
18-
uint64_t buffer_len = sizeof(rpc::Buffer) - sizeof(uint64_t);
19-
for (uint64_t i = 0; i < length; i += buffer_len) {
20-
rpc::client.run(
21-
[&](rpc::Buffer *buffer) {
22-
buffer->data[0] = rpc::Opcode::PRINT_TO_STDERR;
23-
inline_memcpy(reinterpret_cast<char *>(&buffer->data[1]), &msg[i],
24-
(length > buffer_len ? buffer_len : length));
25-
},
26-
[](rpc::Buffer *) { /* void */ });
17+
namespace internal {
18+
19+
static constexpr size_t BUFFER_SIZE = sizeof(rpc::Buffer) - sizeof(uint64_t);
20+
static constexpr size_t MAX_STRING_SIZE = BUFFER_SIZE;
21+
22+
LIBC_INLINE void send_null_terminated(cpp::string_view src) {
23+
rpc::client.run(
24+
[&](rpc::Buffer *buffer) {
25+
buffer->data[0] = rpc::Opcode::PRINT_TO_STDERR;
26+
char *data = reinterpret_cast<char *>(&buffer->data[1]);
27+
inline_memcpy(data, src.data(), src.size());
28+
data[src.size()] = '\0';
29+
},
30+
[](rpc::Buffer *) { /* void */ });
31+
}
32+
33+
} // namespace internal
34+
35+
void write_to_stderr(cpp::string_view msg) {
36+
bool send_empty_string = true;
37+
for (; !msg.empty();) {
38+
const auto chunk = msg.substr(0, internal::MAX_STRING_SIZE);
39+
internal::send_null_terminated(chunk);
40+
msg.remove_prefix(chunk.size());
41+
send_empty_string = false;
2742
}
43+
if (send_empty_string)
44+
internal::send_null_terminated("");
2845
}
2946

3047
} // namespace __llvm_libc

libc/src/__support/OSUtil/gpu/io.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@
99
#ifndef LLVM_LIBC_SRC_SUPPORT_OSUTIL_GPU_IO_H
1010
#define LLVM_LIBC_SRC_SUPPORT_OSUTIL_GPU_IO_H
1111

12+
#include "src/__support/CPP/string_view.h"
13+
#include "src/__support/macros/attributes.h" // LIBC_INLINE
14+
1215
namespace __llvm_libc {
1316

14-
void write_to_stderr(const char *msg);
17+
void write_to_stderr(cpp::string_view msg);
18+
19+
LIBC_INLINE void write_to_stderr(const char *msg) {
20+
write_to_stderr(cpp::string_view(msg));
21+
}
1522

1623
} // namespace __llvm_libc
1724

libc/src/__support/OSUtil/linux/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ add_header_library(
1313
DEPENDS
1414
.${LIBC_TARGET_ARCHITECTURE}.linux_${LIBC_TARGET_ARCHITECTURE}_util
1515
libc.src.__support.common
16+
libc.src.__support.CPP.string_view
1617
)

libc/src/__support/OSUtil/linux/io.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@
99
#ifndef LLVM_LIBC_SRC_SUPPORT_OSUTIL_LINUX_IO_H
1010
#define LLVM_LIBC_SRC_SUPPORT_OSUTIL_LINUX_IO_H
1111

12-
#include "src/string/string_utils.h"
12+
#include "src/__support/CPP/string_view.h"
1313
#include "syscall.h" // For internal syscall function.
1414

1515
#include <sys/syscall.h> // For syscall numbers.
1616

1717
namespace __llvm_libc {
1818

19-
LIBC_INLINE void write_to_stderr(const char *msg) {
20-
__llvm_libc::syscall_impl(SYS_write, 2 /* stderr */, msg,
21-
internal::string_length(msg));
19+
LIBC_INLINE void write_to_stderr(cpp::string_view msg) {
20+
__llvm_libc::syscall_impl(SYS_write, 2 /* stderr */, msg.data(), msg.size());
2221
}
2322

2423
} // namespace __llvm_libc

0 commit comments

Comments
 (0)