Files
RetroArch/samples/tasks/cloudsync/Makefile
T
LibretroAdmin 7b0159d5b8 cloud_sync: hand calls and results to the worker without a lock
A blocking driver's calls reach the worker on a many-producer stack and
its results come back on another; the worker parks on an eventcount
when the sync is still open and the queue is empty, and leaves once it
ends. A call queued as the worker leaves either starts a new worker or
is taken by the leaving one. cloud_sync_deinit() waits for the worker
on an eventcount, still bounded by its timeout.

Without pointer atomics the calls run directly, as without threads.

The async test queues a sync from the worker's leaving point.
2026-10-29 22:31:19 +01:00

142 lines
5.7 KiB
Makefile

# Regression tests for cloud sync:
# - cloudsync_savefile_owner_test: the save-file ownership predicate
# cloud sync consults before it replaces or removes a local file, and
# the manifest key lookup its carry-forward depends on.
# - cloudsync_path_safety_test: the manifest-key path-traversal guard
# (tasks/task_cloudsync_path.c, #included by the test).
# - cloudsync_manifest_adds_test: entries added to the updated
# manifests from several threads at once, with no lock
# (tasks/task_cloudsync.c, #included by the test).
# - cloudsync_pacing_test: the diff runs as much as the shared
# per-frame I/O window grants, hashing large files a chunk at a time
# (tasks/task_cloudsync.c, #included by the test).
# - cloudsync_async_test: a blocking driver's calls run on a worker
# and complete through cloud_sync_poll() on the caller's thread
# (network/cloud_sync_driver.c).
#
# make check
# make check SANITIZER=address
# make check SANITIZER=undefined
include ../../sample_objdir.mk
TARGET := cloudsync_savefile_owner_test
PATH_TARGET := cloudsync_path_safety_test
CORE_DIR := ../../..
LIBRETRO_COMM_DIR := $(CORE_DIR)/libretro-common
SOURCES := \
cloudsync_savefile_owner_test.c \
$(LIBRETRO_COMM_DIR)/lists/string_list.c \
$(LIBRETRO_COMM_DIR)/lists/file_list.c \
$(LIBRETRO_COMM_DIR)/lists/dir_list.c \
$(LIBRETRO_COMM_DIR)/file/retro_dirent.c \
$(LIBRETRO_COMM_DIR)/file/file_path.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c \
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \
$(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \
$(LIBRETRO_COMM_DIR)/time/rtime.c \
$(LIBRETRO_COMM_DIR)/string/rstrtod.c \
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c
OBJS := $(call sample_objs,$(SOURCES:.c=.o))
PATH_OBJS := cloudsync_path_safety_test.o
# Built in one step with the task's own defines: the library objects
# above are compiled without threads.
ADDS_TARGET := cloudsync_manifest_adds_test
ADDS_SOURCES := cloudsync_manifest_adds_test.c \
$(filter-out cloudsync_savefile_owner_test.c,$(SOURCES)) \
$(CORE_DIR)/tasks/task_cloudsync_path.c \
$(LIBRETRO_COMM_DIR)/formats/json/rjson.c \
$(LIBRETRO_COMM_DIR)/utils/md5.c \
$(LIBRETRO_COMM_DIR)/queues/task_queue.c \
$(LIBRETRO_COMM_DIR)/features/features_cpu.c \
$(LIBRETRO_COMM_DIR)/rthreads/rthreads.c \
$(LIBRETRO_COMM_DIR)/rthreads/retro_eventcount.c
PACING_TARGET := cloudsync_pacing_test
COMMIT_TARGET := cloudsync_commit_test
ASYNC_TARGET := cloudsync_async_test
ASYNC_SOURCES := cloudsync_async_test.c \
$(CORE_DIR)/network/cloud_sync_driver.c \
$(LIBRETRO_COMM_DIR)/rthreads/rthreads.c \
$(LIBRETRO_COMM_DIR)/rthreads/retro_eventcount.c \
$(LIBRETRO_COMM_DIR)/features/features_cpu.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c \
$(LIBRETRO_COMM_DIR)/file/file_path.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \
$(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \
$(LIBRETRO_COMM_DIR)/time/rtime.c \
$(LIBRETRO_COMM_DIR)/string/rstrtod.c
ASYNC_DEFS := -DHAVE_THREADS -DRARCH_INTERNAL -DHAVE_CLOUDSYNC \
-DHAVE_NETWORKING -DCLOUD_SYNC_TEST_HOOKS
ADDS_DEFS := -DHAVE_THREADS -DRARCH_INTERNAL -DHAVE_CLOUDSYNC \
-DHAVE_NETWORKING -I$(CORE_DIR)/deps
# FORCE_LOCK=1: the hand-over under tcs_manifest_lock, as a backend with
# no pointer atomics builds it, on this host's backend
ifneq ($(FORCE_LOCK),)
ADDS_DEFS += -DTASK_CLOUDSYNC_FORCE_LOCK
endif
CFLAGS += -Wall -pedantic -std=gnu99 -g1 -O1 -fno-omit-frame-pointer \
-I$(LIBRETRO_COMM_DIR)/include -I$(CORE_DIR)
ifneq ($(SANITIZER),)
CFLAGS := -fsanitize=$(SANITIZER) $(CFLAGS)
LDFLAGS := -fsanitize=$(SANITIZER) $(LDFLAGS)
endif
all: $(TARGET) $(PATH_TARGET) $(ADDS_TARGET) $(PACING_TARGET) $(ASYNC_TARGET) $(COMMIT_TARGET)
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
$(SAMPLE_OBJDIR)/%.o: $$(call sample_src,$$*).c
@mkdir -p $(@D)
$(CC) -c -o $@ $< $(CFLAGS)
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(LDFLAGS)
$(PATH_TARGET): $(PATH_OBJS)
$(CC) -o $@ $^ $(LDFLAGS)
$(ADDS_TARGET): $(ADDS_SOURCES) $(CORE_DIR)/tasks/task_cloudsync.c
$(CC) -o $@ $(ADDS_SOURCES) $(filter-out -pedantic,$(CFLAGS)) $(ADDS_DEFS) $(LDFLAGS) -lpthread
$(PACING_TARGET): cloudsync_pacing_test.c $(filter-out cloudsync_manifest_adds_test.c,$(ADDS_SOURCES)) $(CORE_DIR)/tasks/task_cloudsync.c
$(CC) -o $@ cloudsync_pacing_test.c $(filter-out cloudsync_manifest_adds_test.c,$(ADDS_SOURCES)) $(filter-out -pedantic,$(CFLAGS)) $(ADDS_DEFS) $(LDFLAGS) -lpthread
$(ASYNC_TARGET): $(ASYNC_SOURCES) $(CORE_DIR)/network/cloud_sync_driver.h
$(CC) -o $@ $(ASYNC_SOURCES) $(filter-out -pedantic,$(CFLAGS)) $(ASYNC_DEFS) $(LDFLAGS) -lpthread
$(COMMIT_TARGET): cloudsync_commit_test.c $(filter-out cloudsync_manifest_adds_test.c,$(ADDS_SOURCES)) $(CORE_DIR)/tasks/task_cloudsync.c
$(CC) -o $@ cloudsync_commit_test.c $(filter-out cloudsync_manifest_adds_test.c,$(ADDS_SOURCES)) $(filter-out -pedantic,$(CFLAGS)) $(ADDS_DEFS) $(LDFLAGS) -lpthread
check: $(TARGET) $(PATH_TARGET) $(ADDS_TARGET) $(PACING_TARGET) $(ASYNC_TARGET) $(COMMIT_TARGET)
./$(TARGET)
./$(PATH_TARGET)
./$(ADDS_TARGET)
./$(PACING_TARGET)
./$(ASYNC_TARGET)
./$(COMMIT_TARGET)
clean:
rm -rf $(SAMPLE_OBJDIR)
rm -f $(TARGET) $(OBJS) $(PATH_TARGET) $(PATH_OBJS) $(ADDS_TARGET) $(PACING_TARGET) $(ASYNC_TARGET) $(COMMIT_TARGET) $(COMMIT_TARGET).exe
.PHONY: all check clean