Final sys_ fixes

This commit is contained in:
RipleyTom
2026-02-27 08:02:46 +01:00
committed by Elad
parent b30a20c2dc
commit 3b6afc1d9a
23 changed files with 110 additions and 114 deletions
+17 -9
View File
@@ -174,20 +174,28 @@ bool lv2_config_service_listener::check_service(const lv2_config_service& servic
return true; return true;
} }
bool lv2_config_service_listener::notify(const shared_ptr<lv2_config_service_event>& event)
{
service_events.emplace_back(event);
return event->notify();
}
bool lv2_config_service_listener::notify(const shared_ptr<lv2_config_service>& service) bool lv2_config_service_listener::notify(const shared_ptr<lv2_config_service>& service)
{ {
{
std::lock_guard lock(mutex_service_events);
if (!check_service(*service)) if (!check_service(*service))
return false; return false;
// Create service event and notify queue! // Create service event and notify queue!
const auto event = lv2_config_service_event::create(handle, service, *this); const auto event = lv2_config_service_event::create(handle, service, *this);
return notify(event); service_events.emplace_back(event);
if (!event->notify())
{
// If we fail to deliver the event to the queue just clean the event up or it'll hold the listener alive forever
g_fxo->get<lv2_config>().remove_service_event(event->id);
service_events.pop_back();
return false;
}
}
return true;
} }
void lv2_config_service_listener::notify_all() void lv2_config_service_listener::notify_all()
@@ -267,7 +275,7 @@ void lv2_config_service_event::write(sys_config_service_event_t *dst) const
{ {
const auto registered = service->is_registered(); const auto registered = service->is_registered();
dst->service_listener_handle = listener.get_id(); dst->service_listener_handle = listener_id;
dst->registered = registered; dst->registered = registered;
dst->service_id = service->id; dst->service_id = service->id;
dst->user_id = service->user_id; dst->user_id = service->user_id;
@@ -346,7 +354,7 @@ error_code sys_config_get_service_event(u32 config_hdl, u32 event_id, vm::ptr<sy
// Find service_event object // Find service_event object
const auto event = g_fxo->get<lv2_config>().find_event(event_id); const auto event = g_fxo->get<lv2_config>().find_event(event_id);
if (!event) if (!event || event->handle != cfg)
{ {
return CELL_ESRCH; return CELL_ESRCH;
} }
+3 -4
View File
@@ -296,11 +296,10 @@ private:
// The service listener owns the service events - service events will not be freed as long as their corresponding listener exists // The service listener owns the service events - service events will not be freed as long as their corresponding listener exists
// This has been confirmed to be the case in realhw // This has been confirmed to be the case in realhw
shared_mutex mutex_service_events;
std::vector<shared_ptr<lv2_config_service_event>> service_events; std::vector<shared_ptr<lv2_config_service_event>> service_events;
shared_ptr<lv2_config_handle> handle; shared_ptr<lv2_config_handle> handle;
bool notify(const shared_ptr<lv2_config_service_event>& event);
public: public:
const sys_config_service_id service_id; const sys_config_service_id service_id;
const u64 min_verbosity; const u64 min_verbosity;
@@ -370,14 +369,14 @@ public:
// This has been confirmed to be the case in realhw // This has been confirmed to be the case in realhw
const shared_ptr<lv2_config_handle> handle; const shared_ptr<lv2_config_handle> handle;
const shared_ptr<lv2_config_service> service; const shared_ptr<lv2_config_service> service;
const lv2_config_service_listener& listener; const u32 listener_id;
// Constructors (should not be used directly) // Constructors (should not be used directly)
lv2_config_service_event(shared_ptr<lv2_config_handle> _handle, shared_ptr<lv2_config_service> _service, const lv2_config_service_listener& _listener) noexcept lv2_config_service_event(shared_ptr<lv2_config_handle> _handle, shared_ptr<lv2_config_service> _service, const lv2_config_service_listener& _listener) noexcept
: id(get_next_id()) : id(get_next_id())
, handle(std::move(_handle)) , handle(std::move(_handle))
, service(std::move(_service)) , service(std::move(_service))
, listener(_listener) , listener_id(_listener.get_id())
{ {
} }
+1 -1
View File
@@ -105,7 +105,7 @@ error_code sys_dbg_write_process_memory(s32 pid, u32 address, u32 size, vm::cptr
i += op_size; i += op_size;
} }
if (!is_exec || i >= end) if ((!is_exec || i >= end) && exec_update_size > 0)
{ {
// Commit executable data update // Commit executable data update
// The read memory is also super ptr so memmove can work correctly on all implementations // The read memory is also super ptr so memmove can work correctly on all implementations
+9 -11
View File
@@ -308,6 +308,15 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
return CELL_EBUSY; return CELL_EBUSY;
} }
for (auto cpu = head; cpu; cpu = cpu->get_next_cpu())
{
if (cpu->state & cpu_flag::again)
{
ppu.state += cpu_flag::again;
return CELL_EAGAIN;
}
}
if (!queue.events.empty()) if (!queue.events.empty())
{ {
// Copy events for logging, does not empty // Copy events for logging, does not empty
@@ -320,17 +329,6 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
{ {
qlock.unlock(); qlock.unlock();
} }
else
{
for (auto cpu = head; cpu; cpu = cpu->get_next_cpu())
{
if (cpu->state & cpu_flag::again)
{
ppu.state += cpu_flag::again;
return CELL_EAGAIN;
}
}
}
return {}; return {};
}); });
+4 -14
View File
@@ -382,7 +382,7 @@ lv2_fs_object::lv2_fs_object(utils::serial& ar, bool)
u64 lv2_file::op_read(const fs::file& file, vm::ptr<void> buf, u64 size, u64 opt_pos) u64 lv2_file::op_read(const fs::file& file, vm::ptr<void> buf, u64 size, u64 opt_pos)
{ {
if (u64 region = buf.addr() >> 28, region_end = (buf.addr() & 0xfff'ffff) + (size & 0xfff'ffff); region == region_end && ((region >> 28) == 0 || region >= 0xC)) if (u64 region = buf.addr() >> 28, region_end = (buf.addr() + size) >> 28; region == region_end && region == 0)
{ {
// Optimize reads from safe memory // Optimize reads from safe memory
return (opt_pos == umax ? file.read(buf.get_ptr(), size) : file.read_at(opt_pos, buf.get_ptr(), size)); return (opt_pos == umax ? file.read(buf.get_ptr(), size) : file.read_at(opt_pos, buf.get_ptr(), size));
@@ -1391,7 +1391,8 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
// Add additional entries for split file candidates (while ends with .66600) // Add additional entries for split file candidates (while ends with .66600)
while (mp.mp != &g_mp_sys_dev_hdd1 && data.back().name.ends_with(".66600")) while (mp.mp != &g_mp_sys_dev_hdd1 && data.back().name.ends_with(".66600"))
{ {
data.emplace_back(data.back()).name.resize(data.back().name.size() - 6); fs::dir_entry copy = data.back();
data.emplace_back(copy).name.resize(copy.name.size() - 6);
} }
} }
@@ -2147,6 +2148,7 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
sys_fs.notice("sys_fs_fcntl(0xc0000006): %s", vpath); sys_fs.notice("sys_fs_fcntl(0xc0000006): %s", vpath);
// Check only mountpoint // Check only mountpoint
vpath = vpath.substr(0, vpath.find_first_of('\0'));
vpath = vpath.substr(0, vpath.find_first_of("/", 1)); vpath = vpath.substr(0, vpath.find_first_of("/", 1));
// Some mountpoints seem to be handled specially // Some mountpoints seem to be handled specially
@@ -2635,8 +2637,6 @@ error_code sys_fs_lseek(ppu_thread& ppu, u32 fd, s64 offset, s32 whence, vm::ptr
error_code sys_fs_fdatasync(ppu_thread& ppu, u32 fd) error_code sys_fs_fdatasync(ppu_thread& ppu, u32 fd)
{ {
lv2_obj::sleep(ppu);
sys_fs.trace("sys_fs_fdadasync(fd=%d)", fd); sys_fs.trace("sys_fs_fdadasync(fd=%d)", fd);
const auto file = idm::get_unlocked<lv2_fs_object, lv2_file>(fd); const auto file = idm::get_unlocked<lv2_fs_object, lv2_file>(fd);
@@ -2661,8 +2661,6 @@ error_code sys_fs_fdatasync(ppu_thread& ppu, u32 fd)
error_code sys_fs_fsync(ppu_thread& ppu, u32 fd) error_code sys_fs_fsync(ppu_thread& ppu, u32 fd)
{ {
lv2_obj::sleep(ppu);
sys_fs.trace("sys_fs_fsync(fd=%d)", fd); sys_fs.trace("sys_fs_fsync(fd=%d)", fd);
const auto file = idm::get_unlocked<lv2_fs_object, lv2_file>(fd); const auto file = idm::get_unlocked<lv2_fs_object, lv2_file>(fd);
@@ -2903,14 +2901,6 @@ error_code sys_fs_chmod(ppu_thread&, vm::cptr<char> path, s32 mode)
{ {
// Try to locate split files // Try to locate split files
for (u32 i = 66601; i <= 66699; i++)
{
if (mp != &g_mp_sys_dev_hdd1 && !fs::get_stat(fmt::format("%s.%u", local_path, i), info) && !info.is_directory)
{
break;
}
}
if (fs::get_stat(local_path + ".66600", info) && !info.is_directory) if (fs::get_stat(local_path + ".66600", info) && !info.is_directory)
{ {
break; break;
+13 -4
View File
@@ -333,7 +333,7 @@ error_code sys_mmapper_allocate_shared_memory_ext(ppu_thread& ppu, u64 ipc_key,
} }
} }
if (flags & ~SYS_MEMORY_PAGE_SIZE_MASK) if (flags & ~SYS_MEMORY_GRANULARITY_MASK)
{ {
return CELL_EINVAL; return CELL_EINVAL;
} }
@@ -401,6 +401,11 @@ error_code sys_mmapper_allocate_shared_memory_from_container_ext(ppu_thread& ppu
sys_mmapper.todo("sys_mmapper_allocate_shared_memory_from_container_ext(ipc_key=0x%x, size=0x%x, flags=0x%x, cid=0x%x, entries=*0x%x, entry_count=0x%x, mem_id=*0x%x)", ipc_key, size, flags, cid, entries, sys_mmapper.todo("sys_mmapper_allocate_shared_memory_from_container_ext(ipc_key=0x%x, size=0x%x, flags=0x%x, cid=0x%x, entries=*0x%x, entry_count=0x%x, mem_id=*0x%x)", ipc_key, size, flags, cid, entries,
entry_count, mem_id); entry_count, mem_id);
if (size == 0)
{
return CELL_EALIGN;
}
switch (flags & SYS_MEMORY_PAGE_SIZE_MASK) switch (flags & SYS_MEMORY_PAGE_SIZE_MASK)
{ {
case SYS_MEMORY_PAGE_SIZE_1M: case SYS_MEMORY_PAGE_SIZE_1M:
@@ -546,8 +551,7 @@ error_code sys_mmapper_free_address(ppu_thread& ppu, u32 addr)
// If a memory block is freed, remove it from page notification table. // If a memory block is freed, remove it from page notification table.
auto& pf_entries = g_fxo->get<page_fault_notification_entries>(); auto& pf_entries = g_fxo->get<page_fault_notification_entries>();
std::lock_guard lock(pf_entries.mutex); std::unique_lock lock(pf_entries.mutex);
auto ind_to_remove = pf_entries.entries.begin(); auto ind_to_remove = pf_entries.entries.begin();
for (; ind_to_remove != pf_entries.entries.end(); ++ind_to_remove) for (; ind_to_remove != pf_entries.entries.end(); ++ind_to_remove)
{ {
@@ -558,7 +562,11 @@ error_code sys_mmapper_free_address(ppu_thread& ppu, u32 addr)
} }
if (ind_to_remove != pf_entries.entries.end()) if (ind_to_remove != pf_entries.entries.end())
{ {
u32 port_id = ind_to_remove->port_id;
pf_entries.entries.erase(ind_to_remove); pf_entries.entries.erase(ind_to_remove);
lock.unlock();
sys_event_port_disconnect(ppu, port_id);
sys_event_port_destroy(ppu, port_id);
} }
return CELL_OK; return CELL_OK;
@@ -826,7 +834,6 @@ error_code sys_mmapper_enable_page_fault_notification(ppu_thread& ppu, u32 start
vm::var<u32> port_id(0); vm::var<u32> port_id(0);
error_code res = sys_event_port_create(ppu, port_id, SYS_EVENT_PORT_LOCAL, SYS_MEMORY_PAGE_FAULT_EVENT_KEY); error_code res = sys_event_port_create(ppu, port_id, SYS_EVENT_PORT_LOCAL, SYS_MEMORY_PAGE_FAULT_EVENT_KEY);
sys_event_port_connect_local(ppu, *port_id, event_queue_id);
if (res + 0u == CELL_EAGAIN) if (res + 0u == CELL_EAGAIN)
{ {
@@ -834,6 +841,8 @@ error_code sys_mmapper_enable_page_fault_notification(ppu_thread& ppu, u32 start
return CELL_EAGAIN; return CELL_EAGAIN;
} }
sys_event_port_connect_local(ppu, *port_id, event_queue_id);
auto& pf_entries = g_fxo->get<page_fault_notification_entries>(); auto& pf_entries = g_fxo->get<page_fault_notification_entries>();
std::unique_lock lock(pf_entries.mutex); std::unique_lock lock(pf_entries.mutex);
+3 -7
View File
@@ -563,8 +563,6 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr
return not_an_error(result); return not_an_error(result);
} }
if (!sock.ret)
{
while (auto state = ppu.state.fetch_sub(cpu_flag::signal)) while (auto state = ppu.state.fetch_sub(cpu_flag::signal))
{ {
if (is_stopped(state)) if (is_stopped(state))
@@ -594,7 +592,6 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr
return not_an_error(result); return not_an_error(result);
} }
}
return CELL_OK; return CELL_OK;
} }
@@ -1295,7 +1292,7 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
if (auto sock = idm::check_unlocked<lv2_socket>(fds_buf[i].fd)) if (auto sock = idm::check_unlocked<lv2_socket>(fds_buf[i].fd))
{ {
signaled += sock->poll(fds_buf[i], _fds[i]); sock->poll(fds_buf[i], _fds[i]);
#ifdef _WIN32 #ifdef _WIN32
connecting[i] = sock->is_connecting(); connecting[i] = sock->is_connecting();
#endif #endif
@@ -1303,7 +1300,6 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
else else
{ {
fds_buf[i].revents |= SYS_NET_POLLNVAL; fds_buf[i].revents |= SYS_NET_POLLNVAL;
signaled++;
} }
} }
@@ -1536,9 +1532,9 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
for (s32 i = 0; i < nfds; i++) for (s32 i = 0; i < nfds; i++)
{ {
bool sig = false; bool sig = false;
if (_fds[i].revents & (POLLIN | POLLHUP | POLLERR)) if ((_fds[i].revents & (POLLIN | POLLHUP | POLLERR)) && _readfds.bit(i))
sig = true, rread.set(i); sig = true, rread.set(i);
if (_fds[i].revents & (POLLOUT | POLLERR)) if ((_fds[i].revents & (POLLOUT | POLLERR)) && _writefds.bit(i))
sig = true, rwrite.set(i); sig = true, rwrite.set(i);
if (sig) if (sig)
+1 -1
View File
@@ -104,7 +104,7 @@ public:
virtual void close() = 0; virtual void close() = 0;
virtual s32 shutdown(s32 how) = 0; virtual s32 shutdown(s32 how) = 0;
virtual s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) = 0; virtual void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) = 0;
virtual std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) = 0; virtual std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) = 0;
error_code abort_socket(s32 flags); error_code abort_socket(s32 flags);
@@ -1147,14 +1147,14 @@ s32 lv2_socket_native::shutdown(s32 how)
return -get_last_error(false); return -get_last_error(false);
} }
s32 lv2_socket_native::poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) void lv2_socket_native::poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd)
{ {
// Check for fake packet for dns interceptions // Check for fake packet for dns interceptions
auto& dnshook = g_fxo->get<np::dnshook>(); auto& dnshook = g_fxo->get<np::dnshook>();
if (sn_pfd.events & SYS_NET_POLLIN && dnshook.is_dns(sn_pfd.fd) && dnshook.is_dns_queue(sn_pfd.fd)) if (sn_pfd.events & SYS_NET_POLLIN && dnshook.is_dns(sn_pfd.fd) && dnshook.is_dns_queue(sn_pfd.fd))
{ {
sn_pfd.revents |= SYS_NET_POLLIN; sn_pfd.revents |= SYS_NET_POLLIN;
return 1; return;
} }
if (sn_pfd.events & ~(SYS_NET_POLLIN | SYS_NET_POLLOUT | SYS_NET_POLLERR)) if (sn_pfd.events & ~(SYS_NET_POLLIN | SYS_NET_POLLOUT | SYS_NET_POLLERR))
{ {
@@ -1171,8 +1171,6 @@ s32 lv2_socket_native::poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd)
{ {
native_pfd.events |= POLLOUT; native_pfd.events |= POLLOUT;
} }
return 0;
} }
std::tuple<bool, bool, bool> lv2_socket_native::select(bs_t<lv2_socket::poll_t> selected, pollfd& native_pfd) std::tuple<bool, bool, bool> lv2_socket_native::select(bs_t<lv2_socket::poll_t> selected, pollfd& native_pfd)
@@ -50,7 +50,7 @@ public:
std::optional<s32> sendto(s32 flags, const std::vector<u8>& buf, std::optional<sys_net_sockaddr> opt_sn_addr, bool is_lock = true) override; std::optional<s32> sendto(s32 flags, const std::vector<u8>& buf, std::optional<sys_net_sockaddr> opt_sn_addr, bool is_lock = true) override;
std::optional<s32> sendmsg(s32 flags, const sys_net_msghdr& msg, bool is_lock = true) override; std::optional<s32> sendmsg(s32 flags, const sys_net_msghdr& msg, bool is_lock = true) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override; std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
bool is_socket_connected(); bool is_socket_connected();
@@ -364,7 +364,7 @@ s32 lv2_socket_p2p::shutdown([[maybe_unused]] s32 how)
return CELL_OK; return CELL_OK;
} }
s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) void lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd)
{ {
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
ensure(vport); ensure(vport);
@@ -381,8 +381,6 @@ s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native
{ {
sn_pfd.revents |= SYS_NET_POLLOUT; sn_pfd.revents |= SYS_NET_POLLOUT;
} }
return sn_pfd.revents ? 1 : 0;
} }
std::tuple<bool, bool, bool> lv2_socket_p2p::select(bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd) std::tuple<bool, bool, bool> lv2_socket_p2p::select(bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
+1 -1
View File
@@ -30,7 +30,7 @@ public:
void close() override; void close() override;
s32 shutdown(s32 how) override; s32 shutdown(s32 how) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override; std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
void handle_new_data(sys_net_sockaddr_in_p2p p2p_addr, std::vector<u8> p2p_data); void handle_new_data(sys_net_sockaddr_in_p2p p2p_addr, std::vector<u8> p2p_data);
@@ -985,7 +985,7 @@ s32 lv2_socket_p2ps::shutdown([[maybe_unused]] s32 how)
return CELL_OK; return CELL_OK;
} }
s32 lv2_socket_p2ps::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) void lv2_socket_p2ps::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd)
{ {
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
sys_net.trace("[P2PS] poll checking for 0x%X", sn_pfd.events); sys_net.trace("[P2PS] poll checking for 0x%X", sn_pfd.events);
@@ -1002,14 +1002,7 @@ s32 lv2_socket_p2ps::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& nativ
{ {
sn_pfd.revents |= SYS_NET_POLLOUT; sn_pfd.revents |= SYS_NET_POLLOUT;
} }
if (sn_pfd.revents)
{
return 1;
} }
}
return 0;
} }
std::tuple<bool, bool, bool> lv2_socket_p2ps::select(bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd) std::tuple<bool, bool, bool> lv2_socket_p2ps::select(bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
+1 -1
View File
@@ -89,7 +89,7 @@ public:
void close() override; void close() override;
s32 shutdown(s32 how) override; s32 shutdown(s32 how) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override; std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
private: private:
@@ -134,10 +134,9 @@ s32 lv2_socket_raw::shutdown([[maybe_unused]] s32 how)
return {}; return {};
} }
s32 lv2_socket_raw::poll([[maybe_unused]] sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd) void lv2_socket_raw::poll([[maybe_unused]] sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native_pfd)
{ {
LOG_ONCE(raw_poll, "lv2_socket_raw::poll"); LOG_ONCE(raw_poll, "lv2_socket_raw::poll");
return {};
} }
std::tuple<bool, bool, bool> lv2_socket_raw::select([[maybe_unused]] bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd) std::tuple<bool, bool, bool> lv2_socket_raw::select([[maybe_unused]] bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
+1 -1
View File
@@ -32,6 +32,6 @@ public:
void close() override; void close() override;
s32 shutdown(s32 how) override; s32 shutdown(s32 how) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override; void poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override; std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
}; };
+1
View File
@@ -305,6 +305,7 @@ error_code sys_ppu_thread_detach(ppu_thread& ppu, u32 thread_id)
{ {
// Join and notify thread (it is detached from IDM now so it must be done explicitly now) // Join and notify thread (it is detached from IDM now so it must be done explicitly now)
*ptr = thread_state::finished; *ptr = thread_state::finished;
return CELL_OK;
} }
return result; return result;
+1 -1
View File
@@ -899,7 +899,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr<void> library)
{ {
for (u32 lib_addr = prx.exports_start, index = 0; lib_addr < prx.exports_end; index++, lib_addr += vm::read8(lib_addr) ? vm::read8(lib_addr) : sizeof_lib) for (u32 lib_addr = prx.exports_start, index = 0; lib_addr < prx.exports_end; index++, lib_addr += vm::read8(lib_addr) ? vm::read8(lib_addr) : sizeof_lib)
{ {
if (std::memcpy(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0) if (std::memcmp(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0)
{ {
atomic_storage<char>::release(prx.m_external_loaded_flags[index], true); atomic_storage<char>::release(prx.m_external_loaded_flags[index], true);
return true; return true;
+8 -8
View File
@@ -46,14 +46,14 @@ namespace rsxaudio_ringbuf_reader
static void set_timestamp(rsxaudio_shmem::ringbuf_t& ring_buf, u64 timestamp) static void set_timestamp(rsxaudio_shmem::ringbuf_t& ring_buf, u64 timestamp)
{ {
const s32 entry_idx_raw = (ring_buf.read_idx + ring_buf.rw_max_idx - (ring_buf.rw_max_idx > 2) - 1) % ring_buf.rw_max_idx; const s32 entry_idx_raw = (ring_buf.read_idx + ring_buf.rw_max_idx - (ring_buf.rw_max_idx > 2) - 1) % ring_buf.rw_max_idx;
const s32 entry_idx = std::clamp<s32>(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ); const s32 entry_idx = std::clamp<s32>(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1);
ring_buf.entries[entry_idx].timestamp = convert_to_timebased_time(timestamp); ring_buf.entries[entry_idx].timestamp = convert_to_timebased_time(timestamp);
} }
static std::tuple<bool /*notify*/, u64 /*blk_idx*/, u64 /*timestamp*/> update_status(rsxaudio_shmem::ringbuf_t& ring_buf) static std::tuple<bool /*notify*/, u64 /*blk_idx*/, u64 /*timestamp*/> update_status(rsxaudio_shmem::ringbuf_t& ring_buf)
{ {
const s32 read_idx = std::clamp<s32>(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ); const s32 read_idx = std::clamp<s32>(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1);
if ((ring_buf.entries[read_idx].valid & 1) == 0U) if ((ring_buf.entries[read_idx].valid & 1) == 0U)
{ {
@@ -61,7 +61,7 @@ namespace rsxaudio_ringbuf_reader
} }
const s32 entry_idx_raw = (ring_buf.read_idx + ring_buf.rw_max_idx - (ring_buf.rw_max_idx > 2)) % ring_buf.rw_max_idx; const s32 entry_idx_raw = (ring_buf.read_idx + ring_buf.rw_max_idx - (ring_buf.rw_max_idx > 2)) % ring_buf.rw_max_idx;
const s32 entry_idx = std::clamp<s32>(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ); const s32 entry_idx = std::clamp<s32>(entry_idx_raw, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1);
ring_buf.entries[read_idx].valid = 0; ring_buf.entries[read_idx].valid = 0;
ring_buf.queue_notify_idx = (ring_buf.queue_notify_idx + 1) % ring_buf.queue_notify_step; ring_buf.queue_notify_idx = (ring_buf.queue_notify_idx + 1) % ring_buf.queue_notify_step;
@@ -72,7 +72,7 @@ namespace rsxaudio_ringbuf_reader
static std::pair<bool /*entry_valid*/, u32 /*addr*/> get_addr(const rsxaudio_shmem::ringbuf_t& ring_buf) static std::pair<bool /*entry_valid*/, u32 /*addr*/> get_addr(const rsxaudio_shmem::ringbuf_t& ring_buf)
{ {
const s32 read_idx = std::clamp<s32>(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ); const s32 read_idx = std::clamp<s32>(ring_buf.read_idx, 0, SYS_RSXAUDIO_RINGBUF_SZ - 1);
if (ring_buf.entries[read_idx].valid & 1) if (ring_buf.entries[read_idx].valid & 1)
{ {
@@ -1392,9 +1392,9 @@ void rsxaudio_backend_thread::operator()()
return; return;
} }
static rsxaudio_state ra_state{}; rsxaudio_state ra_state{};
static emu_audio_cfg emu_cfg{}; emu_audio_cfg emu_cfg{};
static bool backend_failed = false; bool backend_failed = false;
for (;;) for (;;)
{ {
@@ -2018,7 +2018,7 @@ void rsxaudio_periodic_tmr::cancel_timer_unlocked()
{ {
const u64 flag = 1; const u64 flag = 1;
const auto wr_res = write(cancel_event, &flag, sizeof(flag)); const auto wr_res = write(cancel_event, &flag, sizeof(flag));
ensure(wr_res == sizeof(flag) || wr_res == -EAGAIN); ensure(wr_res == sizeof(flag) || errno == EAGAIN);
} }
#elif defined(BSD) || defined(__APPLE__) #elif defined(BSD) || defined(__APPLE__)
handle[TIMER_ID].flags = (handle[TIMER_ID].flags & ~EV_ENABLE) | EV_DISABLE; handle[TIMER_ID].flags = (handle[TIMER_ID].flags & ~EV_ENABLE) | EV_DISABLE;
+2 -1
View File
@@ -24,7 +24,7 @@ struct lv2_update_manager
// For example, 4.90 should be converted to 0x4900000000000 // For example, 4.90 should be converted to 0x4900000000000
std::erase(version_str, '.'); std::erase(version_str, '.');
if (std::from_chars(version_str.data(), version_str.data() + version_str.size(), system_sw_version, 16).ec != std::errc{}) if (std::from_chars(version_str.data(), version_str.data() + version_str.size(), system_sw_version, 16).ec == std::errc{})
system_sw_version <<= 40; system_sw_version <<= 40;
else else
system_sw_version = 0; system_sw_version = 0;
@@ -79,6 +79,7 @@ struct lv2_update_manager
if (malloc_set.count(addr)) if (malloc_set.count(addr))
{ {
malloc_set.erase(addr);
return vm::dealloc(addr, vm::main); return vm::dealloc(addr, vm::main);
} }
+4 -2
View File
@@ -1531,9 +1531,11 @@ private:
} }
}(); }();
if (sce_idx == umax)
return PS3AV_STATUS_INVALID_VIDEO_PARAM;
const video_sce_param &sce_param = sce_param_arr[sce_idx]; const video_sce_param &sce_param = sce_param_arr[sce_idx];
if (sce_idx == umax || if (video_head_cfg.video_head > PS3AV_HEAD_B_ANALOG ||
video_head_cfg.video_head > PS3AV_HEAD_B_ANALOG ||
video_head_cfg.video_order > 1 || video_head_cfg.video_order > 1 ||
video_head_cfg.video_format > 16 || video_head_cfg.video_format > 16 ||
video_head_cfg.video_out_format > 16 || video_head_cfg.video_out_format > 16 ||
+10 -6
View File
@@ -1173,11 +1173,15 @@ error_code sys_usbd_get_device_list(ppu_thread& ppu, u32 handle, vm::ptr<UsbInte
return CELL_EINVAL; return CELL_EINVAL;
// TODO: was std::min<s32> // TODO: was std::min<s32>
u32 i_tocopy = std::min<u32>(max_devices, ::size32(usbh.handled_devices)); const u32 i_tocopy = std::min<u32>(max_devices, ::size32(usbh.handled_devices));
u32 index = 0;
for (u32 index = 0; index < i_tocopy; index++) for (const auto& [_, device] : usbh.handled_devices)
{ {
device_list[index] = usbh.handled_devices[index].first; if (index == i_tocopy)
break;
device_list[index++] = device.first;
} }
return not_an_error(i_tocopy); return not_an_error(i_tocopy);
@@ -1409,7 +1413,7 @@ error_code sys_usbd_receive_event(ppu_thread& ppu, u32 handle, vm::ptr<u64> arg1
if (is_stopped(state)) if (is_stopped(state))
{ {
std::lock_guard lock(usbh.mutex); std::lock_guard lock(usbh.mutex_sq);
for (auto cpu = +usbh.sq; cpu; cpu = cpu->next_cpu) for (auto cpu = +usbh.sq; cpu; cpu = cpu->next_cpu)
{ {
@@ -1587,7 +1591,7 @@ error_code sys_usbd_get_transfer_status(ppu_thread& ppu, u32 handle, u32 id_tran
std::lock_guard lock(usbh.mutex); std::lock_guard lock(usbh.mutex);
if (!usbh.is_init) if (!usbh.is_init || id_transfer >= MAX_SYS_USBD_TRANSFERS)
return CELL_EINVAL; return CELL_EINVAL;
const auto status = usbh.get_transfer_status(id_transfer); const auto status = usbh.get_transfer_status(id_transfer);
@@ -1607,7 +1611,7 @@ error_code sys_usbd_get_isochronous_transfer_status(ppu_thread& ppu, u32 handle,
std::lock_guard lock(usbh.mutex); std::lock_guard lock(usbh.mutex);
if (!usbh.is_init) if (!usbh.is_init || id_transfer >= MAX_SYS_USBD_TRANSFERS)
return CELL_EINVAL; return CELL_EINVAL;
const auto status = usbh.get_isochronous_transfer_status(id_transfer); const auto status = usbh.get_isochronous_transfer_status(id_transfer);
+1 -1
View File
@@ -97,7 +97,7 @@ error_code sys_vm_memory_map(ppu_thread& ppu, u64 vsize, u64 psize, u32 cid, u64
// Look for unmapped space // Look for unmapped space
if (const auto area = vm::find_map(0x10000000, 0x10000000, 2 | (flag & SYS_MEMORY_PAGE_SIZE_MASK))) if (const auto area = vm::find_map(0x10000000, 0x10000000, 2 | (flag & SYS_MEMORY_PAGE_SIZE_MASK)))
{ {
sys_vm.warning("sys_vm_memory_map(): Found VM 0x%x area (vsize=0x%x)", addr, vsize); sys_vm.warning("sys_vm_memory_map(): Found VM 0x%x area (vsize=0x%x)", area->addr, vsize);
// Alloc all memory (shall not fail) // Alloc all memory (shall not fail)
ensure(area->alloc(static_cast<u32>(vsize))); ensure(area->alloc(static_cast<u32>(vsize)));