diff options
Diffstat (limited to 'emulator.cpp')
-rw-r--r-- | emulator.cpp | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/emulator.cpp b/emulator.cpp index 034fc57..0fb50dd 100644 --- a/emulator.cpp +++ b/emulator.cpp @@ -37,6 +37,7 @@ #include <unistd.h> #include <signal.h> #include <netdb.h> +#include <poll.h> #if !defined(DEBUG_TRACE_INSTRUCTIONS) # define DEBUG_TRACE_INSTRUCTIONS 0 @@ -85,9 +86,9 @@ struct Backtrace { }; static constexpr struct timespec kOneMillisecond{0, 1000000}; +static constexpr struct timespec kIdleSleepTime{0, 10000000}; static char msg_buf[MESSAGE_BUFFER_SIZE]; static M68KDebuggingControl g_m68k_debug{}; -static bool g_no_ack_mode{}; static Backtrace<uint32_t, 10> g_pc_backtrace{}; static int set_socket_reuseaddr(const int socket_fd) @@ -231,7 +232,7 @@ static std::string CreateResponse( } break; case PacketType::kQStartNoAckMode: - g_no_ack_mode = true; + m68k_debug.SetNoAckMode(true); return "OK"; case PacketType::kSetThreadForCont: return "OK"; @@ -242,7 +243,7 @@ static std::string CreateResponse( case PacketType::kEnableExtendedMode: break; case PacketType::kInterrupt: - g_m68k_debug.RaiseBreakpoint(); + m68k_debug.RaiseBreakpoint(); return "S05"; // TODO real reason case PacketType::kContinue: m68k_debug.SetRunning(true); @@ -453,7 +454,7 @@ void ParseAndReact( " Packet type: \"%s\"\n", GDBRemote::Packet::PacketTypeToString(packet.type)); } - if (res->ack.length() > 0 && !g_no_ack_mode) { + if (res->ack.length() > 0 && !m68k_debug.IsNoAckModeEnabled()) { if (DEBUG_TRACE_GDB_REMOTE) printf("-> \"%s\"\n", res->ack.c_str()); if (send(conn_fd, &res->ack[0], res->ack.length(), 0) == -1) @@ -529,7 +530,10 @@ static int emulator(M68KDebuggingControl& m68k_debug, Graphics& graphics, CharDe m68k_debug.ResetPendingBreakpoint(); } } else { - clock_nanosleep(CLOCK_MONOTONIC, 0, &kOneMillisecond, nullptr); + struct pollfd fds[1] = { + {/*.fd = */socket_fd, /*.events = */POLLIN, /*.revents = */0}}; + const int timeout_msecs = 30; + poll(fds, 1, timeout_msecs); } continue; } @@ -547,13 +551,14 @@ static int emulator(M68KDebuggingControl& m68k_debug, Graphics& graphics, CharDe GDBRemote::ExchangeContext exchange_ctx{}; while (!quit) { const ssize_t read_size = recv(conn_fd, msg_buf, MESSAGE_BUFFER_SIZE, 0); + const int err = errno; if (read_size > 0) { ParseAndReact(conn_fd, exchange_ctx, m68k_debug, msg_buf, read_size); continue; } else if (read_size == 0) { puts("Client disconnected"); break; - } else if (read_size == -1 && errno != EWOULDBLOCK) { + } else if (read_size == -1 && err != EWOULDBLOCK) { perror("Recv failed"); break; } @@ -570,13 +575,16 @@ static int emulator(M68KDebuggingControl& m68k_debug, Graphics& graphics, CharDe if (send(conn_fd, &response[0], response.length(), 0) == -1) perror("Send failed (response)"); } - } else { - clock_nanosleep(CLOCK_MONOTONIC, 0, &kOneMillisecond, nullptr); + } else if (err == EWOULDBLOCK) { + struct pollfd fds[1] = { + {/*.fd = */conn_fd, /*.events = */POLLIN, /*.revents = */0}}; + const int timeout_msecs = 30; + poll(fds, 1, timeout_msecs); } } close(conn_fd); gdb_chardev.fd = -1; - g_no_ack_mode = false; // TODO move to GDB::ExchangeContext + m68k_debug.SetNoAckMode(false); } close(socket_fd); return 0; |