int op_page_next(cmd_t *cmd, boolean_t smpl) { /* * Create a new page and append it after the current page in page * list. The new page is showed in page_next_execute(). */ if (page_create(cmd) != NULL) { if (page_next_execute(smpl)) { return (0); } } return (-1); }
/* ARGSUSED */ static int op_page_prev(cmd_t *cmd, boolean_t smpl) { page_t *prev; if ((prev = page_curprev_get()) != NULL) { page_drop_next(prev); (void) page_current_set(prev); page_next_set(prev); if (!page_next_execute(smpl)) { return (-1); } } return (0); }
/* ARGSUSED */ int op_refresh(cmd_t *cmd, boolean_t smpl) { page_t *cur = page_current_get(); page_next_set(cur); if (!os_page_smpl_start(cur)) { /* * Refresh the current page by the latest sampling data. */ if (!page_next_execute(B_FALSE)) { return (-1); } } return (0); }
/* ARGSUSED */ static void * disp_handler(void *arg) { disp_flag_t flag; int status = 0; cmd_t cmd; boolean_t quit, pagelist_inited = B_FALSE; struct timespec timeout; uint64_t start_ms; int64_t diff_ms; /* * Wait cons thread to complete initialization. */ if (!consthr_init_wait()) { debug_print(NULL, 2, "Timeout for waiting cons thread to " "complete initialization\n"); /* * The cons thread should exit with error or startup failed, * disp thread stops running. */ goto L_EXIT; } /* * NumaTOP contains multiple windows. It uses double linked list * to link all of windows. */ page_list_init(); pagelist_inited = B_TRUE; timeout_set(&timeout, 0); start_ms = current_ms(); for (;;) { status = 0; (void) pthread_mutex_lock(&s_disp_ctl.mutex); flag = s_disp_ctl.flag; while (flag == DISP_FLAG_NONE) { status = pthread_cond_timedwait(&s_disp_ctl.cond, &s_disp_ctl.mutex, &timeout); flag = s_disp_ctl.flag; if (status == ETIMEDOUT) { break; } } if (flag == DISP_FLAG_CMD) { (void) memcpy(&cmd, &s_disp_ctl.cmd, sizeof (cmd)); } s_disp_ctl.flag = DISP_FLAG_NONE; (void) pthread_mutex_unlock(&s_disp_ctl.mutex); diff_ms = current_ms() - start_ms; if (g_run_secs <= diff_ms / MS_SEC) { g_run_secs = TIME_NSEC_MAX; debug_print(NULL, 2, "disp: it's time to exit\n"); continue; } if ((status == ETIMEDOUT) && (flag == DISP_FLAG_NONE)) { if (page_current_get() == NULL) { timeout_set(&timeout, DISP_DEFAULT_INTVAL); continue; } /* * Force a 'refresh' operation. */ CMD_ID_SET(&cmd, CMD_REFRESH_ID); cmd_execute(&cmd, NULL); timeout_set(&timeout, DISP_DEFAULT_INTVAL); continue; } switch (flag) { case DISP_FLAG_QUIT: debug_print(NULL, 2, "disp: received DISP_FLAG_QUIT\n"); goto L_EXIT; case DISP_FLAG_CMD: cmd_received(&cmd, &quit, &timeout); if (quit) { debug_print(NULL, 2, "disp thread received CMD_QUIT_ID\n"); goto L_EXIT; } break; case DISP_FLAG_PROFILING_DATA_READY: case DISP_FLAG_CALLCHAIN_DATA_READY: case DISP_FLAG_LL_DATA_READY: case DISP_FLAG_PQOS_CMT_READY: /* * Show the page. */ (void) page_next_execute(B_FALSE); timeout_set(&timeout, DISP_DEFAULT_INTVAL); break; case DISP_FLAG_PROFILING_DATA_FAIL: case DISP_FLAG_CALLCHAIN_DATA_FAIL: case DISP_FLAG_LL_DATA_FAIL: case DISP_FLAG_PQOS_CMT_FAIL: /* * Received the notification that the perf counting * was failed. */ debug_print(NULL, 2, "disp: profiling/callchain/LL data failed.\n"); disp_go_home(); break; case DISP_FLAG_SCROLLUP: /* * User hits the "UP" key. */ key_scroll(SCROLL_UP); if (status == ETIMEDOUT) { timeout_set(&timeout, DISP_DEFAULT_INTVAL); } break; case DISP_FLAG_SCROLLDOWN: /* * User hits the "DOWN" key. */ key_scroll(SCROLL_DOWN); if (status == ETIMEDOUT) { timeout_set(&timeout, DISP_DEFAULT_INTVAL); } break; case DISP_FLAG_SCROLLENTER: /* * User selects a scroll item and hit the "ENTER". */ scroll_enter(); if (status == ETIMEDOUT) { timeout_set(&timeout, DISP_DEFAULT_INTVAL); } break; default: break; } } L_EXIT: if (pagelist_inited) { page_list_fini(); } /* * Let the perf thread exit first. */ perf_fini(); debug_print(NULL, 2, "disp thread is exiting\n"); return (NULL); }