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]; gdbstub_handle_t __stubs[2];
public: public:
virtual void EMU_DebugIdleUpdate() { virtual void EMU_DebugIdleUpdate() {
gdbstub_wait(__stubs); gdbstub_wait(__stubs, -1L);
} }
virtual void setStubs(gdbstub_handle_t stubs[2]) { virtual void setStubs(gdbstub_handle_t stubs[2]) {
this->__stubs[0] = stubs[0]; 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. /* wait until either of 2 gdb stubs gives control back to the emulator.
pass a stubs[2], one of them may be NULL. 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 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. 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. */ 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() */ /* enable or disable use of the pipe for gdbstub_wait() */
void gdbstub_wait_set_enabled(gdbstub_handle_t stub, int on); 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); 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]; struct gdb_stub_state* g[2];
g[0] = (struct gdb_stub_state *) stubs[0]; g[0] = (struct gdb_stub_state *) stubs[0];
g[1] = (struct gdb_stub_state *) stubs[1]; g[1] = (struct gdb_stub_state *) stubs[1];
fd_set set; fd_set set;
unsigned i; unsigned i;
struct timeval tv = {}, *tvp = &tv;
FD_ZERO(&set); FD_ZERO(&set);
for (i = 0; i < 2; ++i) for (i = 0; i < 2; ++i)
if(g[i]) FD_SET( g[i]->info_pipe[0], &set); 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; if (res <= 0) return 0;
for (i = 0; i < 2; ++i) for (i = 0; i < 2; ++i)
if ( g[i] && FD_ISSET( g[i]->info_pipe[0], &set)) { if ( g[i] && FD_ISSET( g[i]->info_pipe[0], &set)) {