mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-12 18:45:33 -10:00
vfs: read-only Windows streams on their own handle by default
Read-only streams on Windows NT take their own handle, position and buffer over the C runtime's FILE by default; VFS_WIN32_NO_NATIVE keeps the C runtime. Measured with vfs_native_bench on Windows: 1-byte sequential reads 16.0 -> 6.8 ns, 16-byte 16.6 -> 7.5 ns, 256-byte 40.0 -> 30.4 ns; 4 KiB and up, random reads, reads at offsets, threads and small-file opens the same within run-to-run spread. The cross-libc Windows job's second VFS pass is now the C runtime one (make VFS_NATIVE=0); vfs_native_bench_native is the default build and vfs_native_bench the C runtime one.
This commit is contained in:
1 parent
cf816b8940
commit
9ce7ef2311
7 files changed
+41
-36
No files matched your search
@@ -235,11 +235,11 @@ jobs:
|
||||
./vfs_positional_nommap_test.exe
|
||||
./vfs_positional_ntverify_test.exe
|
||||
./vfs_positional_pathreopen_test.exe
|
||||
# The same with read-only streams on a handle of their own
|
||||
# (VFS_WIN32_NATIVE, opt-in): the stream contract, the
|
||||
# path an open takes, large files, offsets from threads.
|
||||
# The same with read-only streams on the C runtime
|
||||
# (VFS_WIN32_NO_NATIVE): the stream contract, the path an
|
||||
# open takes, large files, offsets from threads.
|
||||
make clean MMAP=0
|
||||
make MMAP=0 VFS_NATIVE=1
|
||||
make MMAP=0 VFS_NATIVE=0
|
||||
./vfs_bulk_read_test.exe
|
||||
./vfs_seek_contract_test.exe
|
||||
./vfs_large_file_test.exe
|
||||
|
||||
@@ -547,8 +547,8 @@ jobs:
|
||||
# self-contained regression tests came to be compiled every
|
||||
# run and never executed.
|
||||
declare -a NORUN_TARGETS=(
|
||||
# Benchmarks: C runtime streams against VFS_WIN32_NATIVE,
|
||||
# for timing on Windows.
|
||||
# Benchmarks: C runtime streams (VFS_WIN32_NO_NATIVE)
|
||||
# against the stream's own handle, for timing on Windows.
|
||||
vfs_native_bench
|
||||
vfs_native_bench_native
|
||||
# Fixture-driven checks run in Linux-samples-record.yml.
|
||||
|
||||
@@ -199,7 +199,7 @@ struct libretro_vfs_implementation_file
|
||||
HANDLE fh;
|
||||
/* CreateFileMapping handle backing `mapped`; NULL when unmapped */
|
||||
HANDLE map_handle;
|
||||
/* A read-only stream on a handle of its own (VFS_WIN32_NATIVE): its
|
||||
/* A read-only stream on a handle of its own (not VFS_WIN32_NO_NATIVE): its
|
||||
* position, the part of the file `buf` holds, and a read error */
|
||||
uint64_t npos;
|
||||
uint64_t nbuf_at;
|
||||
|
||||
@@ -136,11 +136,12 @@ ifeq ($(DESCRIPTOR_IO),1)
|
||||
CFLAGS += -DVFS_HAVE_DESCRIPTOR_IO=1
|
||||
endif
|
||||
|
||||
# 'make VFS_NATIVE=1' builds the suite with read-only Windows streams on
|
||||
# a handle of their own (VFS_WIN32_NATIVE); elsewhere it changes nothing.
|
||||
# 'make VFS_NATIVE=0' builds the suite with read-only Windows streams on
|
||||
# the C runtime (VFS_WIN32_NO_NATIVE) rather than a handle of their own;
|
||||
# elsewhere it changes nothing.
|
||||
VFS_NATIVE ?=
|
||||
ifeq ($(VFS_NATIVE),1)
|
||||
CFLAGS += -DVFS_WIN32_NATIVE
|
||||
ifeq ($(VFS_NATIVE),0)
|
||||
CFLAGS += -DVFS_WIN32_NO_NATIVE
|
||||
endif
|
||||
|
||||
# FAKE_CFR=1 stands in a copy_file_range that copies to EOF whatever
|
||||
@@ -258,22 +259,23 @@ $(TARGET_TEST18): vfs_positional_required.o $(NTVERIFY_OBJS)
|
||||
$(CC) -o $@ $^ $(LDFLAGS) -lpthread
|
||||
|
||||
# vfs_native_bench / vfs_native_bench_native: read-only stream timings
|
||||
# through the C runtime, and through VFS_WIN32_NATIVE - run both on
|
||||
# Windows and compare. Elsewhere the two are the same build.
|
||||
NATIVE_VFS_OBJ := vfs_implementation_native.o
|
||||
BENCH_OBJS := $(filter-out %/vfs_implementation.o,$(COMMON_OBJS)) \
|
||||
# through the C runtime (VFS_WIN32_NO_NATIVE), and through the stream's
|
||||
# own handle - run both on Windows and compare. Elsewhere the two are
|
||||
# the same build.
|
||||
CRT_VFS_OBJ := vfs_implementation_crt.o
|
||||
BENCH_OBJS := $(filter-out %/vfs_implementation.o,$(COMMON_OBJS)) \
|
||||
rthreads_ra.o retro_eventcount_ra.o
|
||||
|
||||
$(NATIVE_VFS_OBJ): $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS) -DVFS_WIN32_NATIVE
|
||||
$(CRT_VFS_OBJ): $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS) -DVFS_WIN32_NO_NATIVE
|
||||
|
||||
vfs_native_bench_native.o: vfs_native_bench.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS) -DVFS_WIN32_NATIVE
|
||||
vfs_native_bench_crt.o: vfs_native_bench.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS) -DVFS_WIN32_NO_NATIVE
|
||||
|
||||
$(BENCH_CRT): vfs_native_bench.o $(COMMON_OBJS) rthreads_ra.o retro_eventcount_ra.o
|
||||
$(BENCH_CRT): vfs_native_bench_crt.o $(BENCH_OBJS) $(CRT_VFS_OBJ)
|
||||
$(CC) -o $@ $^ $(LDFLAGS) $(RA_LIBS) -lpthread
|
||||
|
||||
$(BENCH_NATIVE): vfs_native_bench_native.o $(BENCH_OBJS) $(NATIVE_VFS_OBJ)
|
||||
$(BENCH_NATIVE): vfs_native_bench.o $(COMMON_OBJS) rthreads_ra.o retro_eventcount_ra.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS) $(RA_LIBS) -lpthread
|
||||
|
||||
$(TARGET_TEST10): vfs_view_test.o $(VIEW_OBJS)
|
||||
@@ -355,7 +357,7 @@ clean:
|
||||
$(TARGET_TEST4) $(TARGET_TEST5) $(TARGET_TEST6) \
|
||||
$(TARGET_TEST7) $(TARGET_TEST8) $(TARGET_TEST9) $(TARGET_TEST10) \
|
||||
$(TARGET_TEST11) $(TARGET_TEST12) $(TARGET_TEST13) $(TARGET_TEST14) $(TARGET_TEST15) $(TARGET_TEST16) $(TARGET_TEST17) $(TARGET_TEST18) $(BENCH_CRT) $(BENCH_NATIVE) \
|
||||
vfs_native_bench.o vfs_native_bench_native.o $(NATIVE_VFS_OBJ) $(CLOSE_VFS_OBJ) \
|
||||
vfs_native_bench.o vfs_native_bench_crt.o $(CRT_VFS_OBJ) $(CLOSE_VFS_OBJ) \
|
||||
$(OBJS) $(FAULT_FS_OBJ) $(RENAME_VFS_OBJ) \
|
||||
$(RA_VFS_OBJ) $(HOOK_VFS_OBJ) rthreads_ra.o retro_eventcount_ra.o \
|
||||
$(NOMMAP_VFS_OBJ) vfs_positional_required.o $(OFF32_VFS_OBJ) \
|
||||
|
||||
@@ -272,13 +272,13 @@ static void test_path_selection(void)
|
||||
}
|
||||
|
||||
/* No hint: unchanged, buffered - on a handle of its own where
|
||||
* VFS_WIN32_NATIVE takes read-only streams off the C runtime. */
|
||||
* Windows takes read-only streams off the C runtime. */
|
||||
s = retro_vfs_file_open_impl(path, RETRO_VFS_FILE_ACCESS_READ,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
CHECK(s != NULL, "plain open failed");
|
||||
if (s)
|
||||
{
|
||||
#if defined(VFS_WIN32_NATIVE) && defined(_WIN32) && !defined(_XBOX)
|
||||
#if !defined(VFS_WIN32_NO_NATIVE) && defined(_WIN32) && !defined(_XBOX)
|
||||
CHECK(s->fp == NULL && s->fh != NULL,
|
||||
"plain read-only open is not on its own handle");
|
||||
#else
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
*/
|
||||
|
||||
/* Read-only stream throughput through filestream: the C runtime path
|
||||
* (vfs_native_bench) against VFS_WIN32_NATIVE (vfs_native_bench_native),
|
||||
* the same source built twice. On anything but Windows the two are the
|
||||
* same build.
|
||||
* (vfs_native_bench, VFS_WIN32_NO_NATIVE) against the stream's own
|
||||
* handle (vfs_native_bench_native), the same source built twice. On
|
||||
* anything but Windows the two are the same build.
|
||||
*
|
||||
* sequential reads of 1, 16, 256, 4096 and 65536 bytes, and 1 MiB
|
||||
* 4 KiB at random offsets by seek and read, and by filestream_read_at
|
||||
@@ -273,10 +273,10 @@ int main(int argc, char **argv)
|
||||
if (size < 8192)
|
||||
return 1;
|
||||
|
||||
#ifdef VFS_WIN32_NATIVE
|
||||
printf("VFS_WIN32_NATIVE, %lld bytes\n", (long long)size);
|
||||
#else
|
||||
#ifdef VFS_WIN32_NO_NATIVE
|
||||
printf("C runtime streams, %lld bytes\n", (long long)size);
|
||||
#else
|
||||
printf("native streams, %lld bytes\n", (long long)size);
|
||||
#endif
|
||||
sequential(path, 1);
|
||||
sequential(path, 16);
|
||||
|
||||
@@ -339,15 +339,18 @@ static void vfs_unix_to_filetime(int64_t unix_s, FILETIME *ft)
|
||||
|
||||
#define RFILE_HINT_UNBUFFERED (1 << 8)
|
||||
|
||||
/* VFS_WIN32_NATIVE: a read-only stream on Windows NT opens a handle of
|
||||
* its own rather than a C runtime FILE, keeps its own position and a
|
||||
* 64 KiB buffer, and reads at offsets - with no CRT lock or buffer on
|
||||
* the way, and its reads at offsets on the same handle. Opt-in until
|
||||
* measured; see samples/file/vfs/vfs_native_bench.c. */
|
||||
#if defined(VFS_WIN32_NATIVE) && defined(_WIN32) && !defined(_XBOX) \
|
||||
/* A read-only stream on Windows NT opens a handle of its own rather
|
||||
* than a C runtime FILE, keeps its own position and a 64 KiB buffer,
|
||||
* and reads at offsets - with no CRT lock or buffer on the way, and its
|
||||
* reads at offsets on the same handle. VFS_WIN32_NO_NATIVE keeps the C
|
||||
* runtime; samples/file/vfs/vfs_native_bench.c times the two. */
|
||||
#if !defined(VFS_WIN32_NO_NATIVE) && defined(_WIN32) && !defined(_XBOX) \
|
||||
&& !defined(__WINRT__) && defined(VFS_HAVE_AT_HANDLE)
|
||||
#define VFS_NATIVE 1
|
||||
#define RFILE_HINT_WIN32_NATIVE (1 << 9)
|
||||
#ifndef INVALID_FILE_SIZE
|
||||
#define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF)
|
||||
#endif
|
||||
#define VFS_NATIVE_BUF 0x10000
|
||||
static bool vfs_native_open(libretro_vfs_implementation_file *stream,
|
||||
const char *path);
|
||||
|
||||
Reference in new issue
Block a user