From ff7dcb8e8431d4a35ea21a91436e27a47832521c Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Mon, 19 Aug 2024 11:22:36 -0500 Subject: [PATCH 1/3] [libc] Add `scanf` support to the GPU build Summary: The `scanf` function has a "system file" configuration, which is pretty much what the GPU implementation does at this point. So we should be able to use it in much the same way. --- libc/config/gpu/entrypoints.txt | 2 + libc/docs/gpu/support.rst | 2 + libc/src/stdio/CMakeLists.txt | 2 +- libc/src/stdio/scanf_core/CMakeLists.txt | 46 ++++++++++++-------- libc/src/stdio/scanf_core/vfscanf_internal.h | 26 ++++++++++- 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt index bbae3298fae61..d7f35bc1edf5a 100644 --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -192,6 +192,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdio.vsprintf libc.src.stdio.asprintf libc.src.stdio.vasprintf + libc.src.stdio.scanf + libc.src.stdio.fscanf libc.src.stdio.sscanf libc.src.stdio.vsscanf libc.src.stdio.feof diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst index 5ef298a2ba58f..c8b1052ce1689 100644 --- a/libc/docs/gpu/support.rst +++ b/libc/docs/gpu/support.rst @@ -239,6 +239,8 @@ snprintf |check| vsprintf |check| vsnprintf |check| sscanf |check| +scanf |check| +fscanf |check| putchar |check| |check| fclose |check| |check| fopen |check| |check| diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt index bc5ef5fe0e9b4..372b8fc819245 100644 --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -101,7 +101,7 @@ list(APPEND scanf_deps libc.hdr.types.FILE ) -if(LLVM_LIBC_FULL_BUILD) +if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU) list(APPEND scanf_deps libc.src.__support.File.file libc.src.__support.File.platform_file diff --git a/libc/src/stdio/scanf_core/CMakeLists.txt b/libc/src/stdio/scanf_core/CMakeLists.txt index e2b49e0c91528..5c00ae0c9973c 100644 --- a/libc/src/stdio/scanf_core/CMakeLists.txt +++ b/libc/src/stdio/scanf_core/CMakeLists.txt @@ -92,21 +92,33 @@ add_object_library( libc.src.__support.str_to_float ) -if(NOT (TARGET libc.src.__support.File.file) AND LLVM_LIBC_FULL_BUILD) - # Not all platforms have a file implementation. If file is unvailable, and a - # full build is requested, then we must skip all file based printf sections. - return() +if(LIBC_TARGET_OS_IS_GPU) + add_header_library( + vfscanf_internal + HDRS + vfscanf_internal.h + DEPENDS + .reader + .scanf_main + libc.include.stdio + libc.src.__support.arg_list + libc.src.stdio.getc + libc.src.stdio.ungetc + libc.src.stdio.ferror + COMPILE_OPTIONS + -DLIBC_COPT_STDIO_USE_SYSTEM_FILE + ) +elseif(TARGET libc.src.__support.File.file OR (NOT LLVM_LIBC_FULL_BUILD)) + add_header_library( + vfscanf_internal + HDRS + vfscanf_internal.h + DEPENDS + .reader + .scanf_main + libc.include.stdio + libc.src.__support.File.file + libc.src.__support.arg_list + ${use_system_file} + ) endif() - -add_header_library( - vfscanf_internal - HDRS - vfscanf_internal.h - DEPENDS - .reader - .scanf_main - libc.include.stdio - libc.src.__support.File.file - libc.src.__support.arg_list - ${use_system_file} -) diff --git a/libc/src/stdio/scanf_core/vfscanf_internal.h b/libc/src/stdio/scanf_core/vfscanf_internal.h index 2b0072a6ae35f..68848375eee22 100644 --- a/libc/src/stdio/scanf_core/vfscanf_internal.h +++ b/libc/src/stdio/scanf_core/vfscanf_internal.h @@ -12,9 +12,16 @@ #include "src/__support/File/file.h" #include "src/__support/arg_list.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/properties/architectures.h" #include "src/stdio/scanf_core/reader.h" #include "src/stdio/scanf_core/scanf_main.h" +#if defined(LIBC_TARGET_ARCH_IS_GPU) +#include "src/stdio/ferror.h" +#include "src/stdio/getc.h" +#include "src/stdio/ungetc.h" +#endif + #include "hdr/types/FILE.h" #include @@ -22,7 +29,24 @@ namespace LIBC_NAMESPACE_DECL { namespace internal { -#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE +#if defined(LIBC_TARGET_ARCH_IS_GPU) +// Since ungetc_unlocked isn't always available, we don't acquire the lock for +// system files. +LIBC_INLINE void flockfile(::FILE *) { return; } + +LIBC_INLINE void funlockfile(::FILE *) { return; } + +LIBC_INLINE int getc(void *f) { + return LIBC_NAMESPACE::getc(reinterpret_cast<::FILE *>(f)); +} + +LIBC_INLINE void ungetc(int c, void *f) { + LIBC_NAMESPACE::ungetc(c, reinterpret_cast<::FILE *>(f)); +} + +LIBC_INLINE int ferror_unlocked(::FILE *f) { return LIBC_NAMESPACE::ferror(f); } + +#elif !defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE) LIBC_INLINE void flockfile(FILE *f) { reinterpret_cast(f)->lock(); From d1bc5fc4a11b51d29a7f0594dfeadacc56ff6f45 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Tue, 20 Aug 2024 13:35:05 -0500 Subject: [PATCH 2/3] Update vfscanf_internal.h --- libc/src/stdio/scanf_core/vfscanf_internal.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libc/src/stdio/scanf_core/vfscanf_internal.h b/libc/src/stdio/scanf_core/vfscanf_internal.h index 68848375eee22..46a22e3731f16 100644 --- a/libc/src/stdio/scanf_core/vfscanf_internal.h +++ b/libc/src/stdio/scanf_core/vfscanf_internal.h @@ -30,8 +30,10 @@ namespace LIBC_NAMESPACE_DECL { namespace internal { #if defined(LIBC_TARGET_ARCH_IS_GPU) -// Since ungetc_unlocked isn't always available, we don't acquire the lock for -// system files. +// The GPU build provides FILE access through the host operating system's +// library. So here we simply use the public entrypoints like in the SYSTEM_FILE +// interface. +// FIXME: We do not acquire any locks here, so this is not thread safe. LIBC_INLINE void flockfile(::FILE *) { return; } LIBC_INLINE void funlockfile(::FILE *) { return; } From ee2831d2702bd945a738a420462dc4bfa400a5c2 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Wed, 21 Aug 2024 17:03:52 -0500 Subject: [PATCH 3/3] Update vfscanf_internal.h --- libc/src/stdio/scanf_core/vfscanf_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/src/stdio/scanf_core/vfscanf_internal.h b/libc/src/stdio/scanf_core/vfscanf_internal.h index 46a22e3731f16..67126431fcded 100644 --- a/libc/src/stdio/scanf_core/vfscanf_internal.h +++ b/libc/src/stdio/scanf_core/vfscanf_internal.h @@ -32,7 +32,7 @@ namespace internal { #if defined(LIBC_TARGET_ARCH_IS_GPU) // The GPU build provides FILE access through the host operating system's // library. So here we simply use the public entrypoints like in the SYSTEM_FILE -// interface. +// interface. Entrypoints should normally not call others, this is an exception. // FIXME: We do not acquire any locks here, so this is not thread safe. LIBC_INLINE void flockfile(::FILE *) { return; }