[libc-commits] [libc] 60c0d30 - [libc] Implement stdio writing functions for the GPU port (#65809)
via libc-commits
libc-commits at lists.llvm.org
Sat Sep 9 11:27:11 PDT 2023
Author: Joseph Huber
Date: 2023-09-09T13:27:07-05:00
New Revision: 60c0d303d67631f6504310db2cabab6703c2e3ca
URL: https://github.com/llvm/llvm-project/commit/60c0d303d67631f6504310db2cabab6703c2e3ca
DIFF: https://github.com/llvm/llvm-project/commit/60c0d303d67631f6504310db2cabab6703c2e3ca.diff
LOG: [libc] Implement stdio writing functions for the GPU port (#65809)
Summary:
This patch implements fwrite, putc, putchar, and fputc on the GPU. These
are very straightforward, the main difference for the GPU implementation
is that we are currently ignoring `errno`. This patch also introduces a
minimal smoke test for `putc` that is an exact copy of the `puts` test
except we print the string char by char. This also modifies the `fopen`
test to use `fwrite` to mirror its use of `fread` so that it is tested
as well.
Added:
libc/src/stdio/generic/fputc.cpp
libc/src/stdio/generic/fwrite.cpp
libc/src/stdio/generic/fwrite_unlocked.cpp
libc/src/stdio/generic/putc.cpp
libc/src/stdio/generic/putchar.cpp
libc/src/stdio/gpu/fputc.cpp
libc/src/stdio/gpu/fwrite.cpp
libc/src/stdio/gpu/putc.cpp
libc/src/stdio/gpu/putchar.cpp
libc/test/src/stdio/fputc_test.cpp
Modified:
libc/config/gpu/entrypoints.txt
libc/docs/gpu/support.rst
libc/src/stdio/CMakeLists.txt
libc/src/stdio/generic/CMakeLists.txt
libc/src/stdio/gpu/CMakeLists.txt
libc/test/src/stdio/CMakeLists.txt
libc/test/src/stdio/fopen_test.cpp
Removed:
libc/src/stdio/fputc.cpp
libc/src/stdio/fwrite.cpp
libc/src/stdio/fwrite_unlocked.cpp
libc/src/stdio/putc.cpp
libc/src/stdio/putchar.cpp
################################################################################
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index bf59ba6b0a3eaa6..0e314c60870c6ae 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -88,6 +88,10 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdio.fclose
libc.src.stdio.fread
libc.src.stdio.fputs
+ libc.src.stdio.fwrite
+ libc.src.stdio.fputc
+ libc.src.stdio.putc
+ libc.src.stdio.putchar
libc.src.stdio.stdin
libc.src.stdio.stdout
libc.src.stdio.stderr
diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst
index 3e8de03050332d1..fabdfb968a741ad 100644
--- a/libc/docs/gpu/support.rst
+++ b/libc/docs/gpu/support.rst
@@ -118,20 +118,24 @@ strtoumax |check|
============= ========= ============
stdio.h
---------
+-------
============= ========= ============
Function Name Available RPC Required
============= ========= ============
puts |check| |check|
fputs |check| |check|
+fputc |check| |check|
+fwrite |check| |check|
+putc |check| |check|
+putchar |check| |check|
fclose |check| |check|
fopen |check| |check|
fread |check| |check|
============= ========= ============
time.h
---------
+------
============= ========= ============
Function Name Available RPC Required
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 79863f83c1e5e7d..740ec106da2e4d7 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -229,71 +229,6 @@ add_entrypoint_object(
libc.src.__support.File.platform_file
)
-add_entrypoint_object(
- fwrite_unlocked
- SRCS
- fwrite_unlocked.cpp
- HDRS
- fwrite_unlocked.h
- DEPENDS
- libc.src.errno.errno
- libc.include.stdio
- libc.src.__support.File.file
- libc.src.__support.File.platform_file
-)
-
-add_entrypoint_object(
- fwrite
- SRCS
- fwrite.cpp
- HDRS
- fwrite.h
- DEPENDS
- libc.src.errno.errno
- libc.include.stdio
- libc.src.__support.File.file
- libc.src.__support.File.platform_file
-)
-
-add_entrypoint_object(
- fputc
- SRCS
- fputc.cpp
- HDRS
- fputc.h
- DEPENDS
- libc.src.errno.errno
- libc.include.stdio
- libc.src.__support.File.file
- libc.src.__support.File.platform_file
-)
-
-add_entrypoint_object(
- putc
- SRCS
- putc.cpp
- HDRS
- putc.h
- DEPENDS
- libc.src.errno.errno
- libc.include.stdio
- libc.src.__support.File.file
- libc.src.__support.File.platform_file
-)
-
-add_entrypoint_object(
- putchar
- SRCS
- putchar.cpp
- HDRS
- putchar.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
@@ -538,6 +473,11 @@ add_stdio_entrypoint_object(fread_unlocked)
add_stdio_entrypoint_object(fread)
add_stdio_entrypoint_object(puts)
add_stdio_entrypoint_object(fputs)
+add_stdio_entrypoint_object(fwrite_unlocked)
+add_stdio_entrypoint_object(fwrite)
+add_stdio_entrypoint_object(fputc)
+add_stdio_entrypoint_object(putc)
+add_stdio_entrypoint_object(putchar)
add_stdio_entrypoint_object(stdin)
add_stdio_entrypoint_object(stdout)
add_stdio_entrypoint_object(stderr)
diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt
index 8d14d9fbf6f2497..e40e2cc9e04d3e3 100644
--- a/libc/src/stdio/generic/CMakeLists.txt
+++ b/libc/src/stdio/generic/CMakeLists.txt
@@ -75,6 +75,71 @@ add_entrypoint_object(
libc.src.__support.File.platform_stdout
)
+add_entrypoint_object(
+ fwrite_unlocked
+ SRCS
+ fwrite_unlocked.cpp
+ HDRS
+ ../fwrite_unlocked.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+ fwrite
+ SRCS
+ fwrite.cpp
+ HDRS
+ ../fwrite.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+ fputc
+ SRCS
+ fputc.cpp
+ HDRS
+ ../fputc.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+ putc
+ SRCS
+ putc.cpp
+ HDRS
+ ../putc.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+ putchar
+ SRCS
+ putchar.cpp
+ HDRS
+ ../putchar.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
add_entrypoint_object(
stdin
SRCS
diff --git a/libc/src/stdio/fputc.cpp b/libc/src/stdio/generic/fputc.cpp
similarity index 100%
rename from libc/src/stdio/fputc.cpp
rename to libc/src/stdio/generic/fputc.cpp
diff --git a/libc/src/stdio/fwrite.cpp b/libc/src/stdio/generic/fwrite.cpp
similarity index 100%
rename from libc/src/stdio/fwrite.cpp
rename to libc/src/stdio/generic/fwrite.cpp
diff --git a/libc/src/stdio/fwrite_unlocked.cpp b/libc/src/stdio/generic/fwrite_unlocked.cpp
similarity index 100%
rename from libc/src/stdio/fwrite_unlocked.cpp
rename to libc/src/stdio/generic/fwrite_unlocked.cpp
diff --git a/libc/src/stdio/putc.cpp b/libc/src/stdio/generic/putc.cpp
similarity index 100%
rename from libc/src/stdio/putc.cpp
rename to libc/src/stdio/generic/putc.cpp
diff --git a/libc/src/stdio/putchar.cpp b/libc/src/stdio/generic/putchar.cpp
similarity index 100%
rename from libc/src/stdio/putchar.cpp
rename to libc/src/stdio/generic/putchar.cpp
diff --git a/libc/src/stdio/gpu/CMakeLists.txt b/libc/src/stdio/gpu/CMakeLists.txt
index 458dd86175021c4..d35b1925c6a47a0 100644
--- a/libc/src/stdio/gpu/CMakeLists.txt
+++ b/libc/src/stdio/gpu/CMakeLists.txt
@@ -61,6 +61,50 @@ add_entrypoint_object(
.gpu_file
)
+add_entrypoint_object(
+ fwrite
+ SRCS
+ fwrite.cpp
+ HDRS
+ ../fwrite.h
+ DEPENDS
+ libc.include.stdio
+ .gpu_file
+)
+
+add_entrypoint_object(
+ fputc
+ SRCS
+ fputc.cpp
+ HDRS
+ ../fputc.h
+ DEPENDS
+ libc.include.stdio
+ .gpu_file
+)
+
+add_entrypoint_object(
+ putc
+ SRCS
+ putc.cpp
+ HDRS
+ ../putc.h
+ DEPENDS
+ libc.include.stdio
+ .gpu_file
+)
+
+add_entrypoint_object(
+ putchar
+ SRCS
+ putchar.cpp
+ HDRS
+ ../putchar.h
+ DEPENDS
+ libc.include.stdio
+ .gpu_file
+)
+
add_entrypoint_object(
stdin
SRCS
diff --git a/libc/src/stdio/gpu/fputc.cpp b/libc/src/stdio/gpu/fputc.cpp
new file mode 100644
index 000000000000000..90d238972972ec0
--- /dev/null
+++ b/libc/src/stdio/gpu/fputc.cpp
@@ -0,0 +1,26 @@
+//===-- GPU implementation of fputc ---------------------------------------===//
+//
+// 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 "file.h"
+#include "src/stdio/fputc.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, fputc, (int c, ::FILE *stream)) {
+ unsigned char uc = static_cast<unsigned char>(c);
+
+ size_t written = file::write(stream, &uc, 1);
+ if (1 != written)
+ return EOF;
+
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/gpu/fwrite.cpp b/libc/src/stdio/gpu/fwrite.cpp
new file mode 100644
index 000000000000000..fccaabd0673ec5c
--- /dev/null
+++ b/libc/src/stdio/gpu/fwrite.cpp
@@ -0,0 +1,26 @@
+//===-- GPU implementation of fwrite --------------------------------------===//
+//
+// 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/fwrite.h"
+#include "file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(size_t, fwrite,
+ (const void *__restrict buffer, size_t size, size_t nmemb,
+ ::FILE *stream)) {
+ if (size == 0 || nmemb == 0)
+ return 0;
+
+ auto result = file::write(stream, buffer, size * nmemb);
+ return result / size;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/gpu/putc.cpp b/libc/src/stdio/gpu/putc.cpp
new file mode 100644
index 000000000000000..d450edb6596df1c
--- /dev/null
+++ b/libc/src/stdio/gpu/putc.cpp
@@ -0,0 +1,26 @@
+//===-- GPU implementation of putc ----------------------------------------===//
+//
+// 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/putc.h"
+#include "file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, putc, (int c, ::FILE *stream)) {
+ unsigned char uc = static_cast<unsigned char>(c);
+
+ size_t written = file::write(stream, &uc, 1);
+ if (1 != written)
+ return EOF;
+
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/gpu/putchar.cpp b/libc/src/stdio/gpu/putchar.cpp
new file mode 100644
index 000000000000000..df577544b8ba405
--- /dev/null
+++ b/libc/src/stdio/gpu/putchar.cpp
@@ -0,0 +1,26 @@
+//===-- GPU implementation of putchar -------------------------------------===//
+//
+// 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 "file.h"
+#include "src/stdio/putchar.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, putchar, (int c)) {
+ unsigned char uc = static_cast<unsigned char>(c);
+
+ size_t written = file::write(stdout, &uc, 1);
+ if (1 != written)
+ return EOF;
+
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index 01590f9acb8545f..6090dc1f46c87ef 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -271,6 +271,20 @@ add_libc_test(
libc.src.stdio.stderr
)
+add_libc_test(
+ fputc_test
+ HERMETIC_TEST_ONLY # writes to libc's stdout and stderr
+ SUITE
+ libc_stdio_unittests
+ SRCS
+ fputc_test.cpp
+ DEPENDS
+ libc.src.stdio.fputc
+ libc.src.stdio.putchar
+ libc.src.stdio.stdout
+ libc.src.stdio.stderr
+)
+
add_libc_test(
fopen_test
SUITE
@@ -279,7 +293,7 @@ add_libc_test(
fopen_test.cpp
DEPENDS
libc.src.stdio.fread
- libc.src.stdio.fputs
+ libc.src.stdio.fwrite
libc.src.stdio.fclose
libc.src.stdio.fopen
)
diff --git a/libc/test/src/stdio/fopen_test.cpp b/libc/test/src/stdio/fopen_test.cpp
index 8e8a1c9638f5be6..f0de8caf673cc7e 100644
--- a/libc/test/src/stdio/fopen_test.cpp
+++ b/libc/test/src/stdio/fopen_test.cpp
@@ -9,7 +9,7 @@
#include "src/__support/File/file.h"
#include "src/stdio/fclose.h"
#include "src/stdio/fopen.h"
-#include "src/stdio/fputs.h"
+#include "src/stdio/fwrite.h"
#include "src/stdio/fread.h"
#include "test/UnitTest/Test.h"
@@ -21,7 +21,7 @@ TEST(LlvmLibcFOpenTest, PrintToFile) {
ASSERT_FALSE(file == nullptr);
static constexpr char STRING[] = "A simple string written to a file\n";
- result = __llvm_libc::fputs(STRING, file);
+ result = __llvm_libc::fwrite(STRING, 1, sizeof(STRING) - 1, file);
EXPECT_GE(result, 0);
ASSERT_EQ(0, __llvm_libc::fclose(file));
diff --git a/libc/test/src/stdio/fputc_test.cpp b/libc/test/src/stdio/fputc_test.cpp
new file mode 100644
index 000000000000000..e5aa7c713463bf2
--- /dev/null
+++ b/libc/test/src/stdio/fputc_test.cpp
@@ -0,0 +1,30 @@
+//===-- Unittests for fputc / putchar -------------------------------------===//
+//
+// 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/file.h"
+#include "src/stdio/fputc.h"
+#include "src/stdio/putchar.h"
+
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcPutcTest, PrintOut) {
+ int result;
+
+ constexpr char simple[] = "A simple string written to stdout\n";
+ for (const char &c : simple) {
+ result = __llvm_libc::putchar(c);
+ EXPECT_GE(result, 0);
+ }
+
+ constexpr char more[] = "A simple string written to stderr\n";
+ for (const char &c : simple) {
+ result =
+ __llvm_libc::fputc(c, reinterpret_cast<FILE *>(__llvm_libc::stderr));
+ }
+ EXPECT_GE(result, 0);
+}
More information about the libc-commits
mailing list