Skip to content

Commit 04d0e28

Browse files
jhuber6cjdb
authored andcommitted
[libc] Add scanf support to the GPU build (llvm#104812)
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.
1 parent 6d8abd5 commit 04d0e28

File tree

5 files changed

+61
-19
lines changed

5 files changed

+61
-19
lines changed

libc/config/gpu/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ set(TARGET_LIBC_ENTRYPOINTS
192192
libc.src.stdio.vsprintf
193193
libc.src.stdio.asprintf
194194
libc.src.stdio.vasprintf
195+
libc.src.stdio.scanf
196+
libc.src.stdio.fscanf
195197
libc.src.stdio.sscanf
196198
libc.src.stdio.vsscanf
197199
libc.src.stdio.feof

libc/docs/gpu/support.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ snprintf |check|
239239
vsprintf |check|
240240
vsnprintf |check|
241241
sscanf |check|
242+
scanf |check|
243+
fscanf |check|
242244
putchar |check| |check|
243245
fclose |check| |check|
244246
fopen |check| |check|

libc/src/stdio/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ list(APPEND scanf_deps
101101
libc.hdr.types.FILE
102102
)
103103

104-
if(LLVM_LIBC_FULL_BUILD)
104+
if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU)
105105
list(APPEND scanf_deps
106106
libc.src.__support.File.file
107107
libc.src.__support.File.platform_file

libc/src/stdio/scanf_core/CMakeLists.txt

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,33 @@ add_object_library(
9292
libc.src.__support.str_to_float
9393
)
9494

95-
if(NOT (TARGET libc.src.__support.File.file) AND LLVM_LIBC_FULL_BUILD)
96-
# Not all platforms have a file implementation. If file is unvailable, and a
97-
# full build is requested, then we must skip all file based printf sections.
98-
return()
95+
if(LIBC_TARGET_OS_IS_GPU)
96+
add_header_library(
97+
vfscanf_internal
98+
HDRS
99+
vfscanf_internal.h
100+
DEPENDS
101+
.reader
102+
.scanf_main
103+
libc.include.stdio
104+
libc.src.__support.arg_list
105+
libc.src.stdio.getc
106+
libc.src.stdio.ungetc
107+
libc.src.stdio.ferror
108+
COMPILE_OPTIONS
109+
-DLIBC_COPT_STDIO_USE_SYSTEM_FILE
110+
)
111+
elseif(TARGET libc.src.__support.File.file OR (NOT LLVM_LIBC_FULL_BUILD))
112+
add_header_library(
113+
vfscanf_internal
114+
HDRS
115+
vfscanf_internal.h
116+
DEPENDS
117+
.reader
118+
.scanf_main
119+
libc.include.stdio
120+
libc.src.__support.File.file
121+
libc.src.__support.arg_list
122+
${use_system_file}
123+
)
99124
endif()
100-
101-
add_header_library(
102-
vfscanf_internal
103-
HDRS
104-
vfscanf_internal.h
105-
DEPENDS
106-
.reader
107-
.scanf_main
108-
libc.include.stdio
109-
libc.src.__support.File.file
110-
libc.src.__support.arg_list
111-
${use_system_file}
112-
)

libc/src/stdio/scanf_core/vfscanf_internal.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,43 @@
1212
#include "src/__support/File/file.h"
1313
#include "src/__support/arg_list.h"
1414
#include "src/__support/macros/config.h"
15+
#include "src/__support/macros/properties/architectures.h"
1516
#include "src/stdio/scanf_core/reader.h"
1617
#include "src/stdio/scanf_core/scanf_main.h"
1718

19+
#if defined(LIBC_TARGET_ARCH_IS_GPU)
20+
#include "src/stdio/ferror.h"
21+
#include "src/stdio/getc.h"
22+
#include "src/stdio/ungetc.h"
23+
#endif
24+
1825
#include "hdr/types/FILE.h"
1926
#include <stddef.h>
2027

2128
namespace LIBC_NAMESPACE_DECL {
2229

2330
namespace internal {
2431

25-
#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
32+
#if defined(LIBC_TARGET_ARCH_IS_GPU)
33+
// The GPU build provides FILE access through the host operating system's
34+
// library. So here we simply use the public entrypoints like in the SYSTEM_FILE
35+
// interface. Entrypoints should normally not call others, this is an exception.
36+
// FIXME: We do not acquire any locks here, so this is not thread safe.
37+
LIBC_INLINE void flockfile(::FILE *) { return; }
38+
39+
LIBC_INLINE void funlockfile(::FILE *) { return; }
40+
41+
LIBC_INLINE int getc(void *f) {
42+
return LIBC_NAMESPACE::getc(reinterpret_cast<::FILE *>(f));
43+
}
44+
45+
LIBC_INLINE void ungetc(int c, void *f) {
46+
LIBC_NAMESPACE::ungetc(c, reinterpret_cast<::FILE *>(f));
47+
}
48+
49+
LIBC_INLINE int ferror_unlocked(::FILE *f) { return LIBC_NAMESPACE::ferror(f); }
50+
51+
#elif !defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE)
2652

2753
LIBC_INLINE void flockfile(FILE *f) {
2854
reinterpret_cast<LIBC_NAMESPACE::File *>(f)->lock();

0 commit comments

Comments
 (0)