From eb42e7eb07892e91939e3875a124d5f485697ae9 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 18 Nov 2024 08:04:04 -0800 Subject: [PATCH] Move all curses calls into display threads Curses is not thread safe, but currently both the cons and the disp thread can issue curses calls concurrently. Move all curses handling into the display thread. The cons thread just does the select and pipe handling now. Fixes #91 --- common/disp.c | 138 +++++++++++++++++++++--------------------- common/include/disp.h | 4 +- 2 files changed, 73 insertions(+), 69 deletions(-) diff --git a/common/disp.c b/common/disp.c index ea865c3..78bf9e9 100644 --- a/common/disp.c +++ b/common/disp.c @@ -58,6 +58,7 @@ static cons_ctl_t s_cons_ctl; static int disp_start(void); static void* disp_handler(void *); static void* cons_handler(void *); +static disp_flag_t handle_getch(cmd_t *cmdp); static int mutex_cond_init(pthread_mutex_t *mutex, pthread_cond_t *cond) { @@ -465,6 +466,12 @@ disp_handler(void *arg __attribute__((unused))) uint64_t start_ms; int64_t diff_ms; + if (!reg_curses_init(B_TRUE)) { + goto L_EXIT; + } + + win_fix_init(); + /* * Wait cons thread to complete initialization. */ @@ -509,6 +516,7 @@ disp_handler(void *arg __attribute__((unused))) s_disp_ctl.flag = DISP_FLAG_NONE; (void) pthread_mutex_unlock(&s_disp_ctl.mutex); + diff_ms = current_ms(&g_tvbase) - start_ms; if (g_run_secs <= diff_ms / MS_SEC) { g_run_secs = TIME_NSEC_MAX; @@ -532,6 +540,7 @@ disp_handler(void *arg __attribute__((unused))) continue; } + handle_cmd: switch (flag) { case DISP_FLAG_QUIT: debug_print(NULL, 2, @@ -601,6 +610,12 @@ disp_handler(void *arg __attribute__((unused))) } break; + case DISP_FLAG_GETCH: + flag = handle_getch(&cmd); + if (flag == DISP_FLAG_ERR) + goto L_EXIT; + goto handle_cmd; + default: break; } @@ -610,7 +625,7 @@ L_EXIT: if (pagelist_inited) { page_list_fini(); } - + reg_curses_fini(); /* * Let the perf thread exit first. */ @@ -620,6 +635,53 @@ L_EXIT: return (NULL); } +static disp_flag_t +handle_getch(cmd_t *cmd_id_p) +{ + int c, cmd_id; + unsigned char ch; + + if ((c = getch()) == ERR) { + /* + * It's possile if the associated + * terminal is lost. + */ + debug_print(NULL, 2, "cons: " + "getch() failed.\n"); + return DISP_FLAG_ERR; + } + + ch = tolower((unsigned char)c); + dump_write("\n<-- User hit the key '%c' " + "(ascii = %d) -->\n", ch, (int)ch); + + /* These will send the command to itself. */ + + cmd_id = cmd_id_get(ch); + if (cmd_id != CMD_INVALID_ID) { + CMD_ID_SET(cmd_id_p, cmd_id); + return DISP_FLAG_CMD; + } else { + /* + * Hit the keys 'UP'/'DOWN'/'ENTER' + */ + switch (ch) { + case 2: /* KEY DOWN */ + return DISP_FLAG_SCROLLDOWN; + + case 3: /* KEY UP */ + return DISP_FLAG_SCROLLUP; + + case 13: /* enter. */ + return DISP_FLAG_SCROLLENTER; + + default: + break; + } + } + return DISP_FLAG_NONE; +} + /* * The handler of 'cons thread' */ @@ -627,17 +689,10 @@ L_EXIT: static void * cons_handler(void *arg __attribute__((unused))) { - int c, cmd_id; unsigned char ch; - if (!reg_curses_init(B_TRUE)) { - goto L_EXIT; - } - - win_fix_init(); - /* - * Excute "home" command. It shows the NumaTop default page. + * Execute "home" command. It shows the NumaTop default page. */ disp_go_home(); @@ -676,75 +731,22 @@ cons_handler(void *arg __attribute__((unused))) CMD_ID_SET(&s_disp_ctl.cmd, CMD_RESIZE_ID); - dispthr_flagset_nolock(DISP_FLAG_CMD); + dispthr_flagset_nolock(DISP_FLAG_CMD); - (void) pthread_mutex_unlock( - &s_disp_ctl.mutex); + (void) pthread_mutex_unlock( + &s_disp_ctl.mutex); } } } else { /* - * Character is from STDIN. + * Character is from STDIN. Tell disp handler to process. */ - if ((c = getch()) == ERR) { - /* - * It's possile if the associated - * terminal is lost. - */ - debug_print(NULL, 2, "cons: " - "getch() failed.\n"); - break; - } - - ch = tolower((unsigned char)c); - dump_write("\n<-- User hit the key '%c' " - "(ascii = %d) -->\n", ch, (int)ch); - - cmd_id = cmd_id_get(ch); - if (cmd_id != CMD_INVALID_ID) { - /* - * The character is a command. Send - * the command to 'disp thread'. - */ - (void) pthread_mutex_lock( - &s_disp_ctl.mutex); - - CMD_ID_SET(&s_disp_ctl.cmd, cmd_id); - dispthr_flagset_nolock(DISP_FLAG_CMD); - - (void) pthread_mutex_unlock( - &s_disp_ctl.mutex); - } else { - /* - * Hit the keys 'UP'/'DOWN'/'ENTER' - */ - switch (ch) { - case 2: /* KEY DOWN */ - dispthr_flagset_lock( - DISP_FLAG_SCROLLDOWN); - break; - - case 3: /* KEY UP */ - dispthr_flagset_lock( - DISP_FLAG_SCROLLUP); - break; - - case 13: /* enter. */ - dispthr_flagset_lock( - DISP_FLAG_SCROLLENTER); - break; - - default: - break; - } - } + dispthr_flagset_lock(DISP_FLAG_GETCH); } + } } - reg_curses_fini(); - -L_EXIT: debug_print(NULL, 2, "cons thread is exiting\n"); return (NULL); } diff --git a/common/include/disp.h b/common/include/disp.h index f9d28de..f934406 100644 --- a/common/include/disp.h +++ b/common/include/disp.h @@ -47,6 +47,7 @@ extern "C" { typedef enum { DISP_FLAG_NONE = 0, + DISP_FLAG_ERR, DISP_FLAG_QUIT, DISP_FLAG_PROFILING_DATA_READY, DISP_FLAG_PROFILING_DATA_FAIL, @@ -59,7 +60,8 @@ typedef enum { DISP_FLAG_CMD, DISP_FLAG_SCROLLUP, DISP_FLAG_SCROLLDOWN, - DISP_FLAG_SCROLLENTER + DISP_FLAG_SCROLLENTER, + DISP_FLAG_GETCH } disp_flag_t; typedef struct _disp_ctl { -- 2.41.0