2013-11-03 21:23:16 +02:00
|
|
|
#pragma once
|
2015-07-01 01:25:52 +03:00
|
|
|
|
2016-06-07 23:24:20 +03:00
|
|
|
#include "../Utilities/Thread.h"
|
2016-08-07 22:01:27 +03:00
|
|
|
#include "../Utilities/bit_set.h"
|
2014-08-25 18:56:13 +04:00
|
|
|
|
2016-08-13 17:58:19 +03:00
|
|
|
// Thread state flags
|
2016-08-09 17:14:41 +03:00
|
|
|
enum class cpu_flag : u32
|
2015-03-17 00:38:21 +03:00
|
|
|
{
|
2016-04-14 01:59:00 +03:00
|
|
|
stop, // Thread not running (HLE, initial state)
|
|
|
|
|
exit, // Irreversible exit
|
2017-02-06 21:36:46 +03:00
|
|
|
suspend, // Thread suspended
|
2016-04-14 01:59:00 +03:00
|
|
|
ret, // Callback return requested
|
|
|
|
|
signal, // Thread received a signal (HLE)
|
2017-03-11 02:14:48 +03:00
|
|
|
memory, // Thread must unlock memory mutex
|
2016-04-14 01:59:00 +03:00
|
|
|
|
|
|
|
|
dbg_global_pause, // Emulation paused
|
|
|
|
|
dbg_global_stop, // Emulation stopped
|
|
|
|
|
dbg_pause, // Thread paused
|
|
|
|
|
dbg_step, // Thread forced to pause after one step (one instruction, etc)
|
2016-08-07 22:01:27 +03:00
|
|
|
|
|
|
|
|
__bitset_enum_max
|
2015-03-17 00:38:21 +03:00
|
|
|
};
|
|
|
|
|
|
2016-08-13 17:58:19 +03:00
|
|
|
// Flag set for pause state
|
2016-08-09 17:14:41 +03:00
|
|
|
constexpr bs_t<cpu_flag> cpu_state_pause = cpu_flag::suspend + cpu_flag::dbg_global_pause + cpu_flag::dbg_pause;
|
2015-07-01 01:25:52 +03:00
|
|
|
|
2016-04-14 01:59:00 +03:00
|
|
|
class cpu_thread : public named_thread
|
2013-11-03 21:23:16 +02:00
|
|
|
{
|
2016-08-13 17:58:19 +03:00
|
|
|
void on_task() override final;
|
2013-11-05 20:12:18 +02:00
|
|
|
|
2015-07-01 01:25:52 +03:00
|
|
|
public:
|
2016-04-25 13:49:12 +03:00
|
|
|
virtual void on_stop() override;
|
|
|
|
|
virtual ~cpu_thread() override;
|
2013-11-03 21:23:16 +02:00
|
|
|
|
2017-01-25 20:50:30 +03:00
|
|
|
const u32 id;
|
2016-06-25 16:54:08 +03:00
|
|
|
|
2017-01-25 20:50:30 +03:00
|
|
|
cpu_thread(u32 id);
|
2016-04-27 01:27:24 +03:00
|
|
|
|
2016-04-14 01:59:00 +03:00
|
|
|
// Public thread state
|
2017-03-11 02:14:48 +03:00
|
|
|
atomic_t<bs_t<cpu_flag>> state{+cpu_flag::stop};
|
2016-04-14 01:59:00 +03:00
|
|
|
|
2016-05-13 17:01:48 +03:00
|
|
|
// Process thread state, return true if the checker must return
|
2016-07-28 00:43:22 +03:00
|
|
|
bool check_state();
|
|
|
|
|
|
2017-02-22 13:10:55 +03:00
|
|
|
// Process thread state
|
|
|
|
|
void test_state();
|
|
|
|
|
|
2016-07-28 00:43:22 +03:00
|
|
|
// Run thread
|
|
|
|
|
void run();
|
|
|
|
|
|
2017-01-25 20:50:30 +03:00
|
|
|
// Check thread type
|
|
|
|
|
u32 id_type()
|
|
|
|
|
{
|
|
|
|
|
return id >> 24;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-10 01:51:29 +03:00
|
|
|
// Thread stats for external observation
|
|
|
|
|
static atomic_t<u64> g_threads_created, g_threads_deleted;
|
|
|
|
|
|
2016-08-13 17:58:19 +03:00
|
|
|
// Print CPU state
|
|
|
|
|
virtual std::string dump() const;
|
|
|
|
|
|
|
|
|
|
// Thread entry point function
|
2016-04-14 01:59:00 +03:00
|
|
|
virtual void cpu_task() = 0;
|
2017-02-06 21:36:46 +03:00
|
|
|
|
|
|
|
|
// Callback for cpu_flag::suspend
|
|
|
|
|
virtual void cpu_sleep() {}
|
2013-11-03 21:23:16 +02:00
|
|
|
};
|
|
|
|
|
|
2016-04-14 01:59:00 +03:00
|
|
|
inline cpu_thread* get_current_cpu_thread() noexcept
|
2015-09-26 23:46:04 +03:00
|
|
|
{
|
2016-04-14 01:59:00 +03:00
|
|
|
extern thread_local cpu_thread* g_tls_current_cpu_thread;
|
2015-09-26 23:46:04 +03:00
|
|
|
|
|
|
|
|
return g_tls_current_cpu_thread;
|
|
|
|
|
}
|