mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
Merge branch 'master' into mvk-1211
This commit is contained in:
commit
2983192094
12 changed files with 250 additions and 225 deletions
|
@ -3,18 +3,18 @@
|
|||
# shellcheck disable=SC2086
|
||||
brew_arm64_install_packages() {
|
||||
for pkg in "$@"; do
|
||||
echo "Fetching bottle for $pkg..."
|
||||
bottle_path="$("$BREW_ARM64_PATH/bin/brew" --cache --bottle-tag=arm64_sonoma "$pkg")"
|
||||
echo "Fetching bottle for $pkg (arm64)..."
|
||||
bottle_path="$("$BREW_ARM64_PATH/bin/brew" --cache --bottle-tag=arm64_ventura "$pkg")"
|
||||
if [ ! -f "$bottle_path" ]; then
|
||||
if ! "$BREW_ARM64_PATH/bin/brew" fetch --force --bottle-tag=arm64_sonoma "$pkg"; then
|
||||
if ! "$BREW_ARM64_PATH/bin/brew" fetch --force --verbose --debug --bottle-tag=arm64_ventura "$pkg"; then
|
||||
echo "Failed to fetch bottle for $pkg"
|
||||
return 1
|
||||
fi
|
||||
bottle_path="$("$BREW_ARM64_PATH/bin/brew" --cache --bottle-tag=arm64_sonoma "$pkg")"
|
||||
bottle_path="$("$BREW_ARM64_PATH/bin/brew" --cache --bottle-tag=arm64_ventura "$pkg")"
|
||||
fi
|
||||
|
||||
echo "Installing $pkg..."
|
||||
"$BREW_ARM64_PATH/bin/brew" install --ignore-dependencies "$bottle_path" || true
|
||||
echo "Installing $pkg (arm64)..."
|
||||
"$BREW_ARM64_PATH/bin/brew" install --force --force-bottle --ignore-dependencies "$bottle_path" || true
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,14 @@ export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
|||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
||||
|
||||
/usr/local/bin/brew update
|
||||
sudo rm -rf /usr/local/Cellar/curl /usr/local/opt/curl
|
||||
/usr/local/bin/brew install -f --overwrite curl
|
||||
/usr/local/bin/brew uninstall -f --ignore-dependencies ffmpeg
|
||||
/usr/local/bin/brew install -f --build-from-source ffmpeg@5 || true
|
||||
/usr/local/bin/brew install -f --overwrite python || true
|
||||
/usr/local/bin/brew link --overwrite python || true
|
||||
/usr/local/bin/brew install -f --overwrite nasm ninja p7zip ccache pipenv #create-dmg
|
||||
/usr/local/bin/brew link -f curl || true
|
||||
/usr/local/bin/brew install llvm@$LLVM_COMPILER_VER glew cmake sdl2 vulkan-headers coreutils
|
||||
/usr/local/bin/brew link -f llvm@$LLVM_COMPILER_VER ffmpeg@5 || true
|
||||
|
||||
|
@ -34,8 +39,13 @@ sudo mkdir -p "$BREW_ARM64_PATH"
|
|||
sudo chmod 777 "$BREW_ARM64_PATH"
|
||||
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C "$BREW_ARM64_PATH"
|
||||
|
||||
"$BREW_ARM64_PATH/bin/brew" update
|
||||
brew_arm64_install_packages 0mq aom aribb24 ca-certificates cjson curl dav1d ffmpeg@5 fontconfig freetype freetype2 gettext glew gmp gnutls lame libbluray libidn2 libnettle libogg libpng librist libsodium libsoxr libtasn libtasn1 libunistring libvmaf libvorbis libvpx libx11 libxau libxcb libxdmcp llvm@$LLVM_COMPILER_VER mbedtls molten-vk nettle opencore-amr openjpeg openssl opus p11-kit pkg-config pkgconfig pzstd rav1e sdl2 snappy speex srt svt-av1 theora vulkan-headers webp x264 x265 xz z3 zeromq zmq zstd
|
||||
#"$BREW_ARM64_PATH/bin/brew" update
|
||||
# libvorbis requires Homebrew-installed curl, but we can't run it on x64, and we also need the aarch64 libs, so we swap the binary
|
||||
brew_arm64_install_packages curl
|
||||
mv /opt/homebrew1/opt/curl/bin/curl /opt/homebrew1/opt/curl/bin/curl.bak
|
||||
ln -s /usr/local/opt/curl/bin/curl /opt/homebrew1/opt/curl/bin/curl
|
||||
|
||||
brew_arm64_install_packages 0mq aom aribb24 ca-certificates cjson dav1d ffmpeg@5 fontconfig freetype freetype2 gettext glew gmp gnutls lame libbluray libidn2 libnettle libogg libpng librist libsodium libsoxr libtasn libtasn1 libunistring libvmaf libvorbis libvpx libx11 libxau libxcb libxdmcp llvm@$LLVM_COMPILER_VER mbedtls molten-vk nettle opencore-amr openjpeg openssl opus p11-kit pkg-config pkgconfig pzstd rav1e sdl2 snappy speex srt svt-av1 theora vulkan-headers webp x264 x265 xz z3 zeromq zmq zstd
|
||||
"$BREW_ARM64_PATH/bin/brew" link -f ffmpeg@5
|
||||
|
||||
# moltenvk based on commit for 1.2.11 release
|
||||
|
@ -125,6 +135,7 @@ export MACOSX_DEPLOYMENT_TARGET=13.0
|
|||
-DLLVM_TARGET_ARCH=arm64 \
|
||||
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
||||
-DCMAKE_IGNORE_PATH="$BREW_X64_PATH/lib" \
|
||||
-DCMAKE_IGNORE_PREFIX_PATH=/usr/local/opt \
|
||||
-DCMAKE_SYSTEM_PROCESSOR=arm64 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=buildfiles/cmake/TCDarwinARM64.cmake \
|
||||
-DCMAKE_CXX_FLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=130000" \
|
||||
|
|
|
@ -1673,6 +1673,12 @@ void spu_thread::cpu_init()
|
|||
status_npc.raw() = {get_type() == spu_type::isolated ? SPU_STATUS_IS_ISOLATED : 0, 0};
|
||||
run_ctrl.raw() = 0;
|
||||
|
||||
spurs_last_task_timestamp = 0;
|
||||
spurs_wait_duration_last = 0;
|
||||
spurs_average_task_duration = 0;
|
||||
spurs_waited = false;
|
||||
spurs_entered_wait = false;
|
||||
|
||||
int_ctrl[0].clear();
|
||||
int_ctrl[1].clear();
|
||||
int_ctrl[2].clear();
|
||||
|
@ -4890,53 +4896,71 @@ bool spu_thread::process_mfc_cmd()
|
|||
// Avoid logging useless commands if there is no reservation
|
||||
const bool dump = g_cfg.core.mfc_debug && raddr;
|
||||
|
||||
const bool is_spurs_task_wait = pc == 0x11e4 && spurs_addr == raddr && g_cfg.core.max_spurs_threads != g_cfg.core.max_spurs_threads.def && !spurs_waited;
|
||||
const bool is_spurs_task_wait = pc == 0x11e4 && spurs_addr;
|
||||
|
||||
if (is_spurs_task_wait)
|
||||
if (!is_spurs_task_wait || spurs_addr != raddr || spurs_waited)
|
||||
{
|
||||
//
|
||||
}
|
||||
else if ((_ref<u8>(0x100 + 0x73) & (1u << index)) == 0 && (static_cast<u8>(rdata[0x73]) & (1u << index)) != 0)
|
||||
{
|
||||
// Wait for other threads to complete their tasks (temporarily)
|
||||
u32 max_run = group->max_run;
|
||||
|
||||
u32 prev_running = group->spurs_running.fetch_op([max_run](u32& x)
|
||||
auto [prev_running, ok] = spurs_entered_wait ? std::make_pair(+group->spurs_running, false) :
|
||||
group->spurs_running.fetch_op([max_run, num = group->max_num](u32& x)
|
||||
{
|
||||
if (x >= max_run)
|
||||
if (x >= max_run && max_run < num)
|
||||
{
|
||||
x--;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
});
|
||||
|
||||
if (prev_running == max_run && prev_running != group->max_num)
|
||||
if (ok || spurs_entered_wait)
|
||||
{
|
||||
group->spurs_running.notify_one();
|
||||
lv2_obj::prepare_for_sleep(*this);
|
||||
|
||||
if (group->spurs_running == max_run - 1)
|
||||
if (ok)
|
||||
{
|
||||
// Try to let another thread slip in and take over execution
|
||||
thread_ctrl::wait_for(300);
|
||||
|
||||
// Try to quit waiting
|
||||
prev_running = group->spurs_running.fetch_op([max_run](u32& x)
|
||||
if (prev_running == max_run)
|
||||
{
|
||||
if (x < max_run)
|
||||
group->spurs_running.notify_one();
|
||||
|
||||
if (group->spurs_running == max_run - 1)
|
||||
{
|
||||
x++;
|
||||
return true;
|
||||
// Try to let another thread slip in and take over execution
|
||||
thread_ctrl::wait_for(300);
|
||||
|
||||
// Update value
|
||||
prev_running = group->spurs_running + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
// Restore state
|
||||
prev_running--;
|
||||
}
|
||||
}
|
||||
|
||||
if (prev_running >= max_run)
|
||||
{
|
||||
const u64 before = get_system_time();
|
||||
u64 current = before;
|
||||
|
||||
lv2_obj::prepare_for_sleep(*this);
|
||||
spurs_waited = true;
|
||||
spurs_entered_wait = true;
|
||||
|
||||
// Wait the duration of 3 tasks
|
||||
const u64 spurs_wait_time = std::clamp<u64>(spurs_average_task_duration / spurs_task_count_to_calculate * 3 + 2'000, 3'000, 100'000);
|
||||
spurs_wait_duration_last = spurs_wait_time;
|
||||
|
||||
if (spurs_last_task_timestamp)
|
||||
{
|
||||
const u64 avg_entry = spurs_average_task_duration / spurs_task_count_to_calculate;
|
||||
spurs_average_task_duration -= avg_entry;
|
||||
spurs_average_task_duration += std::min<u64>(45'000, before - spurs_last_task_timestamp);
|
||||
spu_log.trace("duration: %d, avg=%d", current - spurs_last_task_timestamp, spurs_average_task_duration / spurs_task_count_to_calculate);
|
||||
spurs_last_task_timestamp = 0;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -4945,7 +4969,10 @@ bool spu_thread::process_mfc_cmd()
|
|||
break;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_on(group->spurs_running, prev_running, 10000 - (current - before));
|
||||
if (prev_running >= max_run)
|
||||
{
|
||||
thread_ctrl::wait_on(group->spurs_running, prev_running, spurs_wait_time - (current - before));
|
||||
}
|
||||
|
||||
max_run = group->max_run;
|
||||
|
||||
|
@ -4967,9 +4994,10 @@ bool spu_thread::process_mfc_cmd()
|
|||
|
||||
current = get_system_time();
|
||||
|
||||
if (current - before >= 10000u)
|
||||
if (current - before >= spurs_wait_time)
|
||||
{
|
||||
// Timed-out
|
||||
group->spurs_running++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4979,11 +5007,27 @@ bool spu_thread::process_mfc_cmd()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (do_putllc(ch_mfc_cmd))
|
||||
{
|
||||
ch_atomic_stat.set_value(MFC_PUTLLC_SUCCESS);
|
||||
spurs_waited = false;
|
||||
|
||||
if (is_spurs_task_wait)
|
||||
{
|
||||
const u64 current = get_system_time();
|
||||
|
||||
if (spurs_last_task_timestamp)
|
||||
{
|
||||
const u64 avg_entry = spurs_average_task_duration / spurs_task_count_to_calculate;
|
||||
spurs_average_task_duration -= avg_entry;
|
||||
spu_log.trace("duration: %d, avg=%d", current - spurs_last_task_timestamp, spurs_average_task_duration / spurs_task_count_to_calculate);
|
||||
spurs_average_task_duration -= avg_entry;
|
||||
spurs_average_task_duration += std::min<u64>(45'000, current - spurs_last_task_timestamp);
|
||||
}
|
||||
|
||||
spurs_last_task_timestamp = current;
|
||||
spurs_waited = false;
|
||||
spurs_entered_wait = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5588,101 +5632,37 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
return events.events & mask1;
|
||||
}
|
||||
|
||||
const bool is_spurs_task_wait = pc == 0x11a8 && spurs_addr == raddr && g_cfg.core.max_spurs_threads != g_cfg.core.max_spurs_threads.def && !spurs_waited;
|
||||
|
||||
const auto wait_spurs_task = [&]
|
||||
{
|
||||
if (is_spurs_task_wait)
|
||||
{
|
||||
// Wait for other threads to complete their tasks (temporarily)
|
||||
if (!is_stopped())
|
||||
{
|
||||
u32 max_run = group->max_run;
|
||||
|
||||
u32 prev_running = group->spurs_running.fetch_op([max_run](u32& x)
|
||||
{
|
||||
if (x < max_run)
|
||||
{
|
||||
x++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
|
||||
if (prev_running >= max_run)
|
||||
{
|
||||
const u64 before = get_system_time();
|
||||
u64 current = before;
|
||||
|
||||
lv2_obj::prepare_for_sleep(*this);
|
||||
|
||||
spurs_waited = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (is_stopped())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_on(group->spurs_running, prev_running, 10000u - (current - before));
|
||||
|
||||
max_run = group->max_run;
|
||||
|
||||
prev_running = group->spurs_running.fetch_op([max_run](u32& x)
|
||||
{
|
||||
if (x < max_run)
|
||||
{
|
||||
x++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
|
||||
if (prev_running < max_run)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
current = get_system_time();
|
||||
|
||||
if (current - before >= 10000u)
|
||||
{
|
||||
// Timed-out
|
||||
group->spurs_running++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const bool is_spurs_task_wait = pc == 0x11a8 && spurs_addr == raddr;
|
||||
|
||||
if (is_spurs_task_wait)
|
||||
{
|
||||
const u32 prev_running = group->spurs_running.fetch_op([](u32& x)
|
||||
if (g_cfg.core.max_spurs_threads != g_cfg.core.max_spurs_threads.def && !spurs_entered_wait && (static_cast<u8>(rdata[0x73]) & (1u << index)))
|
||||
{
|
||||
if (x)
|
||||
const u32 prev_running = group->spurs_running.fetch_op([](u32& x)
|
||||
{
|
||||
x--;
|
||||
return true;
|
||||
if (x)
|
||||
{
|
||||
x--;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
|
||||
if (prev_running)
|
||||
{
|
||||
spurs_entered_wait = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
|
||||
if (prev_running == group->max_run && prev_running < group->max_num)
|
||||
{
|
||||
group->spurs_running.notify_one();
|
||||
|
||||
spurs_waited = true;
|
||||
|
||||
if (group->spurs_running == prev_running - 1)
|
||||
if (prev_running == group->max_run && prev_running < group->max_num)
|
||||
{
|
||||
// Try to let another thread slip in and take over execution
|
||||
thread_ctrl::wait_for(300);
|
||||
group->spurs_running.notify_one();
|
||||
|
||||
if (group->spurs_running == prev_running - 1)
|
||||
{
|
||||
// Try to let another thread slip in and take over execution
|
||||
thread_ctrl::wait_for(300);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5918,7 +5898,6 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
thread_ctrl::wait_on(state, old, 100);
|
||||
}
|
||||
|
||||
wait_spurs_task();
|
||||
wakeup_delay();
|
||||
|
||||
if (is_paused(state - cpu_flag::suspend))
|
||||
|
|
|
@ -188,10 +188,10 @@ struct spu_channel_op_state
|
|||
struct alignas(16) spu_channel
|
||||
{
|
||||
// Low 32 bits contain value
|
||||
atomic_t<u64> data;
|
||||
atomic_t<u64> data{};
|
||||
|
||||
// Pending value to be inserted when it is possible in pop() or pop_wait()
|
||||
atomic_t<u64> jostling_value;
|
||||
atomic_t<u64> jostling_value{};
|
||||
|
||||
public:
|
||||
static constexpr u32 off_wait = 32;
|
||||
|
@ -667,11 +667,11 @@ public:
|
|||
u8* reserv_base_addr = vm::g_reservations;
|
||||
|
||||
// General-Purpose Registers
|
||||
std::array<v128, 128> gpr;
|
||||
SPU_FPSCR fpscr;
|
||||
std::array<v128, 128> gpr{};
|
||||
SPU_FPSCR fpscr{};
|
||||
|
||||
// MFC command data
|
||||
spu_mfc_cmd ch_mfc_cmd;
|
||||
spu_mfc_cmd ch_mfc_cmd{};
|
||||
|
||||
// MFC command queue
|
||||
spu_mfc_cmd mfc_queue[16]{};
|
||||
|
@ -683,9 +683,9 @@ public:
|
|||
u64 mfc_last_timestamp = 0;
|
||||
|
||||
// MFC proxy command data
|
||||
spu_mfc_cmd mfc_prxy_cmd;
|
||||
spu_mfc_cmd mfc_prxy_cmd{};
|
||||
shared_mutex mfc_prxy_mtx;
|
||||
atomic_t<u32> mfc_prxy_mask;
|
||||
atomic_t<u32> mfc_prxy_mask = 0;
|
||||
|
||||
// Tracks writes to MFC proxy command data
|
||||
union
|
||||
|
@ -707,11 +707,11 @@ public:
|
|||
// Range Lock pointer
|
||||
atomic_t<u64, 64>* range_lock{};
|
||||
|
||||
u32 srr0;
|
||||
u32 ch_tag_upd;
|
||||
u32 ch_tag_mask;
|
||||
u32 srr0 = 0;
|
||||
u32 ch_tag_upd = 0;
|
||||
u32 ch_tag_mask = 0;
|
||||
spu_channel ch_tag_stat;
|
||||
u32 ch_stall_mask;
|
||||
u32 ch_stall_mask = 0;
|
||||
spu_channel ch_stall_stat;
|
||||
spu_channel ch_atomic_stat;
|
||||
|
||||
|
@ -736,14 +736,14 @@ public:
|
|||
};
|
||||
|
||||
atomic_t<ch_events_t> ch_events;
|
||||
bool interrupts_enabled;
|
||||
bool interrupts_enabled = false;
|
||||
|
||||
u64 ch_dec_start_timestamp; // timestamp of writing decrementer value
|
||||
u32 ch_dec_value; // written decrementer value
|
||||
u64 ch_dec_start_timestamp = 0; // timestamp of writing decrementer value
|
||||
u32 ch_dec_value = 0; // written decrementer value
|
||||
bool is_dec_frozen = false;
|
||||
std::pair<u32, u32> read_dec() const; // Read decrementer
|
||||
|
||||
atomic_t<u32> run_ctrl; // SPU Run Control register (only provided to get latest data written)
|
||||
atomic_t<u32> run_ctrl = 0; // SPU Run Control register (only provided to get latest data written)
|
||||
shared_mutex run_ctrl_mtx;
|
||||
|
||||
struct alignas(8) status_npc_sync_var
|
||||
|
@ -752,10 +752,10 @@ public:
|
|||
u32 npc; // SPU Next Program Counter register
|
||||
};
|
||||
|
||||
atomic_t<status_npc_sync_var> status_npc;
|
||||
std::array<spu_int_ctrl_t, 3> int_ctrl; // SPU Class 0, 1, 2 Interrupt Management
|
||||
atomic_t<status_npc_sync_var> status_npc{};
|
||||
std::array<spu_int_ctrl_t, 3> int_ctrl{}; // SPU Class 0, 1, 2 Interrupt Management
|
||||
|
||||
std::array<std::pair<u32, std::shared_ptr<lv2_event_queue>>, 32> spuq; // Event Queue Keys for SPU Thread
|
||||
std::array<std::pair<u32, std::shared_ptr<lv2_event_queue>>, 32> spuq{}; // Event Queue Keys for SPU Thread
|
||||
std::shared_ptr<lv2_event_queue> spup[64]; // SPU Ports
|
||||
spu_channel exit_status{}; // Threaded SPU exit status (not a channel, but the interface fits)
|
||||
atomic_t<u32> last_exit_status; // Value to be written in exit_status after checking group termination
|
||||
|
@ -768,6 +768,11 @@ public:
|
|||
const u32 lv2_id; // The actual id that is used by syscalls
|
||||
u32 spurs_addr = 0;
|
||||
bool spurs_waited = false;
|
||||
bool spurs_entered_wait = false;
|
||||
u64 spurs_wait_duration_last = 0;
|
||||
u64 spurs_average_task_duration = 0;
|
||||
u64 spurs_last_task_timestamp = 0;
|
||||
static constexpr u64 spurs_task_count_to_calculate = 10;
|
||||
|
||||
spu_thread* next_cpu{}; // LV2 thread queues' node link
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ std::shared_ptr<vm::block_t> reserve_map(u32 alloc_size, u32 align)
|
|||
|
||||
// Todo: fix order of error checks
|
||||
|
||||
error_code sys_memory_allocate(cpu_thread& cpu, u32 size, u64 flags, vm::ptr<u32> alloc_addr)
|
||||
error_code sys_memory_allocate(cpu_thread& cpu, u64 size, u64 flags, vm::ptr<u32> alloc_addr)
|
||||
{
|
||||
cpu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -129,9 +129,9 @@ error_code sys_memory_allocate(cpu_thread& cpu, u32 size, u64 flags, vm::ptr<u32
|
|||
return {CELL_ENOMEM, dct.size - dct.used};
|
||||
}
|
||||
|
||||
if (const auto area = reserve_map(size, align))
|
||||
if (const auto area = reserve_map(static_cast<u32>(size), align))
|
||||
{
|
||||
if (const u32 addr = area->alloc(size, nullptr, align))
|
||||
if (const u32 addr = area->alloc(static_cast<u32>(size), nullptr, align))
|
||||
{
|
||||
ensure(!g_fxo->get<sys_memory_address_table>().addrs[addr >> 16].exchange(&dct));
|
||||
|
||||
|
@ -139,7 +139,7 @@ error_code sys_memory_allocate(cpu_thread& cpu, u32 size, u64 flags, vm::ptr<u32
|
|||
{
|
||||
sys_memory.notice("sys_memory_allocate(): Allocated 0x%x address (size=0x%x)", addr, size);
|
||||
|
||||
vm::lock_sudo(addr, size);
|
||||
vm::lock_sudo(addr, static_cast<u32>(size));
|
||||
cpu.check_state();
|
||||
*alloc_addr = addr;
|
||||
return CELL_OK;
|
||||
|
@ -155,7 +155,7 @@ error_code sys_memory_allocate(cpu_thread& cpu, u32 size, u64 flags, vm::ptr<u32
|
|||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
error_code sys_memory_allocate_from_container(cpu_thread& cpu, u32 size, u32 cid, u64 flags, vm::ptr<u32> alloc_addr)
|
||||
error_code sys_memory_allocate_from_container(cpu_thread& cpu, u64 size, u32 cid, u64 flags, vm::ptr<u32> alloc_addr)
|
||||
{
|
||||
cpu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -203,15 +203,15 @@ error_code sys_memory_allocate_from_container(cpu_thread& cpu, u32 size, u32 cid
|
|||
return {ct.ret, ct->size - ct->used};
|
||||
}
|
||||
|
||||
if (const auto area = reserve_map(size, align))
|
||||
if (const auto area = reserve_map(static_cast<u32>(size), align))
|
||||
{
|
||||
if (const u32 addr = area->alloc(size))
|
||||
if (const u32 addr = area->alloc(static_cast<u32>(size)))
|
||||
{
|
||||
ensure(!g_fxo->get<sys_memory_address_table>().addrs[addr >> 16].exchange(ct.ptr.get()));
|
||||
|
||||
if (alloc_addr)
|
||||
{
|
||||
vm::lock_sudo(addr, size);
|
||||
vm::lock_sudo(addr, static_cast<u32>(size));
|
||||
cpu.check_state();
|
||||
*alloc_addr = addr;
|
||||
return CELL_OK;
|
||||
|
@ -320,7 +320,7 @@ error_code sys_memory_get_user_memory_stat(cpu_thread& cpu, vm::ptr<sys_memory_u
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_memory_container_create(cpu_thread& cpu, vm::ptr<u32> cid, u32 size)
|
||||
error_code sys_memory_container_create(cpu_thread& cpu, vm::ptr<u32> cid, u64 size)
|
||||
{
|
||||
cpu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -345,7 +345,7 @@ error_code sys_memory_container_create(cpu_thread& cpu, vm::ptr<u32> cid, u32 si
|
|||
}
|
||||
|
||||
// Create the memory container
|
||||
if (const u32 id = idm::make<lv2_memory_container>(size, true))
|
||||
if (const u32 id = idm::make<lv2_memory_container>(static_cast<u32>(size), true))
|
||||
{
|
||||
cpu.check_state();
|
||||
*cid = id;
|
||||
|
|
|
@ -128,13 +128,13 @@ struct sys_memory_user_memory_stat_t
|
|||
};
|
||||
|
||||
// SysCalls
|
||||
error_code sys_memory_allocate(cpu_thread& cpu, u32 size, u64 flags, vm::ptr<u32> alloc_addr);
|
||||
error_code sys_memory_allocate_from_container(cpu_thread& cpu, u32 size, u32 cid, u64 flags, vm::ptr<u32> alloc_addr);
|
||||
error_code sys_memory_allocate(cpu_thread& cpu, u64 size, u64 flags, vm::ptr<u32> alloc_addr);
|
||||
error_code sys_memory_allocate_from_container(cpu_thread& cpu, u64 size, u32 cid, u64 flags, vm::ptr<u32> alloc_addr);
|
||||
error_code sys_memory_free(cpu_thread& cpu, u32 start_addr);
|
||||
error_code sys_memory_get_page_attribute(cpu_thread& cpu, u32 addr, vm::ptr<sys_page_attr_t> attr);
|
||||
error_code sys_memory_get_user_memory_size(cpu_thread& cpu, vm::ptr<sys_memory_info_t> mem_info);
|
||||
error_code sys_memory_get_user_memory_stat(cpu_thread& cpu, vm::ptr<sys_memory_user_memory_stat_t> mem_stat);
|
||||
error_code sys_memory_container_create(cpu_thread& cpu, vm::ptr<u32> cid, u32 size);
|
||||
error_code sys_memory_container_create(cpu_thread& cpu, vm::ptr<u32> cid, u64 size);
|
||||
error_code sys_memory_container_destroy(cpu_thread& cpu, u32 cid);
|
||||
error_code sys_memory_container_get_size(cpu_thread& cpu, vm::ptr<sys_memory_info_t> mem_info, u32 cid);
|
||||
error_code sys_memory_container_destroy_parent_with_childs(cpu_thread& cpu, u32 cid, u32 must_0, vm::ptr<u32> mc_child);
|
||||
|
|
|
@ -562,16 +562,39 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
|||
|
||||
sys_spu.warning("sys_spu_thread_initialize(thread=*0x%x, group=0x%x, spu_num=%d, img=*0x%x, attr=*0x%x, arg=*0x%x)", thread, group_id, spu_num, img, attr, arg);
|
||||
|
||||
const u32 option = attr->option;
|
||||
if (!attr)
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
if (attr->name_len > 0x80 || option & ~(SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE | SYS_SPU_THREAD_OPTION_ASYNC_INTR_ENABLE))
|
||||
const sys_spu_thread_attribute attr_data = *attr;
|
||||
|
||||
if (attr_data.name_len > 0x80)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
sys_spu_image image;
|
||||
if (!arg)
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
switch (img->type)
|
||||
const sys_spu_thread_argument args = *arg;
|
||||
const u32 option = attr_data.option;
|
||||
|
||||
if (option & ~(SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE | SYS_SPU_THREAD_OPTION_ASYNC_INTR_ENABLE))
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (!img)
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
sys_spu_image image = *img;
|
||||
|
||||
switch (image.type)
|
||||
{
|
||||
case SYS_SPU_IMAGE_TYPE_KERNEL:
|
||||
{
|
||||
|
@ -591,12 +614,11 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
|||
}
|
||||
case SYS_SPU_IMAGE_TYPE_USER:
|
||||
{
|
||||
if (img->entry_point > 0x3fffc || img->nsegs <= 0 || img->nsegs > 0x20)
|
||||
if (image.entry_point > 0x3fffc || image.nsegs <= 0 || image.nsegs > 0x20)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
image = *img;
|
||||
break;
|
||||
}
|
||||
default: return CELL_EINVAL;
|
||||
|
@ -672,7 +694,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
|||
}
|
||||
|
||||
// Read thread name
|
||||
const std::string thread_name(attr->name.get_ptr(), std::max<u32>(attr->name_len, 1) - 1);
|
||||
const std::string thread_name(attr_data.name.get_ptr(), std::max<u32>(attr_data.name_len, 1) - 1);
|
||||
|
||||
const auto group = idm::get<lv2_spu_group>(group_id);
|
||||
|
||||
|
@ -725,7 +747,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
|||
ensure(vm::get(vm::spu)->falloc(spu->vm_offset(), SPU_LS_SIZE, &spu->shm, static_cast<u64>(vm::page_size_64k) | static_cast<u64>(vm::alloc_hidden)));
|
||||
spu->map_ls(*spu->shm, spu->ls);
|
||||
|
||||
group->args[inited] = {arg->arg1, arg->arg2, arg->arg3, arg->arg4};
|
||||
group->args[inited] = {args.arg1, args.arg2, args.arg3, args.arg4};
|
||||
group->imgs[inited].first = image.entry_point;
|
||||
group->imgs[inited].second = std::move(spu_segs);
|
||||
|
||||
|
@ -800,12 +822,14 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr<u32> id, u32 num
|
|||
|
||||
const s32 min_prio = g_ps3_process_info.has_root_perm() ? 0 : 16;
|
||||
|
||||
if (attr->nsize > 0x80 || !num)
|
||||
const sys_spu_thread_group_attribute attr_data = *attr;
|
||||
|
||||
if (attr_data.nsize > 0x80 || !num)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const s32 type = attr->type;
|
||||
const s32 type = attr_data.type;
|
||||
|
||||
bool use_scheduler = true;
|
||||
bool use_memct = !!(type & SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER);
|
||||
|
@ -902,7 +926,7 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr<u32> id, u32 num
|
|||
|
||||
if (use_memct && mem_size)
|
||||
{
|
||||
const auto sct = idm::get<lv2_memory_container>(attr->ct);
|
||||
const auto sct = idm::get<lv2_memory_container>(attr_data.ct);
|
||||
|
||||
if (!sct)
|
||||
{
|
||||
|
@ -936,7 +960,7 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr<u32> id, u32 num
|
|||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
const auto group = idm::make_ptr<lv2_spu_group>(std::string(attr->name.get_ptr(), std::max<u32>(attr->nsize, 1) - 1), num, prio, type, ct, use_scheduler, mem_size);
|
||||
const auto group = idm::make_ptr<lv2_spu_group>(std::string(attr_data.name.get_ptr(), std::max<u32>(attr_data.nsize, 1) - 1), num, prio, type, ct, use_scheduler, mem_size);
|
||||
|
||||
if (!group)
|
||||
{
|
||||
|
@ -1909,7 +1933,7 @@ error_code sys_spu_thread_group_disconnect_event(ppu_thread& ppu, u32 id, u32 et
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_spu_thread_connect_event(ppu_thread& ppu, u32 id, u32 eq, u32 et, u8 spup)
|
||||
error_code sys_spu_thread_connect_event(ppu_thread& ppu, u32 id, u32 eq, u32 et, u32 spup)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -1943,7 +1967,7 @@ error_code sys_spu_thread_connect_event(ppu_thread& ppu, u32 id, u32 eq, u32 et,
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_spu_thread_disconnect_event(ppu_thread& ppu, u32 id, u32 et, u8 spup)
|
||||
error_code sys_spu_thread_disconnect_event(ppu_thread& ppu, u32 id, u32 et, u32 spup)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -2144,7 +2168,7 @@ error_code sys_spu_thread_group_connect_event_all_threads(ppu_thread& ppu, u32 i
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_spu_thread_group_disconnect_event_all_threads(ppu_thread& ppu, u32 id, u8 spup)
|
||||
error_code sys_spu_thread_group_disconnect_event_all_threads(ppu_thread& ppu, u32 id, u32 spup)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ error_code sys_spu_thread_group_get_priority(ppu_thread&, u32 id, vm::ptr<s32> p
|
|||
error_code sys_spu_thread_group_connect_event(ppu_thread&, u32 id, u32 eq, u32 et);
|
||||
error_code sys_spu_thread_group_disconnect_event(ppu_thread&, u32 id, u32 et);
|
||||
error_code sys_spu_thread_group_connect_event_all_threads(ppu_thread&, u32 id, u32 eq_id, u64 req, vm::ptr<u8> spup);
|
||||
error_code sys_spu_thread_group_disconnect_event_all_threads(ppu_thread&, u32 id, u8 spup);
|
||||
error_code sys_spu_thread_group_disconnect_event_all_threads(ppu_thread&, u32 id, u32 spup);
|
||||
error_code sys_spu_thread_group_set_cooperative_victims(ppu_thread&, u32 id, u32 threads_mask);
|
||||
error_code sys_spu_thread_group_syscall_253(ppu_thread& ppu, u32 id, vm::ptr<sys_spu_thread_group_syscall_253_info> info);
|
||||
error_code sys_spu_thread_group_log(ppu_thread&, s32 command, vm::ptr<s32> stat);
|
||||
|
@ -382,8 +382,8 @@ error_code sys_spu_thread_write_spu_mb(ppu_thread&, u32 id, u32 value);
|
|||
error_code sys_spu_thread_set_spu_cfg(ppu_thread&, u32 id, u64 value);
|
||||
error_code sys_spu_thread_get_spu_cfg(ppu_thread&, u32 id, vm::ptr<u64> value);
|
||||
error_code sys_spu_thread_write_snr(ppu_thread&, u32 id, u32 number, u32 value);
|
||||
error_code sys_spu_thread_connect_event(ppu_thread&, u32 id, u32 eq, u32 et, u8 spup);
|
||||
error_code sys_spu_thread_disconnect_event(ppu_thread&, u32 id, u32 et, u8 spup);
|
||||
error_code sys_spu_thread_connect_event(ppu_thread&, u32 id, u32 eq, u32 et, u32 spup);
|
||||
error_code sys_spu_thread_disconnect_event(ppu_thread&, u32 id, u32 et, u32 spup);
|
||||
error_code sys_spu_thread_bind_queue(ppu_thread&, u32 id, u32 spuq, u32 spuq_num);
|
||||
error_code sys_spu_thread_unbind_queue(ppu_thread&, u32 id, u32 spuq_num);
|
||||
error_code sys_spu_thread_get_exit_status(ppu_thread&, u32 id, vm::ptr<s32> status);
|
||||
|
|
|
@ -48,13 +48,18 @@ sys_vm_t::sys_vm_t(utils::serial& ar)
|
|||
g_fxo->get<sys_vm_global_t>().total_vsize += size;
|
||||
}
|
||||
|
||||
error_code sys_vm_memory_map(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr)
|
||||
error_code sys_vm_memory_map(ppu_thread& ppu, u64 vsize, u64 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
sys_vm.warning("sys_vm_memory_map(vsize=0x%x, psize=0x%x, cid=0x%x, flags=0x%x, policy=0x%x, addr=*0x%x)", vsize, psize, cid, flag, policy, addr);
|
||||
|
||||
if (!vsize || !psize || vsize % 0x2000000 || vsize > 0x10000000 || psize > 0x10000000 || policy != SYS_VM_POLICY_AUTO_RECOMMENDED)
|
||||
if (!vsize || !psize || vsize % 0x200'0000 || vsize > 0x1000'0000 || psize > 0x1000'0000 || psize % 0x1'0000 || psize % policy != SYS_VM_POLICY_AUTO_RECOMMENDED)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (ppu.gpr[11] == 300 && psize < 0x10'0000)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
@ -68,16 +73,16 @@ error_code sys_vm_memory_map(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64
|
|||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (!g_fxo->get<sys_vm_global_t>().total_vsize.fetch_op([vsize](u32& size)
|
||||
if (!g_fxo->get<sys_vm_global_t>().total_vsize.fetch_op([vsize, has_root = g_ps3_process_info.has_root_perm()](u32& size)
|
||||
{
|
||||
// A single process can hold up to 256MB of virtual memory, even on DECR
|
||||
// VSH can hold more
|
||||
if ((g_ps3_process_info.has_root_perm() ? 0x1E000000 : 0x10000000) - size < vsize)
|
||||
if ((has_root ? 0x1E000000 : 0x10000000) - size < vsize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size += vsize;
|
||||
size += static_cast<u32>(vsize);
|
||||
return true;
|
||||
}).second)
|
||||
{
|
||||
|
@ -86,7 +91,7 @@ error_code sys_vm_memory_map(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64
|
|||
|
||||
if (!ct->take(psize))
|
||||
{
|
||||
g_fxo->get<sys_vm_global_t>().total_vsize -= vsize;
|
||||
g_fxo->get<sys_vm_global_t>().total_vsize -= static_cast<u32>(vsize);
|
||||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -96,10 +101,10 @@ error_code sys_vm_memory_map(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64
|
|||
sys_vm.warning("sys_vm_memory_map(): Found VM 0x%x area (vsize=0x%x)", addr, vsize);
|
||||
|
||||
// Alloc all memory (shall not fail)
|
||||
ensure(area->alloc(vsize));
|
||||
vm::lock_sudo(area->addr, vsize);
|
||||
ensure(area->alloc(static_cast<u32>(vsize)));
|
||||
vm::lock_sudo(area->addr, static_cast<u32>(vsize));
|
||||
|
||||
idm::make<sys_vm_t>(area->addr, vsize, ct, psize);
|
||||
idm::make<sys_vm_t>(area->addr, static_cast<u32>(vsize), ct, static_cast<u32>(psize));
|
||||
|
||||
// Write a pointer for the allocated memory
|
||||
ppu.check_state();
|
||||
|
@ -108,11 +113,11 @@ error_code sys_vm_memory_map(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64
|
|||
}
|
||||
|
||||
ct->free(psize);
|
||||
g_fxo->get<sys_vm_global_t>().total_vsize -= vsize;
|
||||
g_fxo->get<sys_vm_global_t>().total_vsize -= static_cast<u32>(vsize);
|
||||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
error_code sys_vm_memory_map_different(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr)
|
||||
error_code sys_vm_memory_map_different(ppu_thread& ppu, u64 vsize, u64 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -153,7 +158,7 @@ error_code sys_vm_unmap(ppu_thread& ppu, u32 addr)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u32 size)
|
||||
error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u64 size)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -176,7 +181,7 @@ error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u32 size)
|
|||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
vmo.psize += size;
|
||||
vmo.psize += static_cast<u32>(size);
|
||||
return {};
|
||||
});
|
||||
|
||||
|
@ -193,7 +198,7 @@ error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u32 size)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_vm_return_memory(ppu_thread& ppu, u32 addr, u32 size)
|
||||
error_code sys_vm_return_memory(ppu_thread& ppu, u32 addr, u64 size)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
|
@ -213,12 +218,12 @@ error_code sys_vm_return_memory(ppu_thread& ppu, u32 addr, u32 size)
|
|||
|
||||
auto [_, ok] = vmo.psize.fetch_op([&](u32& value)
|
||||
{
|
||||
if (value < 0x100000ull + size)
|
||||
if (value <= size || value - size < 0x100000ull)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value -= size;
|
||||
value -= static_cast<u32>(size);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
|
|
@ -58,11 +58,11 @@ struct sys_vm_t
|
|||
class ppu_thread;
|
||||
|
||||
// SysCalls
|
||||
error_code sys_vm_memory_map(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr);
|
||||
error_code sys_vm_memory_map_different(ppu_thread& ppu, u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr);
|
||||
error_code sys_vm_memory_map(ppu_thread& ppu, u64 vsize, u64 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr);
|
||||
error_code sys_vm_memory_map_different(ppu_thread& ppu, u64 vsize, u64 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr);
|
||||
error_code sys_vm_unmap(ppu_thread& ppu, u32 addr);
|
||||
error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u32 size);
|
||||
error_code sys_vm_return_memory(ppu_thread& ppu, u32 addr, u32 size);
|
||||
error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u64 size);
|
||||
error_code sys_vm_return_memory(ppu_thread& ppu, u32 addr, u64 size);
|
||||
error_code sys_vm_lock(ppu_thread& ppu, u32 addr, u32 size);
|
||||
error_code sys_vm_unlock(ppu_thread& ppu, u32 addr, u32 size);
|
||||
error_code sys_vm_touch(ppu_thread& ppu, u32 addr, u32 size);
|
||||
|
|
|
@ -39,7 +39,7 @@ struct cfg_root : cfg::node
|
|||
cfg::_int<0, 6> preferred_spu_threads{ this, "Preferred SPU Threads", 0, true }; // Number of hardware threads dedicated to heavy simultaneous spu tasks
|
||||
cfg::_int<0, 16> spu_delay_penalty{ this, "SPU delay penalty", 3 }; // Number of milliseconds to block a thread if a virtual 'core' isn't free
|
||||
cfg::_bool spu_loop_detection{ this, "SPU loop detection", false }; // Try to detect wait loops and trigger thread yield
|
||||
cfg::_int<0, 6> max_spurs_threads{ this, "Max SPURS Threads", 6, true }; // HACK. If less then 6, max number of running SPURS threads in each thread group.
|
||||
cfg::_int<1, 6> max_spurs_threads{ this, "Max SPURS Threads", 6, true }; // HACK. If less then 6, max number of running SPURS threads in each thread group.
|
||||
cfg::_enum<spu_block_size_type> spu_block_size{ this, "SPU Block Size", spu_block_size_type::safe };
|
||||
cfg::_bool spu_accurate_dma{ this, "Accurate SPU DMA", false };
|
||||
cfg::_bool spu_accurate_reservations{ this, "Accurate SPU Reservations", true };
|
||||
|
|
|
@ -494,6 +494,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
const std::string lock_name = fs::get_cache_dir() + "RPCS3.buf";
|
||||
const std::string log_name = fs::get_cache_dir() + "RPCS3.log";
|
||||
|
||||
static fs::file instance_lock;
|
||||
|
||||
|
@ -512,19 +513,19 @@ int main(int argc, char** argv)
|
|||
{
|
||||
if (fs::exists(lock_name))
|
||||
{
|
||||
report_fatal_error("Another instance of RPCS3 is running.\nClose it or kill its process, if necessary.");
|
||||
report_fatal_error(fmt::format("Another instance of RPCS3 is running.\nClose it or kill its process, if necessary.\n'%s' still exists.", lock_name));
|
||||
}
|
||||
|
||||
report_fatal_error("Cannot create RPCS3.log (access denied)."
|
||||
report_fatal_error(fmt::format("Cannot create '%s' or '%s' (access denied).\n"
|
||||
#ifdef _WIN32
|
||||
"\nNote that RPCS3 cannot be installed in Program Files or similar directories with limited permissions."
|
||||
"Note that RPCS3 cannot be installed in Program Files or similar directories with limited permissions."
|
||||
#else
|
||||
"\nPlease, check RPCS3 permissions in '~/.config/rpcs3'."
|
||||
"Please, check RPCS3 permissions."
|
||||
#endif
|
||||
);
|
||||
, log_name, lock_name));
|
||||
}
|
||||
|
||||
report_fatal_error(fmt::format("Cannot create RPCS3.log (error %s)", fs::g_tls_error));
|
||||
report_fatal_error(fmt::format("Cannot create'%s' or '%s' (error=%s)", log_name, lock_name, fs::g_tls_error));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -568,7 +569,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
// Limit log size to ~25% of free space
|
||||
log_file = logs::make_file_listener(fs::get_cache_dir() + "RPCS3.log", stats.avail_free / 4);
|
||||
log_file = logs::make_file_listener(log_name, stats.avail_free / 4);
|
||||
}
|
||||
|
||||
static std::unique_ptr<logs::listener> fatal_listener = std::make_unique<fatal_error_listener>();
|
||||
|
|
|
@ -451,47 +451,47 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) co
|
|||
logs::file_writer::file_writer(const std::string& name, u64 max_size)
|
||||
: m_max_size(max_size)
|
||||
{
|
||||
if (!name.empty() && max_size)
|
||||
if (name.empty() || !max_size)
|
||||
{
|
||||
// Initialize ringbuffer
|
||||
m_fptr = std::make_unique<uchar[]>(s_log_size);
|
||||
return;
|
||||
}
|
||||
|
||||
// Actual log file (allowed to fail)
|
||||
if (!m_fout.open(name, fs::rewrite))
|
||||
{
|
||||
fprintf(stderr, "Log file open failed: %s (error %d)\n", name.c_str(), errno);
|
||||
}
|
||||
// Initialize ringbuffer
|
||||
m_fptr = std::make_unique<uchar[]>(s_log_size);
|
||||
|
||||
// Compressed log, make it inaccessible (foolproof)
|
||||
if (m_fout2.open(name + ".gz", fs::rewrite + fs::unread))
|
||||
{
|
||||
// Actual log file (allowed to fail)
|
||||
if (!m_fout.open(name, fs::rewrite))
|
||||
{
|
||||
fprintf(stderr, "Log file open failed: %s (error %d)\n", name.c_str(), errno);
|
||||
}
|
||||
|
||||
// Compressed log, make it inaccessible (foolproof)
|
||||
if (m_fout2.open(name + ".gz", fs::rewrite + fs::unread))
|
||||
{
|
||||
#ifndef _MSC_VER
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
if (deflateInit2(&m_zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
if (deflateInit2(&m_zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
#ifndef _MSC_VER
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
m_fout2.close();
|
||||
}
|
||||
|
||||
if (!m_fout2)
|
||||
{
|
||||
fprintf(stderr, "Log file open failed: %s.gz (error %d)\n", name.c_str(), errno);
|
||||
m_fout2.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_fout2)
|
||||
{
|
||||
fprintf(stderr, "Log file open failed: %s.gz (error %d)\n", name.c_str(), errno);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Autodelete compressed log file
|
||||
FILE_DISPOSITION_INFO disp;
|
||||
disp.DeleteFileW = true;
|
||||
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||
// Autodelete compressed log file
|
||||
FILE_DISPOSITION_INFO disp{};
|
||||
disp.DeleteFileW = true;
|
||||
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_writer = std::thread([this]()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue