- make client use less CPU for network games

This commit is contained in:
Mark Vejvoda 2013-03-13 21:32:48 +00:00
parent 3661d62c03
commit 16d25210e4
6 changed files with 92 additions and 25 deletions

View File

@ -3882,6 +3882,7 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName,
} }
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] szMsg [%s] lastProgress.first = %d, fileProgress = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,szMsg,lastProgress.first,fileProgress); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] szMsg [%s] lastProgress.first = %d, fileProgress = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,szMsg,lastProgress.first,fileProgress);
clientInterface->sendTextMessage(szMsg,-1, lang.isLanguageLocal(languageList[i]),languageList[i]); clientInterface->sendTextMessage(szMsg,-1, lang.isLanguageLocal(languageList[i]),languageList[i]);
sleep(1);
} }
} }
} }

View File

@ -37,6 +37,8 @@ using namespace Shared::Util;
namespace Glest{ namespace Game{ namespace Glest{ namespace Game{
const bool debugClientInterfacePerf = false;
// ===================================================== // =====================================================
// class ClientInterfaceThread // class ClientInterfaceThread
// ===================================================== // =====================================================
@ -85,6 +87,11 @@ void ClientInterfaceThread::execute() {
bool minorDebugPerformance = false; bool minorDebugPerformance = false;
Chrono chrono; Chrono chrono;
// Set socket to blocking
if(clientInterface != NULL && clientInterface->getSocket(true) != NULL) {
clientInterface->getSocket(true)->setBlock(true);
}
//unsigned int idx = 0; //unsigned int idx = 0;
for(;this->clientInterface != NULL;) { for(;this->clientInterface != NULL;) {
if(getQuitStatus() == true) { if(getQuitStatus() == true) {
@ -108,20 +115,29 @@ void ClientInterfaceThread::execute() {
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
//printf("START === Client thread ended\n"); if(debugClientInterfacePerf == true) printf("START === Client thread\n");
Chrono chrono(true); uint64 loopCount = 0;
Chrono chrono;
if(debugClientInterfacePerf == true) {
chrono.start();
}
while(this->getQuitStatus() == false && clientInterface != NULL) { while(this->getQuitStatus() == false && clientInterface != NULL) {
clientInterface->updateNetworkFrame(); clientInterface->updateNetworkFrame();
if(chrono.getMillis() >= 200) { if(debugClientInterfacePerf == true) {
sleep(5); loopCount++;
chrono.start(); if(chrono.getMillis() >= 1000) {
} printf("Client thread loopCount = %llu\n",(long long unsigned int)loopCount);
loopCount = 0;
//sleep(0);
chrono.start();
}
}
} }
//printf("END === Client thread ended\n"); if(debugClientInterfacePerf == true)printf("END === Client thread\n");
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
@ -866,9 +882,16 @@ void ClientInterface::updateFrame(int *checkFrame) {
if(isConnected() == true && this->quitThread == false) { if(isConnected() == true && this->quitThread == false) {
//printf("#2 ClientInterface::updateFrame\n"); //printf("#2 ClientInterface::updateFrame\n");
uint64 loopCount = 0;
Chrono chronoPerf;
if(debugClientInterfacePerf == true) {
chronoPerf.start();
}
Chrono chrono; Chrono chrono;
chrono.start(); chrono.start();
int waitMilliseconds = (checkFrame == NULL ? 1 : 0);
int simulateLag = Config::getInstance().getInt("SimulateClientLag","0"); int simulateLag = Config::getInstance().getInt("SimulateClientLag","0");
bool done= false; bool done= false;
while(done == false && this->quitThread == false) { while(done == false && this->quitThread == false) {
@ -876,7 +899,7 @@ void ClientInterface::updateFrame(int *checkFrame) {
//printf("BEFORE Client get networkMessageType\n"); //printf("BEFORE Client get networkMessageType\n");
//wait for the next message //wait for the next message
NetworkMessageType networkMessageType = waitForMessage(); NetworkMessageType networkMessageType = waitForMessage(waitMilliseconds);
//printf("AFTER Client got networkMessageType = %d\n",networkMessageType); //printf("AFTER Client got networkMessageType = %d\n",networkMessageType);
@ -1121,8 +1144,19 @@ void ClientInterface::updateFrame(int *checkFrame) {
done = true; done = true;
} }
// Sleep ever second we wait to let other threads work // Sleep ever second we wait to let other threads work
else if(chrono.getMillis() % 25 == 0) { // else if(chrono.getMillis() % 25 == 0) {
sleep(1); // sleep(1);
// }
if(debugClientInterfacePerf == true) {
loopCount++;
if(chronoPerf.getMillis() >= 1000) {
printf("Client updateFrame loopCount = %llu\n",(long long unsigned int)loopCount);
loopCount = 0;
//sleep(0);
chronoPerf.start();
}
} }
} }
@ -1132,7 +1166,7 @@ void ClientInterface::updateFrame(int *checkFrame) {
} }
else if(checkFrame == NULL) { else if(checkFrame == NULL) {
//sleep(15); //sleep(15);
sleep(0); //sleep(0);
} }
} }
//printf("#3 ClientInterface::updateFrame\n"); //printf("#3 ClientInterface::updateFrame\n");
@ -1165,14 +1199,24 @@ bool ClientInterface::getNetworkCommand(int frameCount, int currentCachedPending
bool result = false; bool result = false;
bool waitForData = false; bool waitForData = false;
uint64 copyCachedLastPendingFrameCount = 0;
uint64 waitCount = 0;
if(quit == false && this->quitThread == false) { if(quit == false && this->quitThread == false) {
//MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); //MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE);
//safeMutex.ReleaseLock(true); //safeMutex.ReleaseLock(true);
MutexSafeWrapper safeMutex(NULL,CODE_AT_LINE);
for(;quit == false && this->quitThread == false;) { for(;quit == false && this->quitThread == false;) {
MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); //MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE);
//safeMutex.Lock(); //safeMutex.Lock();
uint64 copyCachedLastPendingFrameCount = cachedLastPendingFrameCount; if(safeMutex.isValidMutex() == false) {
safeMutex.setMutex(networkCommandListThreadAccessor,CODE_AT_LINE);
}
else {
safeMutex.Lock();
}
copyCachedLastPendingFrameCount = cachedLastPendingFrameCount;
if(cachedPendingCommands.find(frameCount) != cachedPendingCommands.end()) { if(cachedPendingCommands.find(frameCount) != cachedPendingCommands.end()) {
Commands &frameCmdList = cachedPendingCommands[frameCount]; Commands &frameCmdList = cachedPendingCommands[frameCount];
if(frameCmdList.size() > 0) { if(frameCmdList.size() > 0) {
@ -1203,13 +1247,18 @@ bool ClientInterface::getNetworkCommand(int frameCount, int currentCachedPending
if(waitForData == false) { if(waitForData == false) {
waitForData = true; waitForData = true;
sleep(1); sleep(0);
} }
waitCount++;
//printf("Client waiting for packet for frame: %d, currentCachedPendingCommandsIndex = %d, cachedPendingCommandsIndex = %lld\n",frameCount,currentCachedPendingCommandsIndex,(long long int)cachedPendingCommandsIndex); //printf("Client waiting for packet for frame: %d, currentCachedPendingCommandsIndex = %d, cachedPendingCommandsIndex = %lld\n",frameCount,currentCachedPendingCommandsIndex,(long long int)cachedPendingCommandsIndex);
} }
} }
} }
if(waitForData == true) {
printf("Client waiting for packet FINISHED for frame: %d, copyCachedLastPendingFrameCount = %lld waitCount = %llu\n",frameCount,(long long int)copyCachedLastPendingFrameCount,(long long unsigned int)waitCount);
}
return result; return result;
} }
@ -1659,7 +1708,7 @@ string ClientInterface::getNetworkStatus() {
return szBuf; return szBuf;
} }
NetworkMessageType ClientInterface::waitForMessage() NetworkMessageType ClientInterface::waitForMessage(int waitMilliseconds)
{ {
// Debug! // Debug!
/* /*
@ -1670,13 +1719,19 @@ NetworkMessageType ClientInterface::waitForMessage()
return; return;
*/ */
uint64 loopCount = 0;
Chrono chronoPerf;
if(debugClientInterfacePerf == true) {
chronoPerf.start();
}
Chrono chrono; Chrono chrono;
chrono.start(); chrono.start();
NetworkMessageType msg = nmtInvalid; NetworkMessageType msg = nmtInvalid;
//uint64 waitLoopCount = 0; //uint64 waitLoopCount = 0;
while(msg == nmtInvalid && this->quitThread == false) { while(msg == nmtInvalid && this->quitThread == false) {
msg = getNextMessageType(); msg = getNextMessageType(waitMilliseconds);
if(msg == nmtInvalid) { if(msg == nmtInvalid) {
if(chrono.getMillis() % 250 == 0 && isConnected() == false) { if(chrono.getMillis() % 250 == 0 && isConnected() == false) {
if(quit == false) { if(quit == false) {
@ -1715,12 +1770,23 @@ NetworkMessageType ClientInterface::waitForMessage()
} }
// Sleep ever second we wait to let other threads work // Sleep ever second we wait to let other threads work
else if(chrono.getMillis() % 25 == 0) { else if(chrono.getMillis() % 25 == 0) {
sleep(1); sleep(5);
} }
//sleep(waitSleepTime); //sleep(waitSleepTime);
} }
//waitLoopCount++; //waitLoopCount++;
if(debugClientInterfacePerf == true) {
loopCount++;
if(chronoPerf.getMillis() >= 100) {
printf("Client waitForMessage loopCount = %llu\n",(long long unsigned int)loopCount);
loopCount = 0;
//sleep(0);
chronoPerf.start();
}
}
} }
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] waiting took %lld msecs, waitLoopCount = %ull, msg = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),waitLoopCount,msg); //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] waiting took %lld msecs, waitLoopCount = %ull, msg = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),waitLoopCount,msg);

View File

@ -186,7 +186,7 @@ public:
protected: protected:
Mutex * getServerSynchAccessor() { return NULL; } Mutex * getServerSynchAccessor() { return NULL; }
NetworkMessageType waitForMessage(); NetworkMessageType waitForMessage(int waitMilliseconds=0);
bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType); bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType);
void updateFrame(int *checkFrame); void updateFrame(int *checkFrame);

View File

@ -75,13 +75,14 @@ void NetworkInterface::sendMessage(NetworkMessage* networkMessage){
networkMessage->send(socket); networkMessage->send(socket);
} }
NetworkMessageType NetworkInterface::getNextMessageType() NetworkMessageType NetworkInterface::getNextMessageType(int waitMilliseconds)
{ {
Socket* socket= getSocket(false); Socket* socket= getSocket(false);
int8 messageType= nmtInvalid; int8 messageType= nmtInvalid;
if(socket != NULL && if(socket != NULL &&
socket->hasDataToRead() == true) { ((waitMilliseconds <= 0 && socket->hasDataToRead() == true) ||
(waitMilliseconds > 0 && socket->hasDataToReadWithWait(waitMilliseconds) == true))) {
//peek message type //peek message type
int dataSize = socket->getDataToRead(); int dataSize = socket->getDataToRead();
if(dataSize >= sizeof(messageType)) { if(dataSize >= sizeof(messageType)) {

View File

@ -207,7 +207,7 @@ public:
string getHostName() const {return Socket::getHostName();} string getHostName() const {return Socket::getHostName();}
virtual void sendMessage(NetworkMessage* networkMessage); virtual void sendMessage(NetworkMessage* networkMessage);
NetworkMessageType getNextMessageType(); NetworkMessageType getNextMessageType(int waitMilliseconds=0);
bool receiveMessage(NetworkMessage* networkMessage); bool receiveMessage(NetworkMessage* networkMessage);
virtual bool isConnected(); virtual bool isConnected();

View File

@ -1077,13 +1077,12 @@ bool Socket::hasDataToRead(PLATFORM_SOCKET socket)
return bResult; return bResult;
} }
bool Socket::hasDataToReadWithWait(int waitMilliseconds) bool Socket::hasDataToReadWithWait(int waitMilliseconds) {
{ MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE);
return Socket::hasDataToReadWithWait(sock,waitMilliseconds) ; return Socket::hasDataToReadWithWait(sock,waitMilliseconds) ;
} }
bool Socket::hasDataToReadWithWait(PLATFORM_SOCKET socket,int waitMilliseconds) bool Socket::hasDataToReadWithWait(PLATFORM_SOCKET socket,int waitMilliseconds) {
{
bool bResult = false; bool bResult = false;
Chrono chono; Chrono chono;