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:
Nekotekina 2015-08-11 19:14:53 +03:00
parent d9403c2ed2
commit c2897cddd6
15 changed files with 166 additions and 165 deletions

View File

@ -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)
{

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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)
{

View 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

View File

@ -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)

View File

@ -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))
{

View File

@ -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);

View File

@ -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())
{
}

View File

@ -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())
{
}

View File

@ -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)
{

View File

@ -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())
{
}

View File

@ -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]()
{

View File

@ -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"