mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-04-02 11:01:43 -04:00
fix pipe fix socketpair fix bridge fix evf_wait with timeout fix umtx_op(0x17) implement ipmi evf stub sched_get_priority_max/min stub sys_rtprio_thread implement sys_yield emit event on signal stub ajm register/unregister ioctls stub av_control ioctl hack removal
95 lines
2.3 KiB
C++
95 lines
2.3 KiB
C++
#pragma once
|
|
#include "KernelAllocator.hpp"
|
|
#include "thread/Thread.hpp"
|
|
#include "utils/SharedMutex.hpp"
|
|
#include <atomic>
|
|
|
|
namespace orbis {
|
|
enum {
|
|
kEvfAttrThFifo = 0x01,
|
|
kEvfAttrThPrio = 0x02,
|
|
kEvfAttrSingle = 0x10,
|
|
kEvfAttrMulti = 0x20,
|
|
kEvfAttrShared = 0x100,
|
|
};
|
|
|
|
enum {
|
|
kEvfWaitModeAnd = 0x01,
|
|
kEvfWaitModeOr = 0x02,
|
|
kEvfWaitModeClearAll = 0x10,
|
|
kEvfWaitModeClearPat = 0x20,
|
|
};
|
|
|
|
struct EventFlag final {
|
|
char name[32];
|
|
|
|
bool isDeleted = false;
|
|
std::uint8_t attrs = kEvfAttrMulti | kEvfAttrThFifo;
|
|
std::atomic<unsigned> references{0};
|
|
std::atomic<std::uint64_t> value{0};
|
|
|
|
struct WaitingThread {
|
|
Thread *thread;
|
|
std::uint64_t bitPattern;
|
|
std::uint8_t waitMode;
|
|
|
|
bool operator==(const WaitingThread &) const = default;
|
|
|
|
bool test(std::uint64_t value) const {
|
|
if (waitMode & kEvfWaitModeAnd) {
|
|
return (value & bitPattern) == bitPattern;
|
|
}
|
|
|
|
return (value & bitPattern) != 0;
|
|
}
|
|
|
|
std::uint64_t applyClear(std::uint64_t value) {
|
|
if (waitMode & kEvfWaitModeClearAll) {
|
|
return 0;
|
|
}
|
|
|
|
if (waitMode & kEvfWaitModeClearPat) {
|
|
return value & ~bitPattern;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
};
|
|
|
|
utils::shared_mutex queueMtx;
|
|
utils::kvector<WaitingThread> waitingThreads;
|
|
|
|
enum class NotifyType { Set, Cancel, Destroy };
|
|
|
|
EventFlag() = default;
|
|
EventFlag(std::int32_t attrs, std::uint64_t initPattern)
|
|
: attrs(attrs), value(initPattern) {}
|
|
|
|
ErrorCode wait(Thread *thread, std::uint8_t waitMode,
|
|
std::uint64_t bitPattern, std::uint32_t *timeout);
|
|
ErrorCode tryWait(Thread *thread, std::uint8_t waitMode,
|
|
std::uint64_t bitPattern);
|
|
std::size_t notify(NotifyType type, std::uint64_t bits);
|
|
|
|
std::size_t destroy() { return notify(NotifyType::Destroy, {}); }
|
|
|
|
std::size_t cancel(std::uint64_t value) {
|
|
return notify(NotifyType::Cancel, value);
|
|
}
|
|
|
|
std::size_t set(std::uint64_t bits) { return notify(NotifyType::Set, bits); }
|
|
|
|
void clear(std::uint64_t bits) {
|
|
writer_lock lock(queueMtx);
|
|
value.fetch_and(bits, std::memory_order::relaxed);
|
|
}
|
|
|
|
void incRef() { references.fetch_add(1, std::memory_order::relaxed); }
|
|
|
|
void decRef() {
|
|
if (references.fetch_sub(1, std::memory_order::relaxed) == 1) {
|
|
kdelete(this);
|
|
}
|
|
}
|
|
};
|
|
} // namespace orbis
|