61 changes: 61 additions & 0 deletions libc/src/stdio/gpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
add_header_library(
gpu_file
HDRS
file.h
DEPENDS
libc.src.__support.common
libc.src.__support.CPP.string_view
libc.src.__support.RPC.rpc_client
)

add_entrypoint_object(
puts
SRCS
puts.cpp
HDRS
../puts.h
DEPENDS
libc.include.stdio
.gpu_file
)

add_entrypoint_object(
fputs
SRCS
fputs.cpp
HDRS
../fputs.h
DEPENDS
libc.include.stdio
.gpu_file
)

add_entrypoint_object(
stdin
SRCS
stdin.cpp
HDRS
../stdin.h
DEPENDS
libc.include.stdio
)

add_entrypoint_object(
stdout
SRCS
stdout.cpp
HDRS
../stdout.h
DEPENDS
libc.include.stdio
)

add_entrypoint_object(
stderr
SRCS
stderr.cpp
HDRS
../stderr.h
DEPENDS
libc.include.stdio
)
89 changes: 89 additions & 0 deletions libc/src/stdio/gpu/file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//===--- GPU helper functions--------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/__support/RPC/rpc_client.h"
#include "src/string/string_utils.h"

#include <stdio.h>

namespace __llvm_libc {
namespace file {

LIBC_INLINE uint64_t write_to_stdout(const void *data, size_t size) {
uint64_t ret = 0;
rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STDOUT>();
port.send_n(data, size);
port.recv([&](rpc::Buffer *buffer) {
ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
});
port.close();
return ret;
}

LIBC_INLINE uint64_t write_to_stderr(const void *data, size_t size) {
uint64_t ret = 0;
rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STDERR>();
port.send_n(data, size);
port.recv([&](rpc::Buffer *buffer) {
ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
});
port.close();
return ret;
}

LIBC_INLINE uint64_t write_to_stream(uintptr_t file, const void *data,
size_t size) {
uint64_t ret = 0;
rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STREAM>();
port.send([&](rpc::Buffer *buffer) {
reinterpret_cast<uintptr_t *>(buffer->data)[0] = file;
});
port.send_n(data, size);
port.recv([&](rpc::Buffer *buffer) {
ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
});
port.close();
return ret;
}

LIBC_INLINE uint64_t write(FILE *f, const void *data, size_t size) {
if (f == stdout)
return write_to_stdout(data, size);
else if (f == stderr)
return write_to_stderr(data, size);
else
return write_to_stream(reinterpret_cast<uintptr_t>(f), data, size);
}

LIBC_INLINE uint64_t read_from_stdin(void *buf, size_t size) {
uint64_t ret = 0;
uint64_t recv_size;
rpc::Client::Port port = rpc::client.open<RPC_READ_FROM_STDIN>();
port.send([=](rpc::Buffer *buffer) { buffer->data[0] = size; });
port.recv_n(&buf, &recv_size, [&](uint64_t) { return buf; });
port.recv([&](rpc::Buffer *buffer) { ret = buffer->data[0]; });
port.close();
return ret;
}

LIBC_INLINE uint64_t read_from_stream(uintptr_t file, void *buf, size_t size) {
uint64_t ret = 0;
uint64_t recv_size;
rpc::Client::Port port = rpc::client.open<RPC_READ_FROM_STREAM>();
port.send([=](rpc::Buffer *buffer) {
buffer->data[0] = size;
buffer->data[1] = file;
});
port.recv_n(&buf, &recv_size, [&](uint64_t) { return buf; });
port.recv([&](rpc::Buffer *buffer) { ret = buffer->data[0]; });
port.close();
return ret;
}

} // namespace file
} // namespace __llvm_libc
27 changes: 27 additions & 0 deletions libc/src/stdio/gpu/fputs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===-- GPU Implementation of fputs ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/stdio/fputs.h"
#include "src/__support/CPP/string_view.h"
#include "src/errno/libc_errno.h"
#include "src/stdio/gpu/file.h"

#include <stdio.h>

namespace __llvm_libc {

LLVM_LIBC_FUNCTION(int, fputs,
(const char *__restrict str, ::FILE *__restrict stream)) {
cpp::string_view str_view(str);
auto written = file::write(stream, str, str_view.size());
if (written != str_view.size())
return EOF;
return 0;
}

} // namespace __llvm_libc
29 changes: 29 additions & 0 deletions libc/src/stdio/gpu/puts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- GPU Implementation of puts ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/stdio/puts.h"
#include "src/__support/CPP/string_view.h"
#include "src/errno/libc_errno.h"
#include "src/stdio/gpu/file.h"

#include <stdio.h>

namespace __llvm_libc {

LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) {
cpp::string_view str_view(str);
auto written = file::write(stdout, str, str_view.size());
if (written != str_view.size())
return EOF;
written = file::write(stdout, "\n", 1);
if (written != 1)
return EOF;
return 0;
}

} // namespace __llvm_libc
16 changes: 16 additions & 0 deletions libc/src/stdio/gpu/stderr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//===-- Definition of the global stderr object ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <stdio.h>

namespace __llvm_libc {
static struct {
} stub;
FILE *stderr = reinterpret_cast<FILE *>(&stub);
} // namespace __llvm_libc
extern "C" FILE *stderr = reinterpret_cast<FILE *>(&__llvm_libc::stub);
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
//===--- GPU implementation of the Dir helpers ----------------------------===//
//===-- Definition of the global stdin object -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/__support/File/dir.h"
#include <stdio.h>

#include "src/__support/error_or.h"

namespace __llvm_libc {} // namespace __llvm_libc
namespace __llvm_libc {
static struct {
} stub;
FILE *stdin = reinterpret_cast<FILE *>(&stub);
} // namespace __llvm_libc
extern "C" FILE *stdin = reinterpret_cast<FILE *>(&__llvm_libc::stub);
16 changes: 16 additions & 0 deletions libc/src/stdio/gpu/stdout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//===-- Definition of the global stdout object ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <stdio.h>

namespace __llvm_libc {
static struct {
} stub;
FILE *stdout = reinterpret_cast<FILE *>(&stub);
} // namespace __llvm_libc
extern "C" FILE *stdout = reinterpret_cast<FILE *>(&__llvm_libc::stub);
2 changes: 2 additions & 0 deletions libc/test/src/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ add_libc_test(
fputs_test.cpp
DEPENDS
libc.src.stdio.fputs
libc.src.stdio.stdout
libc.src.stdio.stderr
)

add_libc_test(
Expand Down