fs: implement AccessLog, enable for File operations
This commit is contained in:
@@ -21,47 +21,74 @@ namespace ams::sf {
|
||||
|
||||
namespace {
|
||||
|
||||
thread_local InlineContext g_inline_context;
|
||||
ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext(os::ThreadType *thread) {
|
||||
static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<uintptr_t>));
|
||||
return reinterpret_cast<std::atomic<uintptr_t> *>(std::addressof(thread->atomic_sf_inline_context));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void OnSetInlineContext() {
|
||||
ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext() {
|
||||
return GetAtomicSfInlineContext(os::GetCurrentThread());
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void OnSetInlineContext(os::ThreadType *thread) {
|
||||
/* Ensure that libnx receives the priority value. */
|
||||
::fsSetPriority(static_cast<::FsPriority>(::ams::sf::GetFsInlineContext()));
|
||||
::fsSetPriority(static_cast<::FsPriority>(::ams::sf::GetFsInlineContext(thread)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InlineContext GetInlineContext() {
|
||||
/* Get current thread. */
|
||||
os::ThreadType * const cur_thread = os::GetCurrentThread();
|
||||
|
||||
/* Get the context. */
|
||||
uintptr_t thread_context = GetAtomicSfInlineContext()->load();
|
||||
|
||||
/* Copy it out. */
|
||||
InlineContext ctx;
|
||||
std::memcpy(std::addressof(ctx), std::addressof(::ams::sf::cmif::g_inline_context), sizeof(ctx));
|
||||
static_assert(sizeof(ctx) <= sizeof(thread_context));
|
||||
std::memcpy(std::addressof(ctx), std::addressof(thread_context), sizeof(ctx));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
InlineContext SetInlineContext(InlineContext ctx) {
|
||||
ON_SCOPE_EXIT { OnSetInlineContext(); };
|
||||
static_assert(sizeof(ctx) <= sizeof(g_inline_context));
|
||||
/* Get current thread. */
|
||||
os::ThreadType * const cur_thread = os::GetCurrentThread();
|
||||
ON_SCOPE_EXIT { OnSetInlineContext(cur_thread); };
|
||||
|
||||
/* Create the new context. */
|
||||
static_assert(sizeof(ctx) <= sizeof(uintptr_t));
|
||||
uintptr_t new_context_value = 0;
|
||||
std::memcpy(std::addressof(new_context_value), std::addressof(ctx), sizeof(ctx));
|
||||
|
||||
/* Get the old context. */
|
||||
uintptr_t old_context_value = GetAtomicSfInlineContext()->exchange(new_context_value);
|
||||
|
||||
/* Convert and copy it out. */
|
||||
InlineContext old_ctx;
|
||||
std::memcpy(std::addressof(old_ctx), std::addressof(g_inline_context), sizeof(old_ctx));
|
||||
std::memcpy(std::addressof(g_inline_context), std::addressof(ctx), sizeof(ctx));
|
||||
std::memcpy(std::addressof(old_ctx), std::addressof(old_context_value), sizeof(old_ctx));
|
||||
return old_ctx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u8 GetFsInlineContext() {
|
||||
u8 ctx;
|
||||
std::memcpy(std::addressof(ctx), std::addressof(cmif::g_inline_context), sizeof(ctx));
|
||||
return ctx;
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE std::atomic<u8> *GetAtomicFsInlineContext(os::ThreadType *thread) {
|
||||
static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<u8>));
|
||||
return reinterpret_cast<std::atomic<u8> *>(std::addressof(thread->atomic_sf_inline_context));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u8 SetFsInlineContext(u8 ctx) {
|
||||
ON_SCOPE_EXIT { cmif::OnSetInlineContext(); };
|
||||
static_assert(sizeof(ctx) <= sizeof(cmif::g_inline_context));
|
||||
u8 GetFsInlineContext(os::ThreadType *thread) {
|
||||
return GetAtomicFsInlineContext(thread)->load();
|
||||
}
|
||||
|
||||
u8 old_ctx;
|
||||
std::memcpy(std::addressof(old_ctx), std::addressof(cmif::g_inline_context), sizeof(old_ctx));
|
||||
std::memcpy(std::addressof(cmif::g_inline_context), std::addressof(ctx), sizeof(ctx));
|
||||
return old_ctx;
|
||||
u8 SetFsInlineContext(os::ThreadType *thread, u8 ctx) {
|
||||
ON_SCOPE_EXIT { cmif::OnSetInlineContext(thread); };
|
||||
|
||||
return GetAtomicFsInlineContext(thread)->exchange(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user