mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
The review of the save file use count found that fs_host.c file_release took `lock` exclusive whenever users dropped to 0, which is the end of every single read_file, write_file, file_size, set_file_size and flush_file, not only when a CloseFile had marked the slot. The exclusive acquisition waits for every shared holder, such as the fsync loop of a non-save Commit (commit, FlushFileBuffers under the shared lock), and while it waits it holds up new file_of callers: a new wait on the guest threads that the change had said it did not add. file_release now takes the lock only when it finds closing set after its decrement. The decrement and the load of closing, and close_file's store of closing and load of users, are sequentially consistent pairs, so either the last call out sees the mark or close_file sees users at 0 and closes the file itself; the check under the lock still keeps the close to one. closing is an int32_t read and stored with atomics; a slot is emptied by the new file_clear, which stores users and closing as atomics because the call that has just left the slot may read closing without the lock, and open_file fills only h, mode and save. Not reproduced in the game before the change. tests/fs_file_use_check.py gains a case: 1000 reads with no close take the exclusive lock 0 times, and a read ends while another thread holds the lock shared. It failed on the code before this change (1000 exclusive takes, the read waited) and passes after it, as do its close-during-a-read case and its 20000 closes and opens beside a reader (six runs, no foreign bytes, no double close). The compile check of fs_host.c passes with no -Wall warnings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 KiB
103 KiB