Added priority setting to eqstream to control cpu usage on thread more effectively

This commit is contained in:
KimLS 2019-04-06 15:10:41 -07:00
parent 54a7f73e50
commit 82e247f77b
6 changed files with 59 additions and 14 deletions

View File

@ -50,6 +50,12 @@ struct EQStreamManagerInterfaceOptions
EQ::EventLoop *loop; EQ::EventLoop *loop;
}; };
enum EQStreamPriority : int32_t {
High,
Normal,
Low
};
class EQStreamInterface; class EQStreamInterface;
class EQStreamManagerInterface class EQStreamManagerInterface
{ {
@ -62,6 +68,7 @@ public:
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) = 0; virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) = 0;
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) = 0; virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) = 0;
virtual void SetPriority(EQStreamPriority priority) = 0;
protected: protected:
EQStreamManagerInterfaceOptions m_options; EQStreamManagerInterfaceOptions m_options;
}; };

View File

@ -21,6 +21,7 @@ namespace EQ
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) { m_on_new_connection = func; } virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) { m_on_new_connection = func; }
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) { m_on_connection_state_change = func; } virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) { m_on_connection_state_change = func; }
virtual void SetPriority(EQStreamPriority priority) { }
private: private:
DaybreakConnectionManager m_daybreak; DaybreakConnectionManager m_daybreak;
std::function<void(std::shared_ptr<EQStreamInterface>)> m_on_new_connection; std::function<void(std::shared_ptr<EQStreamInterface>)> m_on_new_connection;

View File

@ -27,6 +27,7 @@ struct EQ::Net::ConcurrentEQStreamManager::Impl
std::unordered_map<uint64_t, std::shared_ptr<ConcurrentEQStream>> streams; std::unordered_map<uint64_t, std::shared_ptr<ConcurrentEQStream>> streams;
std::function<void(std::shared_ptr<EQStreamInterface>)> on_new_connection; std::function<void(std::shared_ptr<EQStreamInterface>)> on_new_connection;
std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> on_connection_state_change; std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> on_connection_state_change;
EQStreamPriority priority;
}; };
EQ::Net::ConcurrentEQStreamManager::ConcurrentEQStreamManager(const EQStreamManagerInterfaceOptions &options) EQ::Net::ConcurrentEQStreamManager::ConcurrentEQStreamManager(const EQStreamManagerInterfaceOptions &options)
@ -36,6 +37,7 @@ EQ::Net::ConcurrentEQStreamManager::ConcurrentEQStreamManager(const EQStreamMana
_impl->background = std::thread(std::bind(&ConcurrentEQStreamManager::_BackgroundThread, this)); _impl->background = std::thread(std::bind(&ConcurrentEQStreamManager::_BackgroundThread, this));
_impl->foreground_loop_timer.reset(new EQ::Timer(options.loop, 16, true, _impl->foreground_loop_timer.reset(new EQ::Timer(options.loop, 16, true,
std::bind(&ConcurrentEQStreamManager::_ForegroundTimer, this, std::placeholders::_1))); std::bind(&ConcurrentEQStreamManager::_ForegroundTimer, this, std::placeholders::_1)));
_impl->priority = EQStreamPriority::High;
} }
EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager() EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
@ -48,7 +50,7 @@ EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
//Tell the background to shutdown and wait for it to actually do so //Tell the background to shutdown and wait for it to actually do so
ceqs_terminate_msg_t msg; ceqs_terminate_msg_t msg;
msg.type = TerminateBackground; msg.type = ceqs_msg_type::TerminateBackground;
_PushToBackgroundQueue((ceqs_msg_t*)&msg); _PushToBackgroundQueue((ceqs_msg_t*)&msg);
_impl->background.join(); _impl->background.join();
@ -57,7 +59,7 @@ EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
ceqs_msg_t eqs_msg; ceqs_msg_t eqs_msg;
while (_impl->foreground_queue.try_dequeue(eqs_msg)) { while (_impl->foreground_queue.try_dequeue(eqs_msg)) {
if (eqs_msg.type == PacketRecv) { if (eqs_msg.type == ceqs_msg_type::PacketRecv) {
ceqs_packet_recv_msg_t *eqs_msg_in = (ceqs_packet_recv_msg_t*)&eqs_msg; ceqs_packet_recv_msg_t *eqs_msg_in = (ceqs_packet_recv_msg_t*)&eqs_msg;
delete eqs_msg_in->packet; delete eqs_msg_in->packet;
@ -85,7 +87,18 @@ void EQ::Net::ConcurrentEQStreamManager::_BackgroundThread() {
while (true == _impl->background_running) { while (true == _impl->background_running) {
loop.Process(); loop.Process();
switch (_impl->priority) {
case EQStreamPriority::Low:
Sleep(10);
break;
case EQStreamPriority::Normal:
Sleep(5);
break;
case EQStreamPriority::High:
Sleep(1); Sleep(1);
break;
}
} }
_impl->background_loop_timer.release(); _impl->background_loop_timer.release();
@ -94,7 +107,7 @@ void EQ::Net::ConcurrentEQStreamManager::_BackgroundThread() {
ceqs_msg_t eqs_msg; ceqs_msg_t eqs_msg;
while (_impl->background_queue.try_dequeue(eqs_msg)) { while (_impl->background_queue.try_dequeue(eqs_msg)) {
if (eqs_msg.type == QueuePacket) { if (eqs_msg.type == ceqs_msg_type::QueuePacket) {
ceqs_queue_packet_msg_t *eqs_msg_in = (ceqs_queue_packet_msg_t*)&eqs_msg; ceqs_queue_packet_msg_t *eqs_msg_in = (ceqs_queue_packet_msg_t*)&eqs_msg;
delete eqs_msg_in->packet; delete eqs_msg_in->packet;
} }
@ -142,7 +155,7 @@ void EQ::Net::ConcurrentEQStreamManager::_BackgroundUpdateStatsTimer(EQ::Timer *
void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_msg_t &msg) void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_msg_t &msg)
{ {
switch (msg.type) { switch (msg.type) {
case QueuePacket: case ceqs_msg_type::QueuePacket:
{ {
ceqs_queue_packet_msg_t *msg_in = (ceqs_queue_packet_msg_t*)&msg; ceqs_queue_packet_msg_t *msg_in = (ceqs_queue_packet_msg_t*)&msg;
@ -154,12 +167,12 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_ms
delete msg_in->packet; delete msg_in->packet;
break; break;
} }
case TerminateBackground: case ceqs_msg_type::TerminateBackground:
{ {
_impl->background_running = false; _impl->background_running = false;
break; break;
} }
case CloseConnection: case ceqs_msg_type::CloseConnection:
{ {
ceqs_close_connection_msg_t *msg_in = (ceqs_close_connection_msg_t*)&msg; ceqs_close_connection_msg_t *msg_in = (ceqs_close_connection_msg_t*)&msg;
auto iter = _impl->connections.find(msg_in->stream_id); auto iter = _impl->connections.find(msg_in->stream_id);
@ -168,7 +181,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_ms
} }
break; break;
} }
case ResetStats: case ceqs_msg_type::ResetStats:
{ {
ceqs_reset_stats_msg_t *msg_in = (ceqs_reset_stats_msg_t*)&msg; ceqs_reset_stats_msg_t *msg_in = (ceqs_reset_stats_msg_t*)&msg;
auto iter = _impl->connections.find(msg_in->stream_id); auto iter = _impl->connections.find(msg_in->stream_id);
@ -177,6 +190,12 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_ms
} }
break; break;
} }
case ceqs_msg_type::SetPriority:
{
ceqs_set_priority_msg_t *msg_in = (ceqs_set_priority_msg_t*)&msg;
_impl->priority = msg_in->priority;
break;
}
default: default:
break; break;
} }
@ -198,7 +217,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ForegroundTimer(EQ::Timer *t)
void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_msg_t &msg) void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_msg_t &msg)
{ {
switch (msg.type) { switch (msg.type) {
case NewConnection: case ceqs_msg_type::NewConnection:
{ {
ceqs_new_connection_msg_t *msg_in = (ceqs_new_connection_msg_t*)&msg; ceqs_new_connection_msg_t *msg_in = (ceqs_new_connection_msg_t*)&msg;
@ -214,7 +233,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_ms
} }
break; break;
} }
case ConnectionStateChange: case ceqs_msg_type::ConnectionStateChange:
{ {
ceqs_connection_state_change_msg_t *msg_in = (ceqs_connection_state_change_msg_t*)&msg; ceqs_connection_state_change_msg_t *msg_in = (ceqs_connection_state_change_msg_t*)&msg;
@ -228,7 +247,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_ms
} }
break; break;
} }
case PacketRecv: case ceqs_msg_type::PacketRecv:
{ {
ceqs_packet_recv_msg_t *msg_in = (ceqs_packet_recv_msg_t*)&msg; ceqs_packet_recv_msg_t *msg_in = (ceqs_packet_recv_msg_t*)&msg;
std::unique_ptr<EQ::Net::Packet> p(msg_in->packet); std::unique_ptr<EQ::Net::Packet> p(msg_in->packet);
@ -239,7 +258,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_ms
} }
break; break;
} }
case UpdateStats: case ceqs_msg_type::UpdateStats:
{ {
ceqs_update_stats_msg_t *msg_in = (ceqs_update_stats_msg_t*)&msg; ceqs_update_stats_msg_t *msg_in = (ceqs_update_stats_msg_t*)&msg;
auto iter = _impl->streams.find(msg_in->stream_id); auto iter = _impl->streams.find(msg_in->stream_id);
@ -275,6 +294,15 @@ void EQ::Net::ConcurrentEQStreamManager::OnConnectionStateChange(std::function<v
_impl->on_connection_state_change = func; _impl->on_connection_state_change = func;
} }
//Called by foreground
void EQ::Net::ConcurrentEQStreamManager::SetPriority(EQStreamPriority priority)
{
ceqs_set_priority_msg_t msg;
msg.type = ceqs_msg_type::SetPriority;
msg.priority = priority;
_PushToBackgroundQueue((ceqs_msg_t*)&msg);
}
//Called by background //Called by background
void EQ::Net::ConcurrentEQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection) void EQ::Net::ConcurrentEQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
{ {
@ -451,7 +479,7 @@ void EQ::Net::ConcurrentEQStream::Close()
} }
ceqs_close_connection_msg_t msg; ceqs_close_connection_msg_t msg;
msg.type = CloseConnection; msg.type = ceqs_msg_type::CloseConnection;
msg.stream_id = _impl->id; msg.stream_id = _impl->id;
_impl->parent->_PushToBackgroundQueue((ceqs_msg_t*)&msg); _impl->parent->_PushToBackgroundQueue((ceqs_msg_t*)&msg);

View File

@ -18,6 +18,7 @@ namespace EQ
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func); virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func);
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func); virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func);
virtual void SetPriority(EQStreamPriority priority);
void _PushToBackgroundQueue(ceqs_msg_t* msg); void _PushToBackgroundQueue(ceqs_msg_t* msg);
void _PushToForegroundQueue(ceqs_msg_t* msg); void _PushToForegroundQueue(ceqs_msg_t* msg);

View File

@ -18,7 +18,8 @@ namespace EQ
QueuePacket, QueuePacket,
TerminateBackground, TerminateBackground,
CloseConnection, CloseConnection,
ResetStats ResetStats,
SetPriority
}; };
typedef struct typedef struct
@ -85,5 +86,10 @@ namespace EQ
ceqs_msg_type type; ceqs_msg_type type;
} ceqs_terminate_msg_t; } ceqs_terminate_msg_t;
typedef struct
{
ceqs_msg_type type;
EQStreamPriority priority;
} ceqs_set_priority_msg_t;
} }
} }

View File

@ -594,10 +594,12 @@ int main(int argc, char** argv) {
if (previous_loaded && !current_loaded) { if (previous_loaded && !current_loaded) {
process_timer.Stop(); process_timer.Stop();
process_timer.Start(1000, true); process_timer.Start(1000, true);
eqsm->SetPriority(EQStreamPriority::Low);
} }
else if (!previous_loaded && current_loaded) { else if (!previous_loaded && current_loaded) {
process_timer.Stop(); process_timer.Stop();
process_timer.Start(32, true); process_timer.Start(32, true);
eqsm->SetPriority(EQStreamPriority::High);
} }
if (current_loaded) { if (current_loaded) {