mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
id_traits, idm::get_last_id() added
id_traits for file/dir descriptors idm::get_current_id() removed, thread-local last ID
This commit is contained in:
parent
d9403c2ed2
commit
c2897cddd6
15 changed files with 166 additions and 165 deletions
|
@ -11,7 +11,7 @@
|
|||
|
||||
CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<std::string()> thread_name)
|
||||
: m_state({ CPU_STATE_STOPPED })
|
||||
, m_id(idm::get_current_id())
|
||||
, m_id(idm::get_last_id())
|
||||
, m_type(type)
|
||||
, m_name(name)
|
||||
{
|
||||
|
|
|
@ -5,16 +5,18 @@ namespace idm
|
|||
{
|
||||
std::mutex g_id_mutex;
|
||||
|
||||
std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
u32 g_cur_id = 1;
|
||||
thread_local u32 g_tls_last_id = 0xdeadbeef;
|
||||
|
||||
u32 g_last_raw_id = 0;
|
||||
|
||||
void clear()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
g_id_map.clear();
|
||||
g_cur_id = 1; // first ID
|
||||
g_last_raw_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,21 +2,34 @@
|
|||
|
||||
#define ID_MANAGER_INCLUDED
|
||||
|
||||
class ID_data_t final
|
||||
// default specialization for all types
|
||||
template<typename T> struct id_traits
|
||||
{
|
||||
// get next mapped id (may return 0 if out of IDs)
|
||||
static u32 next_id(u32 raw_id) { return raw_id < 0x80000000 ? (raw_id + 1) & 0x7fffffff : 0; }
|
||||
|
||||
// convert "public" id to mapped id (may return 0 if invalid)
|
||||
static u32 in_id(u32 id) { return id; }
|
||||
|
||||
// convert mapped id to "public" id
|
||||
static u32 out_id(u32 raw_id) { return raw_id; }
|
||||
};
|
||||
|
||||
class id_data_t final
|
||||
{
|
||||
public:
|
||||
const std::shared_ptr<void> data;
|
||||
const std::type_info& info;
|
||||
const std::size_t hash;
|
||||
|
||||
template<typename T> force_inline ID_data_t(std::shared_ptr<T> data)
|
||||
template<typename T> force_inline id_data_t(std::shared_ptr<T> data)
|
||||
: data(std::move(data))
|
||||
, info(typeid(T))
|
||||
, hash(typeid(T).hash_code())
|
||||
{
|
||||
}
|
||||
|
||||
ID_data_t(ID_data_t&& right)
|
||||
id_data_t(id_data_t&& right)
|
||||
: data(std::move(const_cast<std::shared_ptr<void>&>(right.data)))
|
||||
, info(right.info)
|
||||
, hash(right.hash)
|
||||
|
@ -27,9 +40,17 @@ public:
|
|||
// ID Manager
|
||||
// 0 is invalid ID
|
||||
// 1..0x7fffffff : general purpose IDs
|
||||
// 0x80000000+ : reserved
|
||||
// 0x80000000+ : reserved (may be used through id_traits specializations)
|
||||
namespace idm
|
||||
{
|
||||
// can be called from the constructor called through make() or make_ptr() to get the ID of currently created object
|
||||
inline u32 get_last_id()
|
||||
{
|
||||
thread_local extern u32 g_tls_last_id;
|
||||
|
||||
return g_tls_last_id;
|
||||
}
|
||||
|
||||
// reinitialize ID manager
|
||||
void clear();
|
||||
|
||||
|
@ -37,85 +58,81 @@ namespace idm
|
|||
template<typename T> bool check(u32 id)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
const auto found = g_id_map.find(id);
|
||||
const auto found = g_id_map.find(id_traits<T>::in_id(id));
|
||||
|
||||
return found != g_id_map.end() && found->second.info == typeid(T);
|
||||
}
|
||||
|
||||
// check if ID exists and return its type or nullptr
|
||||
inline const std::type_info* get_type(u32 id)
|
||||
inline const std::type_info* get_type(u32 raw_id)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
const auto found = g_id_map.find(id);
|
||||
const auto found = g_id_map.find(raw_id);
|
||||
|
||||
return found == g_id_map.end() ? nullptr : &found->second.info;
|
||||
}
|
||||
|
||||
// must be called from the constructor called through make() or make_ptr() to get further ID of current object
|
||||
inline u32 get_current_id()
|
||||
{
|
||||
// contains the next ID or 0x80000000 | current_ID
|
||||
extern u32 g_cur_id;
|
||||
|
||||
if ((g_cur_id & 0x80000000) == 0)
|
||||
{
|
||||
throw EXCEPTION("Current ID is not available");
|
||||
}
|
||||
|
||||
return g_cur_id & 0x7fffffff;
|
||||
}
|
||||
|
||||
// add new ID of specified type with specified constructor arguments (returns object)
|
||||
// add new ID of specified type with specified constructor arguments (returns object or nullptr)
|
||||
template<typename T, typename... Args> std::enable_if_t<std::is_constructible<T, Args...>::value, std::shared_ptr<T>> make_ptr(Args&&... args)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern u32 g_cur_id;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
extern u32 g_last_raw_id;
|
||||
thread_local extern u32 g_tls_last_id;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
g_cur_id |= 0x80000000;
|
||||
u32 raw_id = g_last_raw_id;
|
||||
|
||||
if (const u32 id = g_cur_id & 0x7fffffff)
|
||||
while ((raw_id = id_traits<T>::next_id(raw_id)))
|
||||
{
|
||||
if (g_id_map.find(raw_id) != g_id_map.end()) continue;
|
||||
|
||||
g_tls_last_id = id_traits<T>::out_id(raw_id);
|
||||
|
||||
auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
|
||||
g_id_map.emplace(id, ID_data_t(ptr));
|
||||
g_id_map.emplace(raw_id, id_data_t(ptr));
|
||||
|
||||
g_cur_id = id + 1;
|
||||
if (raw_id < 0x80000000) g_last_raw_id = raw_id;
|
||||
|
||||
return std::move(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
throw EXCEPTION("Out of IDs");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// add new ID of specified type with specified constructor arguments (returns id)
|
||||
template<typename T, typename... Args> std::enable_if_t<std::is_constructible<T, Args...>::value, u32> make(Args&&... args)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern u32 g_cur_id;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
extern u32 g_last_raw_id;
|
||||
thread_local extern u32 g_tls_last_id;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
g_cur_id |= 0x80000000;
|
||||
u32 raw_id = g_last_raw_id;
|
||||
|
||||
if (const u32 id = g_cur_id & 0x7fffffff)
|
||||
while ((raw_id = id_traits<T>::next_id(raw_id)))
|
||||
{
|
||||
g_id_map.emplace(id, ID_data_t(std::make_shared<T>(std::forward<Args>(args)...)));
|
||||
if (g_id_map.find(raw_id) != g_id_map.end()) continue;
|
||||
|
||||
g_cur_id = id + 1;
|
||||
g_tls_last_id = id_traits<T>::out_id(raw_id);
|
||||
|
||||
return id;
|
||||
g_id_map.emplace(raw_id, id_data_t(std::make_shared<T>(std::forward<Args>(args)...)));
|
||||
|
||||
if (raw_id < 0x80000000) g_last_raw_id = raw_id;
|
||||
|
||||
return id_traits<T>::out_id(raw_id);
|
||||
}
|
||||
|
||||
throw EXCEPTION("Out of IDs");
|
||||
|
@ -125,18 +142,25 @@ namespace idm
|
|||
template<typename T> u32 import(const std::shared_ptr<T>& ptr)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern u32 g_cur_id;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
extern u32 g_last_raw_id;
|
||||
thread_local extern u32 g_tls_last_id;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
if (const u32 id = g_cur_id & 0x7fffffff)
|
||||
u32 raw_id = g_last_raw_id;
|
||||
|
||||
while ((raw_id = id_traits<T>::next_id(raw_id)))
|
||||
{
|
||||
g_id_map.emplace(id, ID_data_t(ptr));
|
||||
if (g_id_map.find(raw_id) != g_id_map.end()) continue;
|
||||
|
||||
g_cur_id = id + 1;
|
||||
g_tls_last_id = id_traits<T>::out_id(raw_id);
|
||||
|
||||
return id;
|
||||
g_id_map.emplace(raw_id, id_data_t(ptr));
|
||||
|
||||
if (raw_id < 0x80000000) g_last_raw_id = raw_id;
|
||||
|
||||
return id_traits<T>::out_id(raw_id);
|
||||
}
|
||||
|
||||
throw EXCEPTION("Out of IDs");
|
||||
|
@ -146,11 +170,11 @@ namespace idm
|
|||
template<typename T> std::shared_ptr<T> get(u32 id)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
const auto found = g_id_map.find(id);
|
||||
const auto found = g_id_map.find(id_traits<T>::in_id(id));
|
||||
|
||||
if (found == g_id_map.end() || found->second.info != typeid(T))
|
||||
{
|
||||
|
@ -164,7 +188,7 @@ namespace idm
|
|||
template<typename T> std::vector<std::shared_ptr<T>> get_all()
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
|
@ -187,11 +211,11 @@ namespace idm
|
|||
template<typename T> bool remove(u32 id)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
const auto found = g_id_map.find(id);
|
||||
const auto found = g_id_map.find(id_traits<T>::in_id(id));
|
||||
|
||||
if (found == g_id_map.end() || found->second.info != typeid(T))
|
||||
{
|
||||
|
@ -207,11 +231,11 @@ namespace idm
|
|||
template<typename T> std::shared_ptr<T> withdraw(u32 id)
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
const auto found = g_id_map.find(id);
|
||||
const auto found = g_id_map.find(id_traits<T>::in_id(id));
|
||||
|
||||
if (found == g_id_map.end() || found->second.info != typeid(T))
|
||||
{
|
||||
|
@ -228,7 +252,7 @@ namespace idm
|
|||
template<typename T> u32 get_count()
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
|
@ -251,7 +275,7 @@ namespace idm
|
|||
template<typename T> std::set<u32> get_set()
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
|
@ -263,7 +287,7 @@ namespace idm
|
|||
{
|
||||
if (v.second.hash == hash && v.second.info == typeid(T))
|
||||
{
|
||||
result.insert(v.first);
|
||||
result.insert(id_traits<T>::out_id(v.first));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,7 +298,7 @@ namespace idm
|
|||
template<typename T> std::map<u32, std::shared_ptr<T>> get_map()
|
||||
{
|
||||
extern std::mutex g_id_mutex;
|
||||
extern std::unordered_map<u32, ID_data_t> g_id_map;
|
||||
extern std::unordered_map<u32, id_data_t> g_id_map;
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_id_mutex);
|
||||
|
||||
|
@ -286,7 +310,7 @@ namespace idm
|
|||
{
|
||||
if (v.second.hash == hash && v.second.info == typeid(T))
|
||||
{
|
||||
result[v.first] = std::static_pointer_cast<T>(v.second.data);
|
||||
result[id_traits<T>::out_id(v.first)] = std::static_pointer_cast<T>(v.second.data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ PesHeader::PesHeader(DemuxerStream& stream)
|
|||
|
||||
ElementaryStream::ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr<CellDmuxCbEsMsg> cbFunc, u32 cbArg, u32 spec)
|
||||
: dmux(dmux)
|
||||
, id(idm::get_current_id())
|
||||
, id(idm::get_last_id())
|
||||
, memAddr(align(addr, 128))
|
||||
, memSize(size - (addr - memAddr))
|
||||
, fidMajor(fidMajor)
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
extern Module cellFs;
|
||||
|
||||
extern u32 _fd_to_id(u32 fd);
|
||||
|
||||
s32 cellFsOpen(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, vm::cptr<void> arg, u64 size)
|
||||
{
|
||||
cellFs.Warning("cellFsOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx) -> sys_fs_open()", path, flags, fd, arg, size);
|
||||
|
@ -211,7 +209,7 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32
|
|||
{
|
||||
cellFs.Warning("cellFsGetDirectoryEntries(fd=%d, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count);
|
||||
|
||||
const auto directory = idm::get<lv2_dir_t>(_fd_to_id(fd));
|
||||
const auto directory = idm::get<lv2_dir_t>(fd);
|
||||
|
||||
if (!directory)
|
||||
{
|
||||
|
@ -256,7 +254,7 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size,
|
|||
|
||||
// TODO: use single sys_fs_fcntl syscall
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file || file->flags & CELL_FS_O_WRONLY)
|
||||
{
|
||||
|
@ -287,7 +285,7 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr<void> buf, u64 data_size,
|
|||
|
||||
// TODO: use single sys_fs_fcntl syscall
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
|
||||
{
|
||||
|
@ -331,7 +329,7 @@ s32 cellFsStReadInit(u32 fd, vm::cptr<CellFsRingBuffer> ringbuf)
|
|||
return CELL_FS_EINVAL;
|
||||
}
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -369,7 +367,7 @@ s32 cellFsStReadFinish(u32 fd)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadFinish(fd=%d)", fd);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -392,7 +390,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, ringbuf=*0x%x)", fd, ringbuf);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -416,7 +414,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, status=*0x%x)", fd, status);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -450,7 +448,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, regid=*0x%x)", fd, regid);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -471,7 +469,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -552,7 +550,7 @@ s32 cellFsStReadStop(u32 fd)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadStop(fd=%d)", fd);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -583,7 +581,7 @@ s32 cellFsStRead(u32 fd, vm::ptr<u8> buf, u64 size, vm::ptr<u64> rsize)
|
|||
{
|
||||
cellFs.Warning("cellFsStRead(fd=%d, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -617,7 +615,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetCurrentAddr(fd=%d, addr=*0x%x, size=*0x%x)", fd, addr, size);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -650,7 +648,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr<u8> addr, u64 size)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadPutCurrentAddr(fd=%d, addr=*0x%x, size=0x%llx)", fd, addr, size);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -677,7 +675,7 @@ s32 cellFsStReadWait(u32 fd, u64 size)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadWait(fd=%d, size=0x%llx)", fd, size);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -706,7 +704,7 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadWaitCallback(fd=%d, size=0x%llx, func=*0x%x)", fd, size, func);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -874,7 +872,7 @@ void fsAio(vm::ptr<CellFsAio> aio, bool write, s32 xid, fs_aio_cb_t func)
|
|||
s32 error = CELL_OK;
|
||||
u64 result = 0;
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(aio->fd));
|
||||
const auto file = idm::get<lv2_file_t>(aio->fd);
|
||||
|
||||
if (!file || (!write && file->flags & CELL_FS_O_WRONLY) || (write && !(file->flags & CELL_FS_O_ACCMODE)))
|
||||
{
|
||||
|
@ -968,7 +966,7 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type
|
|||
{
|
||||
cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
|
|
@ -18,26 +18,16 @@ extern Module sceNpTrophy;
|
|||
|
||||
struct trophy_context_t
|
||||
{
|
||||
const u32 id;
|
||||
const u32 id = idm::get_last_id();
|
||||
|
||||
std::string trp_name;
|
||||
std::unique_ptr<vfsStream> trp_stream;
|
||||
std::unique_ptr<TROPUSRLoader> tropusr;
|
||||
|
||||
trophy_context_t()
|
||||
: id(idm::get_current_id())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct trophy_handle_t
|
||||
{
|
||||
const u32 id;
|
||||
|
||||
trophy_handle_t()
|
||||
: id(idm::get_current_id())
|
||||
{
|
||||
}
|
||||
const u32 id = idm::get_last_id();
|
||||
};
|
||||
|
||||
// Functions
|
||||
|
|
|
@ -16,7 +16,7 @@ SysCallBase sys_event("sys_event");
|
|||
extern u64 get_system_time();
|
||||
|
||||
lv2_event_queue_t::lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 key, s32 size)
|
||||
: id(idm::get_current_id())
|
||||
: id(idm::get_last_id())
|
||||
, protocol(protocol)
|
||||
, type(type)
|
||||
, name(name)
|
||||
|
|
|
@ -13,29 +13,6 @@
|
|||
|
||||
SysCallBase sys_fs("sys_fs");
|
||||
|
||||
std::array<atomic_t<u32>, 256> g_fds = {}; // file descriptors 0..255 mapped to IDs
|
||||
|
||||
u32 _fd_to_id(u32 fd)
|
||||
{
|
||||
return fd < g_fds.size() ? g_fds[fd].load() : 0;
|
||||
}
|
||||
|
||||
lv2_file_t::~lv2_file_t()
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
g_fds = {};
|
||||
}
|
||||
}
|
||||
|
||||
lv2_dir_t::~lv2_dir_t()
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
g_fds = {};
|
||||
}
|
||||
}
|
||||
|
||||
s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr<u32> arg3, u32 arg4, vm::ptr<char> arg5, u32 arg6)
|
||||
{
|
||||
sys_fs.Todo("sys_fs_test(arg1=0x%x, arg2=0x%x, arg3=*0x%x, arg4=0x%x, arg5=*0x%x, arg6=0x%x) -> CELL_OK", arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
|
@ -137,28 +114,24 @@ s32 sys_fs_open(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, s32 mode, vm::c
|
|||
return CELL_FS_ENOENT;
|
||||
}
|
||||
|
||||
for (u32 i = 3; i < g_fds.size(); i++)
|
||||
const auto _file = idm::make_ptr<lv2_file_t>(std::move(file), mode, flags);
|
||||
|
||||
if (!_file)
|
||||
{
|
||||
// try to reserve fd
|
||||
if (g_fds[i].compare_and_swap_test(0, ~0))
|
||||
{
|
||||
g_fds[i].store(idm::make<lv2_file_t>(std::move(file), mode, flags));
|
||||
|
||||
*fd = i;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
// out of file descriptors
|
||||
return CELL_FS_EMFILE;
|
||||
}
|
||||
|
||||
// out of file descriptors
|
||||
return CELL_FS_EMFILE;
|
||||
*fd = idm::get_last_id();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_fs_read(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread)
|
||||
{
|
||||
sys_fs.Log("sys_fs_read(fd=%d, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file || file->flags & CELL_FS_O_WRONLY)
|
||||
{
|
||||
|
@ -176,7 +149,7 @@ s32 sys_fs_write(u32 fd, vm::cptr<void> buf, u64 nbytes, vm::ptr<u64> nwrite)
|
|||
{
|
||||
sys_fs.Log("sys_fs_write(fd=%d, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
|
||||
{
|
||||
|
@ -196,7 +169,7 @@ s32 sys_fs_close(u32 fd)
|
|||
{
|
||||
sys_fs.Log("sys_fs_close(fd=%d)", fd);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -205,9 +178,7 @@ s32 sys_fs_close(u32 fd)
|
|||
|
||||
// TODO: return CELL_FS_EBUSY if locked
|
||||
|
||||
idm::remove<lv2_file_t>(_fd_to_id(fd));
|
||||
|
||||
g_fds[fd].store(0);
|
||||
idm::remove<lv2_file_t>(fd);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -225,28 +196,24 @@ s32 sys_fs_opendir(vm::cptr<char> path, vm::ptr<u32> fd)
|
|||
return CELL_FS_ENOENT;
|
||||
}
|
||||
|
||||
for (u32 i = 3; i < g_fds.size(); i++)
|
||||
const auto _dir = idm::make_ptr<lv2_dir_t>(std::move(dir));
|
||||
|
||||
if (!_dir)
|
||||
{
|
||||
// try to reserve fd
|
||||
if (g_fds[i].compare_and_swap_test(0, ~0))
|
||||
{
|
||||
g_fds[i].store(idm::make<lv2_dir_t>(std::move(dir)));
|
||||
|
||||
*fd = i;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
// out of file descriptors
|
||||
return CELL_FS_EMFILE;
|
||||
}
|
||||
|
||||
// out of file descriptors
|
||||
return CELL_FS_EMFILE;
|
||||
*fd = idm::get_last_id();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_fs_readdir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
|
||||
{
|
||||
sys_fs.Warning("sys_fs_readdir(fd=%d, dir=*0x%x, nread=*0x%x)", fd, dir, nread);
|
||||
|
||||
const auto directory = idm::get<lv2_dir_t>(_fd_to_id(fd));
|
||||
const auto directory = idm::get<lv2_dir_t>(fd);
|
||||
|
||||
if (!directory)
|
||||
{
|
||||
|
@ -274,16 +241,14 @@ s32 sys_fs_closedir(u32 fd)
|
|||
{
|
||||
sys_fs.Log("sys_fs_closedir(fd=%d)", fd);
|
||||
|
||||
const auto directory = idm::get<lv2_dir_t>(_fd_to_id(fd));
|
||||
const auto directory = idm::get<lv2_dir_t>(fd);
|
||||
|
||||
if (!directory)
|
||||
{
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
||||
idm::remove<lv2_dir_t>(_fd_to_id(fd));
|
||||
|
||||
g_fds[fd].store(0);
|
||||
idm::remove<lv2_dir_t>(fd);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -325,7 +290,7 @@ s32 sys_fs_fstat(u32 fd, vm::ptr<CellFsStat> sb)
|
|||
{
|
||||
sys_fs.Warning("sys_fs_fstat(fd=%d, sb=*0x%x)", fd, sb);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -456,7 +421,7 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr<u64> pos)
|
|||
return CELL_FS_EINVAL;
|
||||
}
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -474,7 +439,7 @@ s32 sys_fs_fget_block_size(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_
|
|||
{
|
||||
sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
|
@ -522,7 +487,7 @@ s32 sys_fs_ftruncate(u32 fd, u64 size)
|
|||
{
|
||||
sys_fs.Warning("sys_fs_ftruncate(fd=%d, size=0x%llx)", fd, size);
|
||||
|
||||
const auto file = idm::get<lv2_file_t>(_fd_to_id(fd));
|
||||
const auto file = idm::get<lv2_file_t>(fd);
|
||||
|
||||
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
|
||||
{
|
||||
|
|
|
@ -201,8 +201,28 @@ struct lv2_file_t
|
|||
, st_callback({})
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
~lv2_file_t();
|
||||
template<> struct id_traits<lv2_file_t>
|
||||
{
|
||||
static const u32 base = 0xfddd0000, max = 255;
|
||||
|
||||
static u32 next_id(u32 raw_id)
|
||||
{
|
||||
return
|
||||
raw_id < 0x80000000 ? base + 3 :
|
||||
raw_id - base < max ? raw_id + 1 : 0;
|
||||
}
|
||||
|
||||
static u32 in_id(u32 id)
|
||||
{
|
||||
return id + base;
|
||||
}
|
||||
|
||||
static u32 out_id(u32 raw_id)
|
||||
{
|
||||
return raw_id - base;
|
||||
}
|
||||
};
|
||||
|
||||
class vfsDirBase;
|
||||
|
@ -215,10 +235,10 @@ struct lv2_dir_t
|
|||
: dir(std::move(dir))
|
||||
{
|
||||
}
|
||||
|
||||
~lv2_dir_t();
|
||||
};
|
||||
|
||||
template<> struct id_traits<lv2_dir_t> : public id_traits<lv2_file_t> {};
|
||||
|
||||
// SysCalls
|
||||
s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr<u32> arg3, u32 arg4, vm::ptr<char> arg5, u32 arg6);
|
||||
s32 sys_fs_open(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, s32 mode, vm::cptr<void> arg, u64 size);
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
SysCallBase sys_interrupt("sys_interrupt");
|
||||
|
||||
lv2_int_tag_t::lv2_int_tag_t()
|
||||
: id(idm::get_current_id())
|
||||
: id(idm::get_last_id())
|
||||
{
|
||||
}
|
||||
|
||||
lv2_int_serv_t::lv2_int_serv_t(const std::shared_ptr<PPUThread>& thread)
|
||||
: thread(thread)
|
||||
, id(idm::get_current_id())
|
||||
, id(idm::get_last_id())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ SysCallBase sys_memory("sys_memory");
|
|||
|
||||
lv2_memory_container_t::lv2_memory_container_t(u32 size)
|
||||
: size(size)
|
||||
, id(idm::get_current_id())
|
||||
, id(idm::get_last_id())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ SysCallBase sys_mmapper("sys_mmapper");
|
|||
lv2_memory_t::lv2_memory_t(u32 size, u32 align, u64 flags, const std::shared_ptr<lv2_memory_container_t> ct)
|
||||
: size(size)
|
||||
, align(align)
|
||||
, id(idm::get_current_id())
|
||||
, id(idm::get_last_id())
|
||||
, flags(flags)
|
||||
, ct(ct)
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
SysCallBase sys_prx("sys_prx");
|
||||
|
||||
lv2_prx_t::lv2_prx_t()
|
||||
: id(idm::get_current_id())
|
||||
: id(idm::get_last_id())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ lv2_timer_t::lv2_timer_t()
|
|||
, period(0)
|
||||
, state(SYS_TIMER_STATE_STOP)
|
||||
{
|
||||
auto name = fmt::format("Timer[0x%x] Thread", idm::get_current_id());
|
||||
auto name = fmt::format("Timer[0x%x] Thread", idm::get_last_id());
|
||||
|
||||
thread.start([name]{ return name; }, [this]()
|
||||
{
|
||||
|
|
|
@ -134,6 +134,8 @@ struct explicit_bool_t
|
|||
#define EXCEPTION(text, ...) fmt::exception(__FILE__, __LINE__, __FUNCTION__, text, ##__VA_ARGS__)
|
||||
#define VM_CAST(value) vm::impl_cast(value, __FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
template<typename T> struct id_traits;
|
||||
|
||||
#define _PRGNAME_ "RPCS3"
|
||||
#define _PRGVER_ "0.0.0.5"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue