Skip to content

Commit 11179ad

Browse files
committed
Fix MMU cache statistics signal handling
This restores MMU cache statistics functionality broken by coroutine refactoring. The refactor introduced separate execution paths (SMP mode, single-hart mode, debug mode) but signal handling was only implemented in the SMP path. Signal handling follows async-signal-safe pattern: handler only sets a volatile sig_atomic_t flag, with stats printing deferred to main loop context. All execution paths now properly clean up resources (pfds, file descriptors) before exit. Close #113
1 parent 51e1115 commit 11179ad

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

main.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <getopt.h>
55
#include <inttypes.h>
66
#include <poll.h>
7+
#include <signal.h>
78
#include <stdio.h>
89
#include <stdlib.h>
910
#include <string.h>
@@ -1007,7 +1008,6 @@ static int semu_step(emu_state_t *emu)
10071008
}
10081009

10091010
#ifdef MMU_CACHE_STATS
1010-
static vm_t *global_vm_for_signal = NULL;
10111011
static volatile sig_atomic_t signal_received = 0;
10121012

10131013
/* Forward declaration */
@@ -1152,11 +1152,11 @@ static int semu_run(emu_state_t *emu)
11521152

11531153
while (!emu->stopped) {
11541154
#ifdef MMU_CACHE_STATS
1155-
/* Check if signal received (SIGINT/SIGTERM) */
1156-
if (signal_received) {
1157-
print_mmu_cache_stats(&emu->vm);
1158-
return 0;
1159-
}
1155+
/* Check if signal received (SIGINT/SIGTERM).
1156+
* Break to cleanup resources, stats printed at end of main().
1157+
*/
1158+
if (signal_received)
1159+
break;
11601160
#endif
11611161
/* Only need fds for timer and UART (no coroutine I/O) */
11621162
size_t needed = 2;
@@ -1345,6 +1345,13 @@ static int semu_run(emu_state_t *emu)
13451345

13461346
/* Single-hart mode: use original scheduling */
13471347
while (!emu->stopped) {
1348+
#ifdef MMU_CACHE_STATS
1349+
/* Check if signal received (SIGINT/SIGTERM).
1350+
* Break to exit loop, stats printed at end of main().
1351+
*/
1352+
if (signal_received)
1353+
break;
1354+
#endif
13481355
#if SEMU_HAS(VIRTIONET)
13491356
int i = 0;
13501357
if (emu->vnet.peer.type == NETDEV_IMPL_user && boot_complete) {
@@ -1422,6 +1429,13 @@ static gdb_action_t semu_cont(void *args)
14221429
{
14231430
emu_state_t *emu = (emu_state_t *) args;
14241431
while (!semu_is_interrupt(emu)) {
1432+
#ifdef MMU_CACHE_STATS
1433+
/* Check if signal received (SIGINT/SIGTERM).
1434+
* Break to return control to gdbstub, stats printed at end of main().
1435+
*/
1436+
if (signal_received)
1437+
break;
1438+
#endif
14251439
semu_step(emu);
14261440
}
14271441

@@ -1507,7 +1521,6 @@ int main(int argc, char **argv)
15071521
return ret;
15081522

15091523
#ifdef MMU_CACHE_STATS
1510-
global_vm_for_signal = &emu.vm;
15111524
signal(SIGINT, signal_handler_stats);
15121525
signal(SIGTERM, signal_handler_stats);
15131526
#endif

0 commit comments

Comments
 (0)