mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-13 17:58:56 +02:00
restore stupid lock, make ps4sup library
This commit is contained in:
parent
f792712a66
commit
9dbd0bb57b
21 changed files with 71 additions and 43 deletions
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
|
|||
|
|
@ -134,3 +134,9 @@ target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
|
|||
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
|
||||
|
||||
add_test(NAME dynarmic_tests COMMAND dynarmic_tests --durations yes)
|
||||
|
||||
if (PLATFORM_PS4)
|
||||
target_link_libraries(dynarmic_tests PRIVATE SceVideoOut SceAudioOut ScePad SceSystemService)
|
||||
target_link_libraries(dynarmic_tests PRIVATE ps4sup)
|
||||
create_ps4_eboot(dynarmic_tests dynarmic_tests IV0000-BREW00090_00-DYNARMICTS000000)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ Result ResourceManager::CreateAppletResource(u64 aruid) {
|
|||
}
|
||||
|
||||
Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
return applet_resource->CreateAppletResource(aruid);
|
||||
}
|
||||
|
||||
|
|
@ -294,17 +294,17 @@ void ResourceManager::InitializeAHidSampler() {
|
|||
}
|
||||
|
||||
Result ResourceManager::RegisterCoreAppletResource() {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
return applet_resource->RegisterCoreAppletResource();
|
||||
}
|
||||
|
||||
Result ResourceManager::UnregisterCoreAppletResource() {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
return applet_resource->UnregisterCoreAppletResource();
|
||||
}
|
||||
|
||||
Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
auto result = applet_resource->RegisterAppletResourceUserId(aruid, bool_value);
|
||||
if (result.IsSuccess()) {
|
||||
result = npad->RegisterAppletResourceUserId(aruid);
|
||||
|
|
@ -313,40 +313,40 @@ Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value)
|
|||
}
|
||||
|
||||
void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
applet_resource->UnregisterAppletResourceUserId(aruid);
|
||||
npad->UnregisterAppletResourceUserId(aruid);
|
||||
// palma->UnregisterAppletResourceUserId(aruid);
|
||||
}
|
||||
|
||||
Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
return applet_resource->GetSharedMemoryHandle(out_handle, aruid);
|
||||
}
|
||||
|
||||
void ResourceManager::FreeAppletResourceId(u64 aruid) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
applet_resource->FreeAppletResourceId(aruid);
|
||||
npad->FreeAppletResourceId(aruid);
|
||||
}
|
||||
|
||||
void ResourceManager::EnableInput(u64 aruid, bool is_enabled) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
applet_resource->EnableInput(aruid, is_enabled);
|
||||
}
|
||||
|
||||
void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
applet_resource->EnableSixAxisSensor(aruid, is_enabled);
|
||||
}
|
||||
|
||||
void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
applet_resource->EnablePadInput(aruid, is_enabled);
|
||||
}
|
||||
|
||||
void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
applet_resource->EnableTouchScreen(aruid, is_enabled);
|
||||
}
|
||||
|
||||
|
|
@ -371,7 +371,7 @@ NpadGcVibrationDevice* ResourceManager::GetGcVibrationDevice(
|
|||
}
|
||||
|
||||
Result ResourceManager::SetAruidValidForVibration(u64 aruid, bool is_enabled) {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
const bool has_changed = applet_resource->SetAruidValidForVibration(aruid, is_enabled);
|
||||
|
||||
if (has_changed) {
|
||||
|
|
@ -394,7 +394,7 @@ void ResourceManager::SetForceHandheldStyleVibration(bool is_forced) {
|
|||
}
|
||||
|
||||
Result ResourceManager::IsVibrationAruidActive(u64 aruid, bool& is_active) const {
|
||||
//std::scoped_lock lock{shared_mutex};
|
||||
std::scoped_lock lock{shared_mutex};
|
||||
is_active = applet_resource->IsVibrationAruidActive(aruid);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ void AbstractPad::Update() {
|
|||
|
||||
interface_type = properties_handler.GetInterfaceType();
|
||||
|
||||
//std::scoped_lock lock{*applet_resource_holder->shared_mutex};
|
||||
std::scoped_lock lock{*applet_resource_holder->shared_mutex};
|
||||
properties_handler.UpdateAllDeviceProperties();
|
||||
battery_handler.UpdateCoreBatteryState();
|
||||
button_handler.UpdateCoreBatteryState();
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ void DebugPad::OnInit() {}
|
|||
void DebugPad::OnRelease() {}
|
||||
|
||||
void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ void Digitizer::OnInit() {}
|
|||
void Digitizer::OnRelease() {}
|
||||
|
||||
void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ void Keyboard::OnInit() {}
|
|||
void Keyboard::OnRelease() {}
|
||||
|
||||
void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ void DebugMouse::OnInit() {}
|
|||
void DebugMouse::OnRelease() {}
|
||||
|
||||
void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ void Mouse::OnInit() {}
|
|||
void Mouse::OnRelease() {}
|
||||
|
||||
void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ Result NPad::Activate() {
|
|||
|
||||
Result NPad::Activate(u64 aruid) {
|
||||
std::scoped_lock lock{mutex};
|
||||
//std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
|
||||
std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
|
||||
|
||||
auto* data = applet_resource_holder.applet_resource->GetAruidData(aruid);
|
||||
const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
|
||||
|
|
@ -393,7 +393,7 @@ void NPad::WriteEmptyEntry(NpadInternalState* npad) {
|
|||
}
|
||||
|
||||
void NPad::RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id) {
|
||||
//std::scoped_lock lock{*applet_resource_holder.shared_mutex};
|
||||
std::scoped_lock lock{*applet_resource_holder.shared_mutex};
|
||||
auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
|
||||
const auto controller_type = controller.device->GetNpadStyleIndex();
|
||||
|
||||
|
|
@ -466,7 +466,7 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
|||
return;
|
||||
}
|
||||
|
||||
//std::scoped_lock lock{*applet_resource_holder.shared_mutex};
|
||||
std::scoped_lock lock{*applet_resource_holder.shared_mutex};
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
|
||||
const auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
||||
|
|
@ -1221,7 +1221,7 @@ Result NPad::SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled) {
|
|||
const auto result = npad_resource.SetNpadSystemExtStateEnabled(aruid, is_enabled);
|
||||
|
||||
if (result.IsSuccess()) {
|
||||
//std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
|
||||
std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
|
||||
// TODO: abstracted_pad->EnableAppletToGetInput(aruid);
|
||||
}
|
||||
|
||||
|
|
@ -1339,7 +1339,7 @@ void NPad::UpdateHandheldAbstractState() {
|
|||
|
||||
void NPad::EnableAppletToGetInput(u64 aruid) {
|
||||
std::scoped_lock lock{mutex};
|
||||
//std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
|
||||
std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
|
||||
for (auto& abstract_pad : abstracted_pads) {
|
||||
abstract_pad.EnableAppletToGetInput(aruid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ void ConsoleSixAxis::OnInit() {}
|
|||
void ConsoleSixAxis::OnRelease() {}
|
||||
|
||||
void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ void SixAxis::OnInit() {}
|
|||
void SixAxis::OnRelease() {}
|
||||
|
||||
void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
|
||||
const auto* data = applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void CaptureButton::OnInit() {}
|
|||
void CaptureButton::OnRelease() {}
|
||||
|
||||
void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void HomeButton::OnInit() {}
|
|||
void HomeButton::OnRelease() {}
|
||||
|
||||
void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ void SleepButton::OnInit() {}
|
|||
void SleepButton::OnRelease() {}
|
||||
|
||||
void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
//std::scoped_lock shared_lock{*shared_mutex};
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Result TouchResource::ActivateTouch() {
|
|||
}
|
||||
|
||||
if (global_ref_counter == 0) {
|
||||
//std::scoped_lock lock{*shared_mutex};
|
||||
std::scoped_lock lock{*shared_mutex};
|
||||
|
||||
const auto result = touch_driver->StartTouchSensor();
|
||||
if (result.IsError()) {
|
||||
|
|
@ -60,7 +60,7 @@ Result TouchResource::ActivateTouch() {
|
|||
}
|
||||
|
||||
Result TouchResource::ActivateTouch(u64 aruid) {
|
||||
//std::scoped_lock lock{*shared_mutex};
|
||||
std::scoped_lock lock{*shared_mutex};
|
||||
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
|
||||
auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
|
@ -121,7 +121,7 @@ Result TouchResource::ActivateGesture() {
|
|||
}
|
||||
|
||||
Result TouchResource::ActivateGesture(u64 aruid, u32 basic_gesture_id) {
|
||||
//std::scoped_lock lock{*shared_mutex};
|
||||
std::scoped_lock lock{*shared_mutex};
|
||||
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
|
||||
auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
|
@ -300,7 +300,7 @@ void TouchResource::SetTouchScreenMagnification(f32 point1_x, f32 point1_y, f32
|
|||
}
|
||||
|
||||
Result TouchResource::SetTouchScreenResolution(u32 width, u32 height, u64 aruid) {
|
||||
//std::scoped_lock lock{*shared_mutex};
|
||||
std::scoped_lock lock{*shared_mutex};
|
||||
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
|
||||
const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
|
@ -321,7 +321,7 @@ Result TouchResource::SetTouchScreenResolution(u32 width, u32 height, u64 aruid)
|
|||
|
||||
Result TouchResource::SetTouchScreenConfiguration(
|
||||
const Core::HID::TouchScreenConfigurationForNx& touch_configuration, u64 aruid) {
|
||||
//std::scoped_lock lock{*shared_mutex};
|
||||
std::scoped_lock lock{*shared_mutex};
|
||||
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
|
||||
const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
|
@ -341,7 +341,7 @@ Result TouchResource::SetTouchScreenConfiguration(
|
|||
|
||||
Result TouchResource::GetTouchScreenConfiguration(
|
||||
Core::HID::TouchScreenConfigurationForNx& out_touch_configuration, u64 aruid) const {
|
||||
//std::scoped_lock lock{*shared_mutex};
|
||||
std::scoped_lock lock{*shared_mutex};
|
||||
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
|
||||
const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
|
@ -518,7 +518,7 @@ void TouchResource::OnTouchUpdate(s64 timestamp) {
|
|||
gesture_handler.SetTouchState(current_touch_state.states, current_touch_state.entry_count,
|
||||
timestamp);
|
||||
|
||||
//std::scoped_lock lock{*shared_mutex};
|
||||
std::scoped_lock lock{*shared_mutex};
|
||||
|
||||
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
|
||||
const auto* applet_data = applet_resource->GetAruidDataByIndex(aruid_index);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ add_executable(yuzu-cmd
|
|||
sdl_config.cpp
|
||||
sdl_config.h
|
||||
yuzu.cpp
|
||||
emutls.c
|
||||
yuzu.rc
|
||||
)
|
||||
|
||||
|
|
@ -35,8 +34,6 @@ target_link_libraries(yuzu-cmd PRIVATE common core input_common frontend_common
|
|||
target_link_libraries(yuzu-cmd PRIVATE glad)
|
||||
if (MSVC)
|
||||
target_link_libraries(yuzu-cmd PRIVATE getopt)
|
||||
elseif(PLATFORM_PS4)
|
||||
target_link_libraries(yuzu-cmd PRIVATE SceVideoOut SceAudioOut ScePad SceSystemService)
|
||||
endif()
|
||||
target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
||||
|
||||
|
|
@ -71,6 +68,7 @@ if (NOT MSVC)
|
|||
endif()
|
||||
|
||||
if (PLATFORM_PS4)
|
||||
target_link_libraries(yuzu-cmd PRIVATE SceVideoOut SceAudioOut ScePad SceSystemService)
|
||||
target_link_libraries(yuzu-cmd PRIVATE ps4sup)
|
||||
create_ps4_eboot(yuzu-cmd eden-cli IV0000-BREW00090_00-EDENEMULAT000000)
|
||||
#create_ps4_pkg(yuzu-cmd eden-cli IV0000-BREW00090_00-EDENEMULAT000000)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,181 +0,0 @@
|
|||
/* ===---------- emutls.c - Implements __emutls_get_address ---------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//#include "int_util.h"
|
||||
|
||||
/* Default is not to use posix_memalign, so systems like Android
|
||||
* can use thread local data without heavier POSIX memory allocators.
|
||||
*/
|
||||
#ifndef EMUTLS_USE_POSIX_MEMALIGN
|
||||
#define EMUTLS_USE_POSIX_MEMALIGN 0
|
||||
#endif
|
||||
|
||||
/* For every TLS variable xyz,
|
||||
* there is one __emutls_control variable named __emutls_v.xyz.
|
||||
* If xyz has non-zero initial value, __emutls_v.xyz's "value"
|
||||
* will point to __emutls_t.xyz, which has the initial value.
|
||||
*/
|
||||
typedef struct __emutls_control {
|
||||
size_t size; /* size of the object in bytes */
|
||||
size_t align; /* alignment of the object in bytes */
|
||||
union {
|
||||
uintptr_t index; /* data[index-1] is the object address */
|
||||
void* address; /* object address, when in single thread env */
|
||||
} object;
|
||||
void* value; /* null or non-zero initial value for the object */
|
||||
} __emutls_control;
|
||||
|
||||
static inline void* emutls_memalign_alloc(size_t align, size_t size) {
|
||||
void *base;
|
||||
#if EMUTLS_USE_POSIX_MEMALIGN
|
||||
if (posix_memalign(&base, align, size) != 0)
|
||||
abort();
|
||||
#else
|
||||
#define EXTRA_ALIGN_PTR_BYTES (align - 1 + sizeof(void*))
|
||||
char* object;
|
||||
if ((object = malloc(EXTRA_ALIGN_PTR_BYTES + size)) == NULL)
|
||||
abort();
|
||||
base = (void*)(((uintptr_t)(object + EXTRA_ALIGN_PTR_BYTES))
|
||||
& ~(uintptr_t)(align - 1));
|
||||
|
||||
((void**)base)[-1] = object;
|
||||
#endif
|
||||
return base;
|
||||
}
|
||||
|
||||
static inline void emutls_memalign_free(void* base) {
|
||||
#if EMUTLS_USE_POSIX_MEMALIGN
|
||||
free(base);
|
||||
#else
|
||||
/* The mallocated address is in ((void**)base)[-1] */
|
||||
free(((void**)base)[-1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Emulated TLS objects are always allocated at run-time. */
|
||||
static inline void* emutls_allocate_object(__emutls_control* control) {
|
||||
/* Use standard C types, check with gcc's emutls.o. */
|
||||
//typedef unsigned int gcc_word __attribute__((mode(word)));
|
||||
//typedef unsigned int gcc_pointer __attribute__((mode(pointer)));
|
||||
//COMPILE_TIME_ASSERT(sizeof(size_t) == sizeof(gcc_word));
|
||||
//COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(gcc_pointer));
|
||||
//COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(void*));
|
||||
|
||||
size_t size = control->size;
|
||||
size_t align = control->align;
|
||||
if (align < sizeof(void*))
|
||||
align = sizeof(void*);
|
||||
/* Make sure that align is power of 2. */
|
||||
if ((align & (align - 1)) != 0)
|
||||
abort();
|
||||
|
||||
void* base = emutls_memalign_alloc(align, size);
|
||||
if (control->value)
|
||||
memcpy(base, control->value, size);
|
||||
else
|
||||
memset(base, 0, size);
|
||||
return base;
|
||||
}
|
||||
|
||||
static pthread_mutex_t emutls_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static size_t emutls_num_object = 0; /* number of allocated TLS objects */
|
||||
|
||||
typedef struct emutls_address_array {
|
||||
uintptr_t size; /* number of elements in the 'data' array */
|
||||
void* data[];
|
||||
} emutls_address_array;
|
||||
|
||||
static pthread_key_t emutls_pthread_key;
|
||||
|
||||
static void emutls_key_destructor(void* ptr) {
|
||||
emutls_address_array* array = (emutls_address_array*)ptr;
|
||||
uintptr_t i;
|
||||
for (i = 0; i < array->size; ++i) {
|
||||
if (array->data[i])
|
||||
emutls_memalign_free(array->data[i]);
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void emutls_init(void) {
|
||||
if (pthread_key_create(&emutls_pthread_key, emutls_key_destructor) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Returns control->object.index; set index if not allocated yet. */
|
||||
static inline uintptr_t emutls_get_index(__emutls_control* control) {
|
||||
uintptr_t index = __atomic_load_n(&control->object.index, __ATOMIC_ACQUIRE);
|
||||
if (!index) {
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&once, emutls_init);
|
||||
pthread_mutex_lock(&emutls_mutex);
|
||||
index = control->object.index;
|
||||
if (!index) {
|
||||
index = ++emutls_num_object;
|
||||
__atomic_store_n(&control->object.index, index, __ATOMIC_RELEASE);
|
||||
}
|
||||
pthread_mutex_unlock(&emutls_mutex);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Updates newly allocated thread local emutls_address_array. */
|
||||
static inline void emutls_check_array_set_size(emutls_address_array* array,
|
||||
uintptr_t size) {
|
||||
if (array == NULL)
|
||||
abort();
|
||||
array->size = size;
|
||||
pthread_setspecific(emutls_pthread_key, (void*)array);
|
||||
}
|
||||
|
||||
/* Returns the new 'data' array size, number of elements,
|
||||
* which must be no smaller than the given index.
|
||||
*/
|
||||
static inline uintptr_t emutls_new_data_array_size(uintptr_t index) {
|
||||
/* Need to allocate emutls_address_array with one extra slot
|
||||
* to store the data array size.
|
||||
* Round up the emutls_address_array size to multiple of 16.
|
||||
*/
|
||||
return ((index + 1 + 15) & ~((uintptr_t)15)) - 1;
|
||||
}
|
||||
|
||||
/* Returns the thread local emutls_address_array.
|
||||
* Extends its size if necessary to hold address at index.
|
||||
*/
|
||||
static inline emutls_address_array* emutls_get_address_array(uintptr_t index) {
|
||||
emutls_address_array* array = pthread_getspecific(emutls_pthread_key);
|
||||
if (array == NULL) {
|
||||
uintptr_t new_size = emutls_new_data_array_size(index);
|
||||
array = calloc(new_size + 1, sizeof(void*));
|
||||
emutls_check_array_set_size(array, new_size);
|
||||
} else if (index > array->size) {
|
||||
uintptr_t orig_size = array->size;
|
||||
uintptr_t new_size = emutls_new_data_array_size(index);
|
||||
array = realloc(array, (new_size + 1) * sizeof(void*));
|
||||
if (array)
|
||||
memset(array->data + orig_size, 0,
|
||||
(new_size - orig_size) * sizeof(void*));
|
||||
emutls_check_array_set_size(array, new_size);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
void* __emutls_get_address(__emutls_control* control) {
|
||||
uintptr_t index = emutls_get_index(control);
|
||||
emutls_address_array* array = emutls_get_address_array(index);
|
||||
if (array->data[index - 1] == NULL)
|
||||
array->data[index - 1] = emutls_allocate_object(control);
|
||||
return array->data[index - 1];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue