1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

Kernel Explorer partially restored

This commit is contained in:
Nekotekina 2014-12-24 19:09:32 +03:00
parent d8239a39c9
commit cbdc32e95e
21 changed files with 405 additions and 423 deletions

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Utilities/Log.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/ARMv7/PSVFuncList.h"

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Utilities/Log.h"
#include "Emu/System.h"
#include "PSVFuncList.h"

View File

@ -225,17 +225,34 @@ public:
return true;
}
//u32 GetTypeCount(IDType type)
//{
// if (type < TYPE_OTHER) {
// return (u32)m_types[type].size();
// }
// return 1;
//}
u32 GetTypeCount(IDType type)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
//const std::set<u32>& GetTypeIDs(IDType type)
//{
// assert(type < TYPE_OTHER);
// return m_types[type];
//}
if (type < TYPE_OTHER)
{
return (u32)m_types[type].size();
}
else
{
assert(!"Invalid ID type");
return 0;
}
}
std::set<u32> GetTypeIDs(IDType type)
{
// you cannot simply return reference to existing set
std::lock_guard<std::mutex> lock(m_mtx_main);
if (type < TYPE_OTHER)
{
return m_types[type];
}
else
{
assert(!"Invalid ID type");
return{};
}
}
};

View File

@ -0,0 +1,75 @@
#include "stdafx.h"
#include "Utilities/Log.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Memory/atomic_type.h"
#include "Utilities/SQueue.h"
#include "lv2/sleep_queue_type.h"
#include "lv2/sys_lwmutex.h"
#include "lv2/sys_lwcond.h"
#include "lv2/sys_mutex.h"
#include "lv2/sys_cond.h"
#include "lv2/sys_semaphore.h"
#include "SyncPrimitivesManager.h"
SemaphoreAttributes SyncPrimManager::GetSemaphoreData(u32 id)
{
std::shared_ptr<Semaphore> sem;
if (!Emu.GetIdManager().GetIDData(id, sem))
{
return{};
}
return{ std::string((const char*)&sem->name, 8), sem->value, sem->max };
}
LwMutexAttributes SyncPrimManager::GetLwMutexData(u32 id)
{
std::shared_ptr<sleep_queue_t> sq;
if (!Emu.GetIdManager().GetIDData(id, sq))
{
return{};
}
return{ std::string((const char*)&sq->name, 8) };
}
std::string SyncPrimManager::GetSyncPrimName(u32 id, IDType type)
{
switch (type)
{
case TYPE_LWCOND:
{
std::shared_ptr<Lwcond> lw;
if (Emu.GetIdManager().GetIDData(id, lw))
{
return std::string((const char*)&lw->queue.name, 8);
}
break;
}
case TYPE_MUTEX:
{
std::shared_ptr<Mutex> mutex;
if (Emu.GetIdManager().GetIDData(id, mutex))
{
return std::string((const char*)&mutex->queue.name, 8);
}
break;
}
case TYPE_COND:
{
std::shared_ptr<Cond> cond;
if (Emu.GetIdManager().GetIDData(id, cond))
{
return std::string((const char*)&cond->queue.name, 8);
}
break;
}
}
LOG_ERROR(GENERAL, "SyncPrimManager::GetSyncPrimName(id=%d, type=%d) failed", id, type);
return "NOT_FOUND";
}

View File

@ -1,119 +1,27 @@
#pragma once
#include <map>
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Utilities/Log.h"
struct SemaphoreAttributes
{
std::string name;
u32 count;
u32 max_count;
SemaphoreAttributes() {}
SemaphoreAttributes(const std::string& _name, u32 _count, u32 _max_count) : name(_name), count(_count), max_count(_max_count) {}
s32 count;
s32 max_count;
};
struct LwMutexAttributes
{
std::string name;
u32 owner_id;
std::string status; // TODO: check status?
LwMutexAttributes() {}
LwMutexAttributes(const std::string& _name, u32 _owner_id, std::string _status = "INITIALIZED")
: name(_name), owner_id(_owner_id), status(_status) {}
};
class SyncPrimManager
{
private:
std::map<u32, std::string> m_cond_name;
std::map<u32, std::string> m_mutex_name;
std::map<u32, std::string> m_lw_cond_name;
std::map<u32, LwMutexAttributes> m_lw_mutex_attr;
std::map<u32, SemaphoreAttributes> m_semaph_attr;
public:
// semaphores
void AddSemaphoreData(const u32 id, const std::string& name, const u32 count, const u32 max_count)
{
m_semaph_attr[id] = *(new SemaphoreAttributes(name, count, max_count));
}
void EraseSemaphoreData(const u32 id)
{
m_semaph_attr.erase(id);
}
SemaphoreAttributes& GetSemaphoreData(const u32 id)
{
return m_semaph_attr[id];
}
// lw_mutexes
void AddLwMutexData(const u32 id, const std::string& name, const u32 owner_id)
{
m_lw_mutex_attr[id] = *(new LwMutexAttributes(name, owner_id));
}
void EraseLwMutexData(const u32 id)
{
m_lw_mutex_attr.erase(id);
}
LwMutexAttributes& GetLwMutexData(const u32 id)
{
return m_lw_mutex_attr[id];
}
// lw_conditions, mutexes, conditions
void AddSyncPrimData(const IDType type, const u32 id, const std::string& name)
{
switch (type)
{
case TYPE_LWCOND: m_lw_cond_name[id] = name; break;
case TYPE_MUTEX: m_mutex_name[id] = name; break;
case TYPE_COND: m_cond_name[id] = name; break;
default: LOG_ERROR(GENERAL, "Unknown IDType = %d", type);
}
}
void EraseSyncPrimData(const IDType type, const u32 id)
{
switch (type)
{
case TYPE_LWCOND: m_lw_cond_name.erase(id); break;
case TYPE_MUTEX: m_mutex_name.erase(id); break;
case TYPE_COND: m_cond_name.erase(id); break;
default: LOG_ERROR(GENERAL, "Unknown IDType = %d", type);
}
}
const std::string& GetSyncPrimName(const IDType type, const u32 id)
{
static const std::string empty = "";
switch (type)
{
case TYPE_LWCOND: return m_lw_cond_name[id];
case TYPE_MUTEX: return m_mutex_name[id];
case TYPE_COND: return m_cond_name[id];
default: LOG_ERROR(GENERAL, "Unknown IDType = %d", type); return empty;
}
}
SemaphoreAttributes GetSemaphoreData(u32 id);
LwMutexAttributes GetLwMutexData(u32 id);
std::string GetSyncPrimName(u32 id, IDType type);
void Close()
{
m_cond_name.clear();
m_mutex_name.clear();
m_lw_cond_name.clear();
m_lw_mutex_attr.clear();
m_semaph_attr.clear();
}
};

View File

@ -2,14 +2,25 @@
#include "Utilities/Log.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
sleep_queue_t::~sleep_queue_t()
{
for (auto& tid : m_list)
{
LOG_NOTICE(HLE, "~sleep_queue_t(): thread %d", tid);
}
}
void sleep_queue_t::push(u32 tid, u32 protocol)
{
assert(tid);
switch (protocol & SYS_SYNC_ATTR_PROTOCOL_MASK)
{
case SYS_SYNC_FIFO:
@ -17,7 +28,15 @@ void sleep_queue_t::push(u32 tid, u32 protocol)
{
std::lock_guard<std::mutex> lock(m_mutex);
list.push_back(tid);
for (auto& v : m_list)
{
if (v == tid)
{
assert(!"sleep_queue_t::push() failed (duplication)");
}
}
m_list.push_back(tid);
return;
}
case SYS_SYNC_RETRY:
@ -38,18 +57,20 @@ u32 sleep_queue_t::pop(u32 protocol)
{
std::lock_guard<std::mutex> lock(m_mutex);
while (true)
if (m_list.size())
{
if (list.size())
const u32 res = m_list[0];
if (!Emu.GetIdManager().CheckID(res))
{
u32 res = list[0];
list.erase(list.begin());
if (res && Emu.GetIdManager().CheckID(res))
// check thread
{
return res;
}
LOG_ERROR(HLE, "sleep_queue_t::pop(SYS_SYNC_FIFO): invalid thread (%d)", res);
Emu.Pause();
}
m_list.erase(m_list.begin());
return res;
}
else
{
return 0;
}
}
@ -57,42 +78,33 @@ u32 sleep_queue_t::pop(u32 protocol)
{
std::lock_guard<std::mutex> lock(m_mutex);
while (true)
u64 highest_prio = ~0ull;
u64 sel = ~0ull;
for (auto& v : m_list)
{
if (list.size())
if (std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(v))
{
u64 highest_prio = ~0ull;
u32 sel = 0;
for (u32 i = 0; i < list.size(); i++)
const u64 prio = t->GetPrio();
if (prio < highest_prio)
{
if (std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(list[i]))
{
u64 prio = t->GetPrio();
if (prio < highest_prio)
{
highest_prio = prio;
sel = i;
}
}
else
{
list[i] = 0;
sel = i;
break;
}
}
u32 res = list[sel];
list.erase(list.begin() + sel);
/* if (Emu.GetIdManager().CheckID(res)) */
if (res)
// check thread
{
return res;
highest_prio = prio;
sel = &v - m_list.data();
}
}
return 0;
else
{
LOG_ERROR(HLE, "sleep_queue_t::pop(SYS_SYNC_PRIORITY): invalid thread (%d)", v);
Emu.Pause();
}
}
if (~sel)
{
const u32 res = m_list[sel];
m_list.erase(m_list.begin() + sel);
return res;
}
// fallthrough
}
case SYS_SYNC_RETRY:
{
@ -107,13 +119,15 @@ u32 sleep_queue_t::pop(u32 protocol)
bool sleep_queue_t::invalidate(u32 tid)
{
assert(tid);
std::lock_guard<std::mutex> lock(m_mutex);
if (tid) for (u32 i = 0; i < list.size(); i++)
for (auto& v : m_list)
{
if (list[i] == tid)
if (v == tid)
{
list.erase(list.begin() + i);
m_list.erase(m_list.begin() + (&v - m_list.data()));
return true;
}
}
@ -125,27 +139,5 @@ u32 sleep_queue_t::count()
{
std::lock_guard<std::mutex> lock(m_mutex);
u32 result = 0;
for (u32 i = 0; i < list.size(); i++)
{
if (list[i]) result++;
}
return result;
}
bool sleep_queue_t::finalize()
{
if (!m_mutex.try_lock()) return false;
for (u32 i = 0; i < list.size(); i++)
{
if (list[i])
{
m_mutex.unlock();
return false;
}
}
m_mutex.unlock();
return true;
return (u32)m_list.size();
}

View File

@ -26,20 +26,23 @@ enum
SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //???
};
struct sleep_queue_t
class sleep_queue_t
{
std::vector<u32> list;
std::vector<u32> m_list;
std::mutex m_mutex;
u64 m_name;
public:
const u64 name;
sleep_queue_t(u64 name = 0)
: m_name(name)
: name(name)
{
}
~sleep_queue_t();
void push(u32 tid, u32 protocol);
u32 pop(u32 protocol);
bool invalidate(u32 tid);
u32 count();
bool finalize();
};

View File

@ -38,7 +38,6 @@ s32 sys_cond_create(vm::ptr<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribu
*cond_id = id;
mutex->cond_count++;
sys_cond.Warning("*** condition created [%s] (mutex_id=%d): id = %d", std::string(attr->name, 8).c_str(), mutex_id, id);
Emu.GetSyncPrimManager().AddSyncPrimData(TYPE_COND, id, std::string(attr->name, 8));
return CELL_OK;
}
@ -55,14 +54,13 @@ s32 sys_cond_destroy(u32 cond_id)
return CELL_ESRCH;
}
if (!cond->queue.finalize())
if (cond->queue.count()) // TODO: safely make object unusable
{
return CELL_EBUSY;
}
cond->mutex->cond_count--;
Emu.GetIdManager().RemoveID(cond_id);
Emu.GetSyncPrimManager().EraseSyncPrimData(TYPE_COND, cond_id);
return CELL_OK;
}

View File

@ -21,10 +21,9 @@ u32 event_queue_create(u32 protocol, s32 type, u64 name_u64, u64 event_queue_key
return 0;
}
std::string name((const char*)&name_u64, 8);
u32 id = sys_event.GetNewId(eq, TYPE_EVENT_QUEUE);
sys_event.Warning("*** event_queue created [%s] (protocol=0x%x, type=0x%x, key=0x%llx, size=0x%x): id = %d",
name.c_str(), protocol, type, event_queue_key, size, id);
std::string((const char*)&name_u64, 8).c_str(), protocol, type, event_queue_key, size, id);
return id;
}
@ -83,28 +82,27 @@ s32 sys_event_queue_destroy(u32 equeue_id, int mode)
return CELL_EINVAL;
}
u32 tid = GetCurrentPPUThread().GetId();
eq->sq.m_mutex.lock();
//u32 tid = GetCurrentPPUThread().GetId();
//eq->sq.m_mutex.lock();
//eq->owner.lock(tid);
// check if some threads are waiting for an event
if (!mode && eq->sq.list.size())
{
//eq->owner.unlock(tid);
eq->sq.m_mutex.unlock();
return CELL_EBUSY;
}
//if (!mode && eq->sq.list.size())
//{
// eq->owner.unlock(tid);
// eq->sq.m_mutex.unlock();
// return CELL_EBUSY;
//}
//eq->owner.unlock(tid, ~0);
eq->sq.m_mutex.unlock();
while (eq->sq.list.size())
{
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
if (Emu.IsStopped())
{
sys_event.Warning("sys_event_queue_destroy(equeue=%d) aborted", equeue_id);
break;
}
}
//eq->sq.m_mutex.unlock();
//while (eq->sq.list.size())
//{
// std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
// if (Emu.IsStopped())
// {
// sys_event.Warning("sys_event_queue_destroy(equeue=%d) aborted", equeue_id);
// break;
// }
//}
Emu.GetEventManager().UnregisterKey(eq->key);
eq->ports.clear();
@ -135,20 +133,19 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_data> event_arra
return CELL_OK;
}
u32 tid = GetCurrentPPUThread().GetId();
eq->sq.m_mutex.lock();
//u32 tid = GetCurrentPPUThread().GetId();
//eq->sq.m_mutex.lock();
//eq->owner.lock(tid);
if (eq->sq.list.size())
{
*number = 0;
//eq->owner.unlock(tid);
eq->sq.m_mutex.unlock();
return CELL_OK;
}
//if (eq->sq.list.size())
//{
// *number = 0;
// eq->owner.unlock(tid);
// eq->sq.m_mutex.unlock();
// return CELL_OK;
//}
*number = eq->events.pop_all(event_array.get_ptr(), size);
//eq->owner.unlock(tid);
eq->sq.m_mutex.unlock();
//eq->sq.m_mutex.unlock();
return CELL_OK;
}
@ -251,7 +248,7 @@ u32 event_port_create(u64 name)
std::shared_ptr<EventPort> eport(new EventPort());
u32 id = sys_event.GetNewId(eport, TYPE_EVENT_PORT);
eport->name = name ? name : ((u64)process_getpid() << 32) | (u64)id;
sys_event.Warning("*** sys_event_port created: id = %d", id);
sys_event.Warning("*** sys_event_port created: id = %d, name=0x%llx", id, eport->name);
return id;
}

View File

@ -5,6 +5,7 @@
#include "Emu/Memory/atomic_type.h"
#include "Utilities/SQueue.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sys_event_flag.h"
@ -13,9 +14,8 @@ SysCallBase sys_event_flag("sys_event_flag");
u32 EventFlag::check()
{
sleep_queue_t sq; // TODO: implement without sleep queue
u32 target = 0;
u64 highest_prio = ~0ull;
const u64 flag_set = flags.read_sync();
for (u32 i = 0; i < waiters.size(); i++)
@ -28,13 +28,25 @@ u32 EventFlag::check()
target = waiters[i].tid;
break;
}
sq.list.push_back(waiters[i].tid);
else if (protocol == SYS_SYNC_PRIORITY)
{
if (std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(waiters[i].tid))
{
const u64 prio = t->GetPrio();
if (prio < highest_prio)
{
highest_prio = prio;
target = waiters[i].tid;
}
}
else
{
assert(!"EventFlag::check(): waiter not found");
}
}
}
}
if (protocol == SYS_SYNC_PRIORITY)
target = sq.pop(SYS_SYNC_PRIORITY);
return target;
}
@ -74,11 +86,11 @@ s32 sys_event_flag_create(vm::ptr<u32> eflag_id, vm::ptr<sys_event_flag_attr> at
default: return CELL_EINVAL;
}
std::shared_ptr<EventFlag> ef(new EventFlag(init, (u32)attr->protocol, (int)attr->type));
std::shared_ptr<EventFlag> ef(new EventFlag(init, (u32)attr->protocol, (s32)attr->type, attr->name_u64));
u32 id = sys_event_flag.GetNewId(ef, TYPE_EVENT_FLAG);
*eflag_id = id;
sys_event_flag.Warning("*** event_flag created [%s] (protocol=0x%x, type=0x%x): id = %d",
std::string(attr->name, 8).c_str(), (u32)attr->protocol, (int)attr->type, id);
std::string(attr->name, 8).c_str(), (u32)attr->protocol, (s32)attr->type, id);
return CELL_OK;
}

View File

@ -17,9 +17,13 @@ struct sys_event_flag_attr
be_t<u32> protocol;
be_t<u32> pshared;
be_t<u64> ipc_key;
be_t<int> flags;
be_t<int> type;
char name[8];
be_t<s32> flags;
be_t<s32> type;
union
{
char name[8];
u64 name_u64;
};
};
struct EventFlagWaiter
@ -35,12 +39,15 @@ struct EventFlag
SQueue<u32, 32> signal;
std::mutex mutex; // protects waiters
std::vector<EventFlagWaiter> waiters;
const u32 protocol;
const int type;
const u64 name;
EventFlag(u64 pattern, u32 protocol, int type)
EventFlag(u64 pattern, u32 protocol, int type, u64 name)
: protocol(protocol)
, type(type)
, name(name)
{
flags.write_relaxed(pattern);
}

View File

@ -23,13 +23,7 @@ s32 lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name_u64)
lwcond.lwmutex.set(addr);
lwcond.lwcond_queue = id;
std::string name((const char*)&name_u64, 8);
sys_lwcond.Warning("*** lwcond created [%s] (lwmutex_addr=0x%x): id = %d",
name.c_str(), addr, id);
Emu.GetSyncPrimManager().AddSyncPrimData(TYPE_LWCOND, id, name);
sys_lwcond.Warning("*** lwcond created [%s] (lwmutex_addr=0x%x): id = %d", std::string((const char*)&name_u64, 8).c_str(), addr, id);
return CELL_OK;
}
@ -55,13 +49,12 @@ s32 sys_lwcond_destroy(vm::ptr<sys_lwcond_t> lwcond)
return CELL_ESRCH;
}
if (!lw->queue.finalize())
if (lw->queue.count()) // TODO: safely make object unusable
{
return CELL_EBUSY;
}
Emu.GetIdManager().RemoveID(id);
Emu.GetSyncPrimManager().EraseSyncPrimData(TYPE_LWCOND, id);
return CELL_OK;
}

