2013-11-09 02:05:58 +01:00
|
|
|
#include "stdafx.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Emu/Memory/Memory.h"
|
|
|
|
|
#include "Emu/System.h"
|
2013-11-09 02:05:58 +01:00
|
|
|
#include "Emu/SysCalls/SysCalls.h"
|
2014-08-23 16:51:51 +02:00
|
|
|
|
|
|
|
|
#include "Emu/Event.h"
|
2014-07-06 01:30:28 +02:00
|
|
|
#include "sys_timer.h"
|
2013-11-09 02:05:58 +01:00
|
|
|
|
|
|
|
|
SysCallBase sys_timer("sys_timer");
|
|
|
|
|
|
2014-10-11 19:20:01 +02:00
|
|
|
s32 sys_timer_create(vm::ptr<u32> timer_id)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2014-09-01 02:51:48 +02:00
|
|
|
sys_timer.Warning("sys_timer_create(timer_id_addr=0x%x)", timer_id.addr());
|
2013-11-09 02:05:58 +01:00
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<timer> timer_data(new timer);
|
2015-03-06 23:10:04 +01:00
|
|
|
*timer_id = Emu.GetIdManager().GetNewID(timer_data, TYPE_TIMER);
|
2013-11-09 02:05:58 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_timer_destroy(u32 timer_id)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2014-07-21 16:42:43 +02:00
|
|
|
sys_timer.Todo("sys_timer_destroy(timer_id=%d)", timer_id);
|
2013-11-09 02:05:58 +01:00
|
|
|
|
2015-03-06 23:10:04 +01:00
|
|
|
if(!Emu.GetIdManager().CheckID(timer_id)) return CELL_ESRCH;
|
2013-11-09 02:05:58 +01:00
|
|
|
|
|
|
|
|
Emu.GetIdManager().RemoveID(timer_id);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-02 03:05:13 +02:00
|
|
|
s32 sys_timer_get_information(u32 timer_id, vm::ptr<sys_timer_information_t> info)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2014-09-02 03:05:13 +02:00
|
|
|
sys_timer.Warning("sys_timer_get_information(timer_id=%d, info_addr=0x%x)", timer_id, info.addr());
|
2013-11-09 02:05:58 +01:00
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<timer> timer_data = nullptr;
|
2015-03-06 23:10:04 +01:00
|
|
|
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
2013-11-09 02:05:58 +01:00
|
|
|
|
2013-11-19 22:10:23 +01:00
|
|
|
*info = timer_data->timer_information_t;
|
2013-11-09 02:05:58 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_timer_start(u32 timer_id, s64 base_time, u64 period)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2015-01-13 15:54:36 +01:00
|
|
|
sys_timer.Warning("sys_timer_start_periodic_absolute(timer_id=%d, basetime=%lld, period=%lld)", timer_id, base_time, period);
|
2013-11-09 02:05:58 +01:00
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<timer> timer_data = nullptr;
|
2015-03-06 23:10:04 +01:00
|
|
|
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
2013-11-09 02:05:58 +01:00
|
|
|
|
|
|
|
|
if(timer_data->timer_information_t.timer_state != SYS_TIMER_STATE_STOP) return CELL_EBUSY;
|
|
|
|
|
if(period < 100) return CELL_EINVAL;
|
|
|
|
|
//TODO: if (timer is not connected to an event queue) return CELL_ENOTCONN;
|
|
|
|
|
|
|
|
|
|
timer_data->timer_information_t.next_expiration_time = base_time;
|
|
|
|
|
timer_data->timer_information_t.period = period;
|
|
|
|
|
timer_data->timer_information_t.timer_state = SYS_TIMER_STATE_RUN;
|
|
|
|
|
//TODO: ?
|
2014-07-11 13:59:13 +02:00
|
|
|
std::function<s32()> task(std::bind(sys_timer_stop, timer_id));
|
|
|
|
|
std::thread([period, task]() {
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(period));
|
|
|
|
|
task();
|
|
|
|
|
}).detach();
|
|
|
|
|
|
2013-11-09 02:05:58 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_timer_stop(u32 timer_id)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2014-07-21 16:42:43 +02:00
|
|
|
sys_timer.Todo("sys_timer_stop()");
|
2013-11-09 02:05:58 +01:00
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<timer> timer_data = nullptr;
|
2015-03-06 23:10:04 +01:00
|
|
|
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
2013-11-09 02:05:58 +01:00
|
|
|
|
|
|
|
|
timer_data->timer_information_t.timer_state = SYS_TIMER_STATE_STOP;
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_timer_connect_event_queue(u32 timer_id, u32 queue_id, u64 name, u64 data1, u64 data2)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2015-01-13 15:54:36 +01:00
|
|
|
sys_timer.Warning("sys_timer_connect_event_queue(timer_id=%d, queue_id=%d, name=0x%llx, data1=0x%llx, data2=0x%llx)",
|
2013-11-09 02:05:58 +01:00
|
|
|
timer_id, queue_id, name, data1, data2);
|
|
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<timer> timer_data = nullptr;
|
2015-03-04 05:42:04 +01:00
|
|
|
std::shared_ptr<event_queue_t> equeue = nullptr;
|
2015-03-06 23:10:04 +01:00
|
|
|
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
|
|
|
|
if(!Emu.GetIdManager().GetIDData(queue_id, equeue)) return CELL_ESRCH;
|
2013-11-09 02:05:58 +01:00
|
|
|
|
|
|
|
|
//TODO: ?
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_timer_disconnect_event_queue(u32 timer_id)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2014-07-21 16:42:43 +02:00
|
|
|
sys_timer.Todo("sys_timer_disconnect_event_queue(timer_id=%d)", timer_id);
|
2013-11-09 02:05:58 +01:00
|
|
|
|
2014-12-24 00:38:13 +01:00
|
|
|
std::shared_ptr<timer> timer_data = nullptr;
|
2015-03-06 23:10:04 +01:00
|
|
|
if(!Emu.GetIdManager().GetIDData(timer_id, timer_data)) return CELL_ESRCH;
|
2013-11-09 02:05:58 +01:00
|
|
|
|
|
|
|
|
//TODO: ?
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_timer_sleep(u32 sleep_time)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2014-07-14 11:24:10 +02:00
|
|
|
sys_timer.Log("sys_timer_sleep(sleep_time=%d)", sleep_time);
|
2014-07-13 20:55:14 +02:00
|
|
|
for (u32 i = 0; i < sleep_time; i++)
|
|
|
|
|
{
|
2014-07-14 11:24:10 +02:00
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
2014-07-13 20:55:14 +02:00
|
|
|
if (Emu.IsStopped())
|
|
|
|
|
{
|
2014-07-14 21:15:30 +02:00
|
|
|
sys_timer.Warning("sys_timer_sleep(sleep_time=%d) aborted", sleep_time);
|
2014-07-13 20:55:14 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-11-09 02:05:58 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
s32 sys_timer_usleep(u64 sleep_time)
|
2013-11-09 02:05:58 +01:00
|
|
|
{
|
2014-07-14 11:24:10 +02:00
|
|
|
sys_timer.Log("sys_timer_usleep(sleep_time=%lld)", sleep_time);
|
2013-11-09 02:05:58 +01:00
|
|
|
if (sleep_time > 0xFFFFFFFFFFFF) sleep_time = 0xFFFFFFFFFFFF; //2^48-1
|
2014-07-14 11:24:10 +02:00
|
|
|
for (u32 i = 0; i < sleep_time / 1000000; i++)
|
2014-07-13 20:55:14 +02:00
|
|
|
{
|
2014-07-14 11:24:10 +02:00
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
2014-07-13 20:55:14 +02:00
|
|
|
if (Emu.IsStopped())
|
|
|
|
|
{
|
2014-07-14 21:15:30 +02:00
|
|
|
sys_timer.Warning("sys_timer_usleep(sleep_time=%lld) aborted", sleep_time);
|
2014-07-13 20:55:14 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds(sleep_time % 1000000));
|
2013-11-09 02:05:58 +01:00
|
|
|
return CELL_OK;
|
2014-07-11 13:59:13 +02:00
|
|
|
}
|