Skip to content

Commit

Permalink
[libc] Implement fseek, fflush, and ftell on the GPU (#67160)
Browse files Browse the repository at this point in the history
Summary:
This patch adds the necessary entrypoints to handle the `fseek`,
`fflush`, and `ftell` functions. These are all very straightfoward, we
simply make RPC calls to the associated function on the other end.
Implementing it this way allows us to more or less borrow the state of
the stream from the server as we intentionally maintain no internal
state on the GPU device. However, this does not implement the `errno`
functinality so that must be ignored.
  • Loading branch information
jhuber6 committed Sep 26, 2023
1 parent 0b3f9d8 commit 7ac8e26
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 39 deletions.
3 changes: 3 additions & 0 deletions libc/config/gpu/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# stdio.h entrypoints
libc.src.stdio.feof
libc.src.stdio.ferror
libc.src.stdio.fseek
libc.src.stdio.fflush
libc.src.stdio.ftell
libc.src.stdio.clearerr
libc.src.stdio.puts
libc.src.stdio.fopen
Expand Down
3 changes: 3 additions & 0 deletions libc/docs/gpu/support.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ Function Name Available RPC Required
feof |check| |check|
ferror |check| |check|
clearerr |check| |check|
fseek |check| |check|
ftell |check| |check|
fflush |check| |check|
fgetc |check| |check|
fgets |check| |check|
getc |check| |check|
Expand Down
3 changes: 3 additions & 0 deletions libc/include/llvm-libc-types/rpc_opcodes_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ typedef enum : unsigned short {
RPC_FEOF = 13,
RPC_FERROR = 14,
RPC_CLEARERR = 15,
RPC_FSEEK = 16,
RPC_FTELL = 17,
RPC_FFLUSH = 18,
} rpc_opcode_t;

#endif // __LLVM_LIBC_TYPES_RPC_OPCODE_H__
42 changes: 3 additions & 39 deletions libc/src/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,6 @@ if(NOT LIBC_TARGET_ARCHITECTURE_IS_GPU)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/generic)
endif()

add_entrypoint_object(
fflush
SRCS
fflush.cpp
HDRS
fflush.h
DEPENDS
libc.src.errno.errno
libc.include.stdio
libc.src.__support.File.file
libc.src.__support.File.platform_file
)

add_entrypoint_object(
flockfile
SRCS
Expand All @@ -63,19 +50,6 @@ add_entrypoint_object(
libc.src.__support.File.platform_file
)

add_entrypoint_object(
fseek
SRCS
fseek.cpp
HDRS
fseek.h
DEPENDS
libc.src.errno.errno
libc.include.stdio
libc.src.__support.File.file
libc.src.__support.File.platform_file
)

add_entrypoint_object(
ungetc
SRCS
Expand Down Expand Up @@ -302,19 +276,6 @@ add_entrypoint_object(
add_subdirectory(printf_core)
add_subdirectory(scanf_core)

add_entrypoint_object(
ftell
SRCS
ftell.cpp
HDRS
ftell.h
DEPENDS
libc.src.errno.errno
libc.include.stdio
libc.src.__support.File.file
libc.src.__support.File.platform_file
)

add_entrypoint_object(
remove
ALIAS
Expand All @@ -327,6 +288,9 @@ add_stdio_entrypoint_object(feof)
add_stdio_entrypoint_object(feof_unlocked)
add_stdio_entrypoint_object(ferror)
add_stdio_entrypoint_object(ferror_unlocked)
add_stdio_entrypoint_object(fseek)
add_stdio_entrypoint_object(ftell)
add_stdio_entrypoint_object(fflush)
add_stdio_entrypoint_object(clearerr)
add_stdio_entrypoint_object(clearerr_unlocked)
add_stdio_entrypoint_object(fopen)
Expand Down
39 changes: 39 additions & 0 deletions libc/src/stdio/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,45 @@ add_entrypoint_object(
libc.src.__support.File.platform_file
)

add_entrypoint_object(
fflush
SRCS
fflush.cpp
HDRS
../fflush.h
DEPENDS
libc.src.errno.errno
libc.include.stdio
libc.src.__support.File.file
libc.src.__support.File.platform_file
)

add_entrypoint_object(
fseek
SRCS
fseek.cpp
HDRS
../fseek.h
DEPENDS
libc.src.errno.errno
libc.include.stdio
libc.src.__support.File.file
libc.src.__support.File.platform_file
)

add_entrypoint_object(
ftell
SRCS
ftell.cpp
HDRS
ftell.h
DEPENDS
libc.src.errno.errno
libc.include.stdio
libc.src.__support.File.file
libc.src.__support.File.platform_file
)

add_entrypoint_object(
fopen
SRCS
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
33 changes: 33 additions & 0 deletions libc/src/stdio/gpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,39 @@ add_entrypoint_object(
libc.src.__support.RPC.rpc_client
)

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

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

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

add_entrypoint_object(
clearerr
SRCS
Expand Down
26 changes: 26 additions & 0 deletions libc/src/stdio/gpu/fflush.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===-- Implementation of fflush ------------------------------------------===//
//
// 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/fflush.h"
#include "file.h"

#include <stdio.h>

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, fflush, (::FILE * stream)) {
int ret;
rpc::Client::Port port = rpc::client.open<RPC_FFLUSH>();
port.send_and_recv(
[=](rpc::Buffer *buffer) { buffer->data[0] = file::from_stream(stream); },
[&](rpc::Buffer *buffer) { ret = static_cast<int>(buffer->data[0]); });
port.close();
return ret;
}

} // namespace LIBC_NAMESPACE
30 changes: 30 additions & 0 deletions libc/src/stdio/gpu/fseek.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===-- GPU implementation of fseek ---------------------------------------===//
//
// 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/fseek.h"
#include "file.h"

#include <stdio.h>

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, fseek, (::FILE * stream, long offset, int whence)) {
int ret;
rpc::Client::Port port = rpc::client.open<RPC_FSEEK>();
port.send_and_recv(
[=](rpc::Buffer *buffer) {
buffer->data[0] = file::from_stream(stream);
buffer->data[1] = static_cast<uint64_t>(offset);
buffer->data[2] = static_cast<uint64_t>(whence);
},
[&](rpc::Buffer *buffer) { ret = static_cast<int>(buffer->data[0]); });
port.close();
return ret;
}

} // namespace LIBC_NAMESPACE
26 changes: 26 additions & 0 deletions libc/src/stdio/gpu/ftell.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===-- GPU implementation of ftell ---------------------------------------===//
//
// 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/ftell.h"
#include "file.h"

#include <stdio.h>

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, ftell, (::FILE * stream)) {
long ret;
rpc::Client::Port port = rpc::client.open<RPC_FSEEK>();
port.send_and_recv(
[=](rpc::Buffer *buffer) { buffer->data[0] = file::from_stream(stream); },
[&](rpc::Buffer *buffer) { ret = static_cast<long>(buffer->data[0]); });
port.close();
return ret;
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/utils/gpu/server/rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,26 @@ struct Server {
});
break;
}
case RPC_FSEEK: {
port->recv_and_send([](rpc::Buffer *buffer) {
buffer->data[0] = fseek(file::to_stream(buffer->data[0]),
static_cast<long>(buffer->data[1]),
static_cast<int>(buffer->data[2]));
});
break;
}
case RPC_FTELL: {
port->recv_and_send([](rpc::Buffer *buffer) {
buffer->data[0] = ftell(file::to_stream(buffer->data[0]));
});
break;
}
case RPC_FFLUSH: {
port->recv_and_send([](rpc::Buffer *buffer) {
buffer->data[0] = fflush(file::to_stream(buffer->data[0]));
});
break;
}
case RPC_NOOP: {
port->recv([](rpc::Buffer *) {});
break;
Expand Down

0 comments on commit 7ac8e26

Please sign in to comment.