View File

@ -25,11 +25,7 @@ s32 lwmutex_create(sys_lwmutex_t& lwmutex, u32 protocol, u32 recursive, u64 name
u32 sq_id = sys_lwmutex.GetNewId(sq, TYPE_LWMUTEX);
lwmutex.sleep_queue = sq_id;
std::string name((const char*)&name_u64, 8);
sys_lwmutex.Notice("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", name.c_str(), protocol | recursive, sq_id);
Emu.GetSyncPrimManager().AddLwMutexData(sq_id, name, 0);
sys_lwmutex.Notice("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", std::string((const char*)&name_u64, 8).c_str(), protocol | recursive, sq_id);
return CELL_OK;
}
@ -65,17 +61,17 @@ s32 sys_lwmutex_destroy(PPUThread& CPU, vm::ptr<sys_lwmutex_t> lwmutex)
u32 sq_id = lwmutex->sleep_queue;
if (!Emu.GetIdManager().CheckID(sq_id)) return CELL_ESRCH;
// try to make it unable to lock
switch (int res = lwmutex->trylock(be_t<u32>::make(~0)))
if (s32 res = lwmutex->trylock(be_t<u32>::make(~0)))
{
case CELL_OK:
lwmutex->all_info() = 0;
lwmutex->attribute = 0xDEADBEEF;
lwmutex->sleep_queue = 0;
Emu.GetIdManager().RemoveID(sq_id);
Emu.GetSyncPrimManager().EraseLwMutexData(sq_id);
default: return res;
return res;
}
// try to make it unable to lock
lwmutex->all_info() = 0;
lwmutex->attribute = 0xDEADBEEF;
lwmutex->sleep_queue = 0;
Emu.GetIdManager().RemoveID(sq_id);
return CELL_OK;
}
s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout)

View File

@ -19,17 +19,10 @@ Mutex::~Mutex()
sys_mutex.Notice("Mutex(%d) was owned by thread %d (recursive=%d)", id, tid, recursive_count.load());
}
if (!queue.m_mutex.try_lock()) return;
for (u32 i = 0; i < queue.list.size(); i++)
if (u32 count = queue.count())
{
if (u32 owner = queue.list[i])
{
sys_mutex.Notice("Mutex(%d) was waited by thread %d", id, owner);
}
sys_mutex.Notice("Mutex(%d) was waited by %d threads", id, count);
}
queue.m_mutex.unlock();
}
s32 sys_mutex_create(PPUThread& CPU, vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute> attr)
@ -68,9 +61,7 @@ s32 sys_mutex_create(PPUThread& CPU, vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_at
sys_mutex.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d",
std::string(attr->name, 8).c_str(), (u32) attr->protocol, (is_recursive ? "true" : "false"), id);
Emu.GetSyncPrimManager().AddSyncPrimData(TYPE_MUTEX, id, std::string(attr->name, 8));
// TODO: unlock mutex when owner thread does exit
return CELL_OK;
}
@ -98,7 +89,7 @@ s32 sys_mutex_destroy(PPUThread& CPU, u32 mutex_id)
return CELL_EBUSY;
}
if (!mutex->queue.finalize())
if (mutex->queue.count()) // TODO: safely make object unusable
{
if (!mutex->owner.compare_and_swap_test(tid, 0))
{
@ -112,7 +103,6 @@ s32 sys_mutex_destroy(PPUThread& CPU, u32 mutex_id)
assert(!"sys_mutex_destroy() failed");
}
Emu.GetIdManager().RemoveID(mutex_id);
Emu.GetSyncPrimManager().EraseSyncPrimData(TYPE_MUTEX, mutex_id);
return CELL_OK;
}

View File

@ -201,26 +201,26 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr<u32> nump)
switch(object)
{
//case SYS_MEM_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MEM); break;
//case SYS_MUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX); break;
//case SYS_COND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_COND); break;
//case SYS_RWLOCK_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_RWLOCK); break;
//case SYS_INTR_TAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_TAG); break;
//case SYS_INTR_SERVICE_HANDLE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_SERVICE_HANDLE); break;
//case SYS_EVENT_QUEUE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE); break;
//case SYS_EVENT_PORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_PORT); break;
//case SYS_TRACE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TRACE); break;
//case SYS_SPUIMAGE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUIMAGE); break;
//case SYS_PRX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_PRX); break;
//case SYS_SPUPORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUPORT); break;
//case SYS_LWMUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX); break;
//case SYS_TIMER_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TIMER); break;
//case SYS_SEMAPHORE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE); break;
//case SYS_LWCOND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND); break;
//case SYS_EVENT_FLAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG); break;
//case SYS_FS_FD_OBJECT:
// *nump = Emu.GetIdManager().GetTypeCount(TYPE_FS_FILE) + Emu.GetIdManager().GetTypeCount(TYPE_FS_DIR);
// break;
case SYS_MEM_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MEM); break;
case SYS_MUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX); break;
case SYS_COND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_COND); break;
case SYS_RWLOCK_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_RWLOCK); break;
case SYS_INTR_TAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_TAG); break;
case SYS_INTR_SERVICE_HANDLE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_INTR_SERVICE_HANDLE); break;
case SYS_EVENT_QUEUE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE); break;
case SYS_EVENT_PORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_PORT); break;
case SYS_TRACE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TRACE); break;
case SYS_SPUIMAGE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUIMAGE); break;
case SYS_PRX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_PRX); break;
case SYS_SPUPORT_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SPUPORT); break;
case SYS_LWMUTEX_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX); break;
case SYS_TIMER_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_TIMER); break;
case SYS_SEMAPHORE_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE); break;
case SYS_LWCOND_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND); break;
case SYS_EVENT_FLAG_OBJECT: *nump = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG); break;
case SYS_FS_FD_OBJECT:
*nump = Emu.GetIdManager().GetTypeCount(TYPE_FS_FILE) + Emu.GetIdManager().GetTypeCount(TYPE_FS_DIR);
break;
default:
return CELL_EINVAL;
@ -239,30 +239,30 @@ s32 sys_process_get_id(u32 object, vm::ptr<u32> buffer, u32 size, vm::ptr<u32> s
#define ADD_OBJECTS(type) { \
u32 i=0; \
const auto& objects = Emu.GetIdManager().GetTypeIDs(type); \
const auto objects = Emu.GetIdManager().GetTypeIDs(type); \
for(auto id=objects.begin(); i<size && id!=objects.end(); id++, i++) \
buffer[i] = *id; \
*set_size = i; \
}
//case SYS_MEM_OBJECT: ADD_OBJECTS(TYPE_MEM); break;
//case SYS_MUTEX_OBJECT: ADD_OBJECTS(TYPE_MUTEX); break;
//case SYS_COND_OBJECT: ADD_OBJECTS(TYPE_COND); break;
//case SYS_RWLOCK_OBJECT: ADD_OBJECTS(TYPE_RWLOCK); break;
//case SYS_INTR_TAG_OBJECT: ADD_OBJECTS(TYPE_INTR_TAG); break;
//case SYS_INTR_SERVICE_HANDLE_OBJECT: ADD_OBJECTS(TYPE_INTR_SERVICE_HANDLE); break;
//case SYS_EVENT_QUEUE_OBJECT: ADD_OBJECTS(TYPE_EVENT_QUEUE); break;
//case SYS_EVENT_PORT_OBJECT: ADD_OBJECTS(TYPE_EVENT_PORT); break;
//case SYS_TRACE_OBJECT: ADD_OBJECTS(TYPE_TRACE); break;
//case SYS_SPUIMAGE_OBJECT: ADD_OBJECTS(TYPE_SPUIMAGE); break;
//case SYS_PRX_OBJECT: ADD_OBJECTS(TYPE_PRX); break;
//case SYS_SPUPORT_OBJECT: ADD_OBJECTS(TYPE_SPUPORT); break;
//case SYS_LWMUTEX_OBJECT: ADD_OBJECTS(TYPE_LWMUTEX); break;
//case SYS_TIMER_OBJECT: ADD_OBJECTS(TYPE_TIMER); break;
//case SYS_SEMAPHORE_OBJECT: ADD_OBJECTS(TYPE_SEMAPHORE); break;
//case SYS_FS_FD_OBJECT: ADD_OBJECTS(TYPE_FS_FILE);/*TODO:DIR*/ break;
//case SYS_LWCOND_OBJECT: ADD_OBJECTS(TYPE_LWCOND); break;
//case SYS_EVENT_FLAG_OBJECT: ADD_OBJECTS(TYPE_EVENT_FLAG); break;
case SYS_MEM_OBJECT: ADD_OBJECTS(TYPE_MEM); break;
case SYS_MUTEX_OBJECT: ADD_OBJECTS(TYPE_MUTEX); break;
case SYS_COND_OBJECT: ADD_OBJECTS(TYPE_COND); break;
case SYS_RWLOCK_OBJECT: ADD_OBJECTS(TYPE_RWLOCK); break;
case SYS_INTR_TAG_OBJECT: ADD_OBJECTS(TYPE_INTR_TAG); break;
case SYS_INTR_SERVICE_HANDLE_OBJECT: ADD_OBJECTS(TYPE_INTR_SERVICE_HANDLE); break;
case SYS_EVENT_QUEUE_OBJECT: ADD_OBJECTS(TYPE_EVENT_QUEUE); break;
case SYS_EVENT_PORT_OBJECT: ADD_OBJECTS(TYPE_EVENT_PORT); break;
case SYS_TRACE_OBJECT: ADD_OBJECTS(TYPE_TRACE); break;
case SYS_SPUIMAGE_OBJECT: ADD_OBJECTS(TYPE_SPUIMAGE); break;
case SYS_PRX_OBJECT: ADD_OBJECTS(TYPE_PRX); break;
case SYS_SPUPORT_OBJECT: ADD_OBJECTS(TYPE_SPUPORT); break;
case SYS_LWMUTEX_OBJECT: ADD_OBJECTS(TYPE_LWMUTEX); break;
case SYS_TIMER_OBJECT: ADD_OBJECTS(TYPE_TIMER); break;
case SYS_SEMAPHORE_OBJECT: ADD_OBJECTS(TYPE_SEMAPHORE); break;
case SYS_FS_FD_OBJECT: ADD_OBJECTS(TYPE_FS_FILE);/*TODO:DIR*/ break;
case SYS_LWCOND_OBJECT: ADD_OBJECTS(TYPE_LWCOND); break;
case SYS_EVENT_FLAG_OBJECT: ADD_OBJECTS(TYPE_EVENT_FLAG); break;
#undef ADD_OBJECTS

