gdbstub_wait(): add timeout parameter

this is probably helpful for frontends other than cli that have to repaint
and react on events in the user interface, so they can set a timeout like
100 ms, or simply poll whether the stub is active using timeout 0.
This commit is contained in:
rofl0r 2021-10-24 15:29:59 +00:00
parent ed5ff51c0c
commit 339ea16b15
3 changed files with 15 additions and 6 deletions

View File

@ -69,7 +69,7 @@ private:
gdbstub_handle_t __stubs[2];
public:
virtual void EMU_DebugIdleUpdate() {
gdbstub_wait(__stubs);
gdbstub_wait(__stubs, -1L);
}
virtual void setStubs(gdbstub_handle_t stubs[2]) {
this->__stubs[0] = stubs[0];

View File

@ -47,12 +47,15 @@ activateStub_gdb( gdbstub_handle_t stub);
/* wait until either of 2 gdb stubs gives control back to the emulator.
pass a stubs[2], one of them may be NULL.
return value: response from stub | (stub number<<31),
i.e. if stub 1 responded, the high bit is set (and so the result negative).
the primary usecase for this is to do a blocking wait until the stub returns
control to the emulator, in order to not waste cpu cycles.
the timeout parameter specifies the maximum time in milliseconds to wait.
if timeout == -1L, block indefinitely, if timeout == 0 return immediately,
effecting a poll.
return value: response from stub | (stub number<<31),
i.e. if stub 1 responded, the high bit is set (and so the result negative).
returns 0 on failure or if no response was available. */
int gdbstub_wait( gdbstub_handle_t *stubs);
int gdbstub_wait( gdbstub_handle_t *stubs, long timeout);
/* enable or disable use of the pipe for gdbstub_wait() */
void gdbstub_wait_set_enabled(gdbstub_handle_t stub, int on);

View File

@ -304,16 +304,22 @@ indicateCPUStop_gdb( struct gdb_stub_state *stub) {
SEND( stub->ctl_pipe[1], &command, 1);
}
int gdbstub_wait(gdbstub_handle_t *stubs) {
int gdbstub_wait(gdbstub_handle_t *stubs, long timeout) {
struct gdb_stub_state* g[2];
g[0] = (struct gdb_stub_state *) stubs[0];
g[1] = (struct gdb_stub_state *) stubs[1];
fd_set set;
unsigned i;
struct timeval tv = {}, *tvp = &tv;
FD_ZERO(&set);
for (i = 0; i < 2; ++i)
if(g[i]) FD_SET( g[i]->info_pipe[0], &set);
int res = select( FD_SETSIZE, &set, NULL, NULL, NULL);
if (timeout == -1L) tvp = NULL;
else {
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
}
int res = select( FD_SETSIZE, &set, NULL, NULL, tvp);
if (res <= 0) return 0;
for (i = 0; i < 2; ++i)
if ( g[i] && FD_ISSET( g[i]->info_pipe[0], &set)) {