2014-02-07 22:55:25 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
2016-04-14 00:23:53 +02:00
|
|
|
#include "sys_sync.h"
|
2015-06-19 17:49:38 +02:00
|
|
|
|
2015-03-04 05:42:04 +01:00
|
|
|
// Event Queue Type
|
|
|
|
|
enum : u32
|
2014-08-08 17:55:12 +02:00
|
|
|
{
|
|
|
|
|
SYS_PPU_QUEUE = 1,
|
|
|
|
|
SYS_SPU_QUEUE = 2,
|
|
|
|
|
};
|
|
|
|
|
|
2015-03-04 05:42:04 +01:00
|
|
|
// Event Queue Destroy Mode
|
|
|
|
|
enum : s32
|
2014-02-07 22:55:25 +01:00
|
|
|
{
|
2014-08-08 17:55:12 +02:00
|
|
|
SYS_EVENT_QUEUE_DESTROY_FORCE = 1,
|
2014-02-07 22:55:25 +01:00
|
|
|
};
|
|
|
|
|
|
2015-02-21 21:54:53 +01:00
|
|
|
// Event Queue Ipc Key
|
|
|
|
|
enum : u64
|
|
|
|
|
{
|
2015-07-19 23:29:40 +02:00
|
|
|
SYS_EVENT_QUEUE_LOCAL = 0,
|
2015-02-21 21:54:53 +01:00
|
|
|
};
|
|
|
|
|
|
2015-03-04 05:42:04 +01:00
|
|
|
// Event Port Type
|
|
|
|
|
enum : s32
|
2014-02-07 22:55:25 +01:00
|
|
|
{
|
2014-08-08 17:55:12 +02:00
|
|
|
SYS_EVENT_PORT_LOCAL = 1,
|
2014-02-07 22:55:25 +01:00
|
|
|
};
|
|
|
|
|
|
2015-02-21 21:54:53 +01:00
|
|
|
// Event Port Name
|
|
|
|
|
enum : u64
|
|
|
|
|
{
|
|
|
|
|
SYS_EVENT_PORT_NO_NAME = 0,
|
|
|
|
|
};
|
|
|
|
|
|
2015-03-04 05:42:04 +01:00
|
|
|
// Event Source Type
|
|
|
|
|
enum : u32
|
2014-03-17 16:07:47 +01:00
|
|
|
{
|
2014-08-08 17:55:12 +02:00
|
|
|
SYS_SPU_THREAD_EVENT_USER = 1,
|
2015-03-04 05:42:04 +01:00
|
|
|
SYS_SPU_THREAD_EVENT_DMA = 2, // not supported
|
2014-03-17 16:07:47 +01:00
|
|
|
};
|
|
|
|
|
|
2015-03-04 05:42:04 +01:00
|
|
|
// Event Source Key
|
|
|
|
|
enum : u64
|
2014-02-07 22:55:25 +01:00
|
|
|
{
|
2015-02-21 21:54:53 +01:00
|
|
|
SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501ull,
|
|
|
|
|
SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502ull,
|
|
|
|
|
SYS_SPU_THREAD_EVENT_EXCEPTION_KEY = 0xFFFFFFFF53505503ull,
|
2014-08-08 17:55:12 +02:00
|
|
|
};
|
|
|
|
|
|
2015-07-09 17:30:37 +02:00
|
|
|
struct sys_event_queue_attribute_t
|
2014-08-08 17:55:12 +02:00
|
|
|
{
|
|
|
|
|
be_t<u32> protocol; // SYS_SYNC_PRIORITY or SYS_SYNC_FIFO
|
2014-09-19 02:19:22 +02:00
|
|
|
be_t<s32> type; // SYS_PPU_QUEUE or SYS_SPU_QUEUE
|
2015-09-26 22:46:04 +02:00
|
|
|
char name[8];
|
2014-08-08 17:55:12 +02:00
|
|
|
};
|
|
|
|
|
|
2015-03-04 05:42:04 +01:00
|
|
|
struct sys_event_t
|
2014-08-08 17:55:12 +02:00
|
|
|
{
|
|
|
|
|
be_t<u64> source;
|
|
|
|
|
be_t<u64> data1;
|
|
|
|
|
be_t<u64> data2;
|
|
|
|
|
be_t<u64> data3;
|
|
|
|
|
};
|
|
|
|
|
|
2016-04-14 00:23:53 +02:00
|
|
|
class lv2_event_queue_t final
|
2014-08-08 17:55:12 +02:00
|
|
|
{
|
2016-04-14 00:23:53 +02:00
|
|
|
// Tuple elements: source, data1, data2, data3
|
|
|
|
|
using event_type = std::tuple<u64, u64, u64, u64>;
|
|
|
|
|
|
|
|
|
|
std::deque<event_type> m_events;
|
|
|
|
|
|
|
|
|
|
sleep_queue<cpu_thread> m_sq;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// Try to make an event queue with specified global key
|
|
|
|
|
static std::shared_ptr<lv2_event_queue_t> make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size);
|
|
|
|
|
|
|
|
|
|
// Get event queue by its global key
|
|
|
|
|
static std::shared_ptr<lv2_event_queue_t> find(u64 ipc_key);
|
|
|
|
|
|
2015-03-04 05:42:04 +01:00
|
|
|
const u32 protocol;
|
|
|
|
|
const s32 type;
|
|
|
|
|
const u64 name;
|
2016-04-14 00:23:53 +02:00
|
|
|
const u64 ipc_key;
|
2015-03-04 05:42:04 +01:00
|
|
|
const s32 size;
|
2016-04-27 00:27:24 +02:00
|
|
|
|
|
|
|
|
const id_value<> id{};
|
2016-04-14 00:23:53 +02:00
|
|
|
|
|
|
|
|
lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size)
|
|
|
|
|
: protocol(protocol)
|
|
|
|
|
, type(type)
|
|
|
|
|
, name(name)
|
|
|
|
|
, ipc_key(ipc_key)
|
|
|
|
|
, size(size)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Send an event
|
|
|
|
|
void push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3);
|
|
|
|
|
|
|
|
|
|
// Receive an event (queue shouldn't be empty)
|
|
|
|
|
event_type pop(lv2_lock_t);
|
2014-03-17 16:07:47 +01:00
|
|
|
|
2016-04-14 00:23:53 +02:00
|
|
|
// Remove all events
|
|
|
|
|
void clear(lv2_lock_t)
|
|
|
|
|
{
|
|
|
|
|
m_events.clear();
|
|
|
|
|
}
|
2014-08-08 17:55:12 +02:00
|
|
|
|
2016-04-14 00:23:53 +02:00
|
|
|
// Get event count
|
|
|
|
|
std::size_t events() const { return m_events.size(); }
|
2014-08-08 17:55:12 +02:00
|
|
|
|
2016-04-14 00:23:53 +02:00
|
|
|
// Get waiter count
|
|
|
|
|
std::size_t waiters() const { return m_sq.size(); }
|
2015-03-05 14:18:06 +01:00
|
|
|
|
2016-04-14 00:23:53 +02:00
|
|
|
// Get threads (TODO)
|
|
|
|
|
auto& thread_queue(lv2_lock_t) { return m_sq; }
|
2014-08-08 17:55:12 +02:00
|
|
|
};
|
|
|
|
|
|
2015-05-27 05:11:59 +02:00
|
|
|
struct lv2_event_port_t
|
2014-08-08 17:55:12 +02:00
|
|
|
{
|
2015-03-04 22:51:14 +01:00
|
|
|
const s32 type; // port type, must be SYS_EVENT_PORT_LOCAL
|
|
|
|
|
const u64 name; // passed as event source (generated from id and process id if not set)
|
2015-07-19 14:58:11 +02:00
|
|
|
|
2015-05-27 05:11:59 +02:00
|
|
|
std::weak_ptr<lv2_event_queue_t> queue; // event queue this port is connected to
|
2014-08-08 17:55:12 +02:00
|
|
|
|
2015-05-27 05:11:59 +02:00
|
|
|
lv2_event_port_t(s32 type, u64 name)
|
2015-03-04 22:51:14 +01:00
|
|
|
: type(type)
|
|
|
|
|
, name(name)
|
2014-08-08 17:55:12 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-27 23:43:22 +02:00
|
|
|
class ppu_thread;
|
2014-09-19 02:19:22 +02:00
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
// SysCalls
|
2015-07-09 17:30:37 +02:00
|
|
|
s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attribute_t> attr, u64 event_queue_key, s32 size);
|
2014-09-19 02:19:22 +02:00
|
|
|
s32 sys_event_queue_destroy(u32 equeue_id, s32 mode);
|
2016-07-27 23:43:22 +02:00
|
|
|
s32 sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout);
|
2015-06-22 00:27:58 +02:00
|
|
|
s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number);
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_event_queue_drain(u32 event_queue_id);
|
|
|
|
|
|
2015-06-22 00:27:58 +02:00
|
|
|
s32 sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name);
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_event_port_destroy(u32 eport_id);
|
|
|
|
|
s32 sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
|
|
|
|
|
s32 sys_event_port_disconnect(u32 eport_id);
|
|
|
|
|
s32 sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);
|