View File

@ -17,10 +17,8 @@ u32 semaphore_create(s32 initial_count, s32 max_count, u32 protocol, u64 name_u6
LV2_LOCK(0);
std::shared_ptr<Semaphore> sem(new Semaphore(initial_count, max_count, protocol, name_u64));
const std::string name((const char*)&name_u64, 8);
const u32 id = sys_semaphore.GetNewId(sem, TYPE_SEMAPHORE);
sys_semaphore.Notice("*** semaphore created [%s] (protocol=0x%x): id = %d", name.c_str(), protocol, id);
Emu.GetSyncPrimManager().AddSemaphoreData(id, name, initial_count, max_count);
sys_semaphore.Notice("*** semaphore created [%s] (protocol=0x%x): id = %d", std::string((const char*)&name_u64, 8).c_str(), protocol, id);
return id;
}
@ -76,13 +74,12 @@ s32 sys_semaphore_destroy(u32 sem_id)
return CELL_ESRCH;
}
if (!sem->queue.finalize())
if (sem->queue.count()) // TODO: safely make object unusable
{
return CELL_EBUSY;
}
Emu.GetIdManager().RemoveID(sem_id);
Emu.GetSyncPrimManager().EraseSemaphoreData(sem_id);
return CELL_OK;
}

View File

@ -23,6 +23,7 @@
#include "Emu/RSX/GSManager.h"
#include "Emu/Audio/AudioManager.h"
#include "Emu/FS/VFS.h"
#include "Emu/SysCalls/SyncPrimitivesManager.h"
#include "Loader/PSF.h"

View File

@ -1,7 +1,6 @@
#pragma once
#include "Loader/Loader.h"
#include "Emu/SysCalls/SyncPrimitivesManager.h"
enum Status
{

View File

@ -4,9 +4,10 @@
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "KernelExplorer.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/SysCalls/SyncPrimitivesManager.h"
#include "KernelExplorer.h"
KernelExplorer::KernelExplorer(wxWindow* parent)
: wxFrame(parent, wxID_ANY, "Kernel Explorer", wxDefaultPosition, wxSize(700, 450))
@ -53,135 +54,125 @@ void KernelExplorer::Update()
// TODO: FileSystem
// Semaphores
//count = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE);
//if (count)
//{
// sprintf(name, "Semaphores (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_SEMAPHORE);
// for (const auto& id : objects)
// {
// sprintf(name, "Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d", id, Emu.GetSyncPrimManager().GetSemaphoreData(id).name.c_str(),
// Emu.GetSyncPrimManager().GetSemaphoreData(id).count, Emu.GetSyncPrimManager().GetSemaphoreData(id).max_count);
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_SEMAPHORE);
if (count)
{
sprintf(name, "Semaphores (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_SEMAPHORE))
{
auto sem = Emu.GetSyncPrimManager().GetSemaphoreData(id);
sprintf(name, "Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d", id, sem.name.c_str(), sem.count, sem.max_count);
m_tree->AppendItem(node, name);
}
}
// Mutexes
//count = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX);
//if (count)
//{
// sprintf(name, "Mutexes (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_MUTEX);
// for (const auto& id : objects)
// {
// sprintf(name, "Mutex: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(TYPE_MUTEX, id).c_str());
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_MUTEX);
if (count)
{
sprintf(name, "Mutexes (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_MUTEX))
{
sprintf(name, "Mutex: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_MUTEX).c_str());
m_tree->AppendItem(node, name);
}
}
// Light Weight Mutexes
//count = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX);
//if (count)
//{
// sprintf(name, "Light Weight Mutexes (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_LWMUTEX);
// for (const auto& id : objects)
// {
// sprintf(name, "LW Mutex: ID = 0x%08x '%s', Owner Thread ID = 0x%08x - %s", id, Emu.GetSyncPrimManager().GetLwMutexData(id).name.c_str(),
// Emu.GetSyncPrimManager().GetLwMutexData(id).owner_id, Emu.GetSyncPrimManager().GetLwMutexData(id).status.c_str());
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX);
if (count)
{
sprintf(name, "Light Weight Mutexes (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_LWMUTEX))
{
auto lwm = Emu.GetSyncPrimManager().GetLwMutexData(id);
sprintf(name, "LW Mutex: ID = 0x%08x '%s'", id, lwm.name.c_str());
m_tree->AppendItem(node, name);
}
}
// Condition Variables
//count = Emu.GetIdManager().GetTypeCount(TYPE_COND);
//if (count)
//{
// sprintf(name, "Condition Variables (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_COND);
// for (const auto& id : objects)
// {
// sprintf(name, "Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(TYPE_COND, id).c_str());
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_COND);
if (count)
{
sprintf(name, "Condition Variables (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_COND))
{
sprintf(name, "Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_COND).c_str());
m_tree->AppendItem(node, name);
}
}
// Light Weight Condition Variables
//count = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND);
//if (count)
//{
// sprintf(name, "Light Weight Condition Variables (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_LWCOND);
// for (const auto& id : objects)
// {
// sprintf(name, "LW Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(TYPE_LWCOND, id).c_str());
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND);
if (count)
{
sprintf(name, "Light Weight Condition Variables (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_LWCOND))
{
sprintf(name, "LW Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_LWCOND).c_str());
m_tree->AppendItem(node, name);
}
}
// Event Queues
//count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE);
//if (count)
//{
// sprintf(name, "Event Queues (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_QUEUE);
// for (const auto& id : objects)
// {
// sprintf(name, "Event Queue: ID = 0x%08x", id);
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_QUEUE);
if (count)
{
sprintf(name, "Event Queues (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_QUEUE))
{
sprintf(name, "Event Queue: ID = 0x%08x", id);
m_tree->AppendItem(node, name);
}
}
// Modules
//count = Emu.GetIdManager().GetTypeCount(TYPE_PRX);
//if (count)
//{
// sprintf(name, "Modules (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_PRX);
// sprintf(name, "Segment List (%l)", 2 * objects.size()); // TODO: Assuming 2 segments per PRX file is not good
// m_tree->AppendItem(node, name);
// for (const auto& id : objects)
// {
// sprintf(name, "PRX: ID = 0x%08x", id);
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_PRX);
if (count)
{
sprintf(name, "Modules (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
//sprintf(name, "Segment List (%l)", 2 * objects.size()); // TODO: Assuming 2 segments per PRX file is not good
//m_tree->AppendItem(node, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_PRX))
{
sprintf(name, "PRX: ID = 0x%08x", id);
m_tree->AppendItem(node, name);
}
}
// Memory Containers
//count = Emu.GetIdManager().GetTypeCount(TYPE_MEM);
//if (count)
//{
// sprintf(name, "Memory Containers (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_MEM);
// for (const auto& id : objects)
// {
// sprintf(name, "Memory Container: ID = 0x%08x", id);
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_MEM);
if (count)
{
sprintf(name, "Memory Containers (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_MEM))
{
sprintf(name, "Memory Container: ID = 0x%08x", id);
m_tree->AppendItem(node, name);
}
}
// Event Flags
//count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG);
//if (count)
//{
// sprintf(name, "Event Flags (%d)", count);
// const auto& node = m_tree->AppendItem(root, name);
// const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_FLAG);
// for (const auto& id : objects)
// {
// sprintf(name, "Event Flag: ID = 0x%08x", id);
// m_tree->AppendItem(node, name);
// }
//}
count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_FLAG);
if (count)
{
sprintf(name, "Event Flags (%d)", count);
const auto& node = m_tree->AppendItem(root, name);
for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_FLAG))
{
sprintf(name, "Event Flag: ID = 0x%08x", id);
m_tree->AppendItem(node, name);
}
}
// PPU / SPU / RawSPU threads
{

View File

@ -236,6 +236,7 @@
<ClCompile Include="Emu\SysCalls\Modules\sys_io.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sys_net.cpp" />
<ClCompile Include="Emu\SysCalls\Static.cpp" />
<ClCompile Include="Emu\SysCalls\SyncPrimitivesManager.cpp" />
<ClCompile Include="Emu\SysCalls\SysCalls.cpp" />
<ClCompile Include="Emu\System.cpp" />
<ClCompile Include="Ini.cpp" />

View File

@ -653,6 +653,9 @@
<ClCompile Include="Emu\SysCalls\lv2\sleep_queue_type.cpp">
<Filter>Emu\SysCalls\lv2</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\SyncPrimitivesManager.cpp">
<Filter>Emu\SysCalls</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">