[client] changed ivshmem wait timeout to avoid stalls on startup

This commit is contained in:
Geoffrey McRae 2017-12-05 21:50:24 +11:00
parent ff81f5df64
commit 2d5b633397
3 changed files with 18 additions and 29 deletions

View File

@ -478,7 +478,7 @@ bool ivshmem_process()
// ============================================================================ // ============================================================================
enum IVSHMEMWaitResult ivshmem_wait_irq(uint16_t vector) enum IVSHMEMWaitResult ivshmem_wait_irq(uint16_t vector, unsigned int timeout)
{ {
if (vector > ivshmem.server.irqCount - 1) if (vector > ivshmem.server.irqCount - 1)
return false; return false;
@ -488,13 +488,13 @@ enum IVSHMEMWaitResult ivshmem_wait_irq(uint16_t vector)
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
struct timeval timeout; struct timeval tv;
timeout.tv_sec = 1; tv.tv_sec = timeout / 1000;
timeout.tv_usec = 0; tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
while(true) while(true)
{ {
int ret = select(fd+1, &fds, NULL, NULL, &timeout); int ret = select(fd+1, &fds, NULL, NULL, &tv);
if (ret < 0) if (ret < 0)
{ {
if (errno == EINTR) if (errno == EINTR)

View File

@ -35,5 +35,5 @@ enum IVSHMEMWaitResult
IVSHMEM_WAIT_RESULT_ERROR IVSHMEM_WAIT_RESULT_ERROR
}; };
enum IVSHMEMWaitResult ivshmem_wait_irq(uint16_t vector); enum IVSHMEMWaitResult ivshmem_wait_irq(uint16_t vector, unsigned int timeout);
bool ivshmem_kick_irq(uint16_t clientID, uint16_t vector); bool ivshmem_kick_irq(uint16_t clientID, uint16_t vector);

View File

@ -154,35 +154,23 @@ inline bool areFormatsSame(const struct KVMFRHeader s1, const struct KVMFRHeader
(s1.height == s2.height ); (s1.height == s2.height );
} }
inline bool waitGuest() inline int waitGuest()
{ {
bool ready = false; while(state.running)
bool error = false;
while(state.running && !ready && !error)
{ {
switch(ivshmem_wait_irq(0)) switch(ivshmem_wait_irq(0, (1000/30)))
{ {
case IVSHMEM_WAIT_RESULT_OK : case IVSHMEM_WAIT_RESULT_OK :
ready = true;
break;
case IVSHMEM_WAIT_RESULT_TIMEOUT: case IVSHMEM_WAIT_RESULT_TIMEOUT:
ivshmem_kick_irq(state.shm->guestID, 0); return true;
break;
case IVSHMEM_WAIT_RESULT_ERROR: case IVSHMEM_WAIT_RESULT_ERROR:
error = true;
break;
}
}
if (error)
{
DEBUG_ERROR("error during wait for host"); DEBUG_ERROR("error during wait for host");
return false; return false;
} }
}
return true; return false;
} }
int renderThread(void * unused) int renderThread(void * unused)
@ -192,16 +180,18 @@ int renderThread(void * unused)
const LG_Renderer * lgr = NULL; const LG_Renderer * lgr = NULL;
void * lgrData; void * lgrData;
unsigned int lastTicks = SDL_GetTicks(); unsigned int lastTicks = SDL_GetTicks();
unsigned int frameCount = 0, lastFrameCount = 0; unsigned int frameCount = 0;
unsigned int lastFrameCount = 0;
SDL_Texture * textTexture = NULL; SDL_Texture * textTexture = NULL;
SDL_Rect textRect; SDL_Rect textRect;
while(state.running) while(state.running)
{ {
// wait for the guest to signal ready and copy the header
if (!waitGuest()) if (!waitGuest())
break; break;
++frameCount;
// we must take a copy of the header, both to let the guest advance and to // we must take a copy of the header, both to let the guest advance and to
// prevent the contained arguments being abused to overflow buffers // prevent the contained arguments being abused to overflow buffers
memcpy(&header, state.shm, sizeof(struct KVMFRHeader)); memcpy(&header, state.shm, sizeof(struct KVMFRHeader));
@ -326,7 +316,6 @@ int renderThread(void * unused)
break; break;
} }
++frameCount;
if (!params.showFPS) if (!params.showFPS)
{ {
SDL_RenderPresent(state.renderer); SDL_RenderPresent(state.renderer);