[orbis-kernel] evf: implement shared evf

Protect shared evfs with mutex
Fixed memory leak on shared evf allocation
Fixed set condition on wait
Update RcIdMap usage to use new api
This commit is contained in:
DH 2023-07-08 02:21:10 +03:00
parent e613f09b6d
commit 800c1ffcdc
6 changed files with 50 additions and 22 deletions

View file

@ -27,12 +27,19 @@ public:
std::pair<EventFlag *, bool> createEventFlag(utils::kstring name,
std::int32_t flags) {
auto [it, inserted] =
m_event_flags.try_emplace(std::move(name), knew<EventFlag>(flags));
std::lock_guard lock(m_evf_mtx);
auto [it, inserted] = m_event_flags.try_emplace(std::move(name), nullptr);
if (inserted) {
it->second = knew<EventFlag>(flags);
}
return {it->second.get(), inserted};
}
Ref<EventFlag> findEventFlag(std::string_view name) {
std::lock_guard lock(m_evf_mtx);
if (auto it = m_event_flags.find(name); it != m_event_flags.end()) {
return it->second;
}
@ -41,6 +48,7 @@ public:
}
private:
shared_mutex m_evf_mtx;
mutable pthread_mutex_t m_heap_mtx;
void *m_heap_next = this + 1;
bool m_heap_is_freeing = false;

View file

@ -11,6 +11,7 @@ enum {
kEvfAttrThPrio = 0x02,
kEvfAttrSingle = 0x10,
kEvfAttrMulti = 0x20,
kEvfAttrShared = 0x100,
};
enum {

View file

@ -119,7 +119,7 @@ std::size_t orbis::EventFlag::notify(NotifyType type, std::uint64_t bits) {
}
auto testThread = [&](WaitingThread *thread) {
if (type != NotifyType::Set && !thread->test(patValue)) {
if (type == NotifyType::Set && !thread->test(patValue)) {
return false;
}

View file

@ -253,5 +253,5 @@ orbis::SysResult orbis::Module::relocate(Process *process) {
void orbis::Module::destroy() {
std::lock_guard lock(proc->mtx);
proc->modulesMap.remove(id);
proc->modulesMap.close(id);
}

View file

@ -9,7 +9,7 @@
orbis::SysResult orbis::sys_netcontrol(Thread *thread, sint fd, uint op,
ptr<void> buf, uint nbuf) {
return ErrorCode::NOSYS;
return {};
}
orbis::SysResult orbis::sys_netabort(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;
@ -19,7 +19,7 @@ orbis::SysResult orbis::sys_netgetsockinfo(Thread *thread /* TODO */) {
}
orbis::SysResult orbis::sys_socketex(Thread *thread, ptr<const char> name,
sint domain, sint type, sint protocol) {
return ErrorCode::NOSYS;
return {};
}
orbis::SysResult orbis::sys_socketclose(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;
@ -53,6 +53,9 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
auto int_value = reinterpret_cast<nonsys_int *>(value);
const char *const string = "someString";
ORBIS_LOG_TODO(__FUNCTION__, string);
ORBIS_LOG_TODO(
__FUNCTION__, int_value->encoded_id,
int_value->encoded_id_parts.data[0],
@ -86,8 +89,8 @@ orbis::SysResult orbis::sys_evf_create(Thread *thread, ptr<char> name,
return ErrorCode::INVAL;
}
if (attrs &
~(kEvfAttrSingle | kEvfAttrMulti | kEvfAttrThPrio | kEvfAttrThFifo)) {
if (attrs & ~(kEvfAttrSingle | kEvfAttrMulti | kEvfAttrThPrio |
kEvfAttrThFifo | kEvfAttrShared)) {
return ErrorCode::INVAL;
}
@ -117,7 +120,22 @@ orbis::SysResult orbis::sys_evf_create(Thread *thread, ptr<char> name,
return result;
}
auto eventFlag = knew<EventFlag>(attrs);
EventFlag *eventFlag;
if (attrs & kEvfAttrShared) {
auto [insertedEvf, inserted] =
thread->tproc->context->createEventFlag(_name, attrs);
if (!inserted) {
return ErrorCode::EXIST; // FIXME: verify
}
eventFlag = insertedEvf;
} else {
eventFlag = knew<EventFlag>(attrs);
}
ORBIS_LOG_WARNING(__FUNCTION__, _name);
thread->retval[0] = thread->tproc->evfMap.insert(eventFlag);
return {};
}
@ -127,10 +145,7 @@ orbis::SysResult orbis::sys_evf_delete(Thread *thread, sint id) {
return ErrorCode::SRCH;
}
// TODO: do destroy and remove atomically
evf->destroy();
thread->tproc->evfMap.remove(id);
thread->tproc->evfMap.destroy(id);
return {};
}
orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr<char> name) {
@ -140,9 +155,13 @@ orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr<char> name) {
return result;
}
ORBIS_LOG_WARNING(__FUNCTION__, _name);
auto eventFlag = thread->tproc->context->findEventFlag(name);
if (eventFlag == nullptr) {
// HACK :)
return sys_evf_create(thread, name, kEvfAttrShared, nullptr);
return ErrorCode::SRCH;
}
@ -151,7 +170,7 @@ orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr<char> name) {
return {};
}
orbis::SysResult orbis::sys_evf_close(Thread *thread, sint id) {
if (!thread->tproc->evfMap.remove(id)) {
if (!thread->tproc->evfMap.close(id)) {
return ErrorCode::SRCH;
}
@ -541,11 +560,7 @@ orbis::SysResult orbis::sys_mdbg_service(Thread *thread, uint32_t op,
switch (op) {
case 1: {
auto prop = uread((ptr<mdbg_property>)arg0);
std::printf(
"sys_mdbg_service set property (name='%s', address=0x%lx, size=%lu)\n",
prop.name, prop.addr_ptr, prop.areaSize);
// FIXME: investigate crash
// ORBIS_LOG_WARNING(__FUNCTION__, prop.name, prop.addr_ptr, prop.areaSize);
ORBIS_LOG_WARNING(__FUNCTION__, prop.name, prop.addr_ptr, prop.areaSize);
break;
}

View file

@ -114,7 +114,7 @@ orbis::SysResult open(orbis::Thread *thread, orbis::ptr<const char> path,
}
orbis::SysResult close(orbis::Thread *thread, orbis::sint fd) {
if (!thread->tproc->fileDescriptors.remove(fd)) {
if (!thread->tproc->fileDescriptors.close(fd)) {
return ErrorCode::BADF;
}
@ -240,7 +240,7 @@ static std::string ioctlToString(unsigned long arg) {
orbis::SysResult ioctl(orbis::Thread *thread, orbis::sint fd, orbis::ulong com,
orbis::caddr_t argp) {
std::printf("ioctl: %s\n", ioctlToString(com).c_str());
std::printf("ioctl: %d %s\n", (int)fd, ioctlToString(com).c_str());
Ref<IoDeviceInstance> handle =
static_cast<IoDeviceInstance *>(thread->tproc->fileDescriptors.get(fd));
@ -248,6 +248,10 @@ orbis::SysResult ioctl(orbis::Thread *thread, orbis::sint fd, orbis::ulong com,
return ErrorCode::BADF;
}
if (handle->ioctl == nullptr) {
return ErrorCode::NOTSUP;
}
auto result = handle->ioctl(handle.get(), com, argp);
if (result < 0) {
@ -411,7 +415,7 @@ orbis::SysResult dynlib_load_prx(orbis::Thread *thread,
thread->tproc->ops->processNeeded(thread);
auto result = module->relocate(thread->tproc);
if (result.isError()) {
thread->tproc->modulesMap.remove(module->id);
thread->tproc->modulesMap.close(module->id);
return result;
}