/* ARGSUSED */ int os_op_switch2llcallchain(cmd_t *cmd1, boolean_t smpl) { cmd_llcallchain_t *cmd = (cmd_llcallchain_t *)cmd1; page_t *cur = page_current_get(); dyn_lat_t *dyn; win_reg_t *data_reg; lat_line_t *lines; int i; dyn = (dyn_lat_t *)(cur->dyn_win.dyn); data_reg = &dyn->data; if ((lines = (lat_line_t *)(data_reg->buf)) == NULL) { return (-1); } if ((i = data_reg->scroll.highlight) == -1) { return (-1); } cmd->pid = dyn->pid; cmd->lwpid = dyn->lwpid; cmd->addr = lines[i].bufaddr.addr; cmd->size = lines[i].bufaddr.size; return (op_page_next(cmd1, smpl)); }
int os_preop_switch2pqosmbm(cmd_t *cmd, boolean_t *smpl) { page_t *cur = page_current_get(); win_type_t type = PAGE_WIN_TYPE(cur); int ret = 0; if ((type == WIN_TYPE_PQOS_CMT_MONIPROC) || (type == WIN_TYPE_PQOS_CMT_MONILWP)) { if (perf_profiling_smpl(B_FALSE) != 0) return -1; if (disp_flag2_wait() != DISP_FLAG_PROFILING_DATA_READY) return -1; CMD_PQOS_MBM(cmd)->pid = DYN_PQOS_CMT_PROC(cur)->pid; CMD_PQOS_MBM(cmd)->lwpid = DYN_PQOS_CMT_PROC(cur)->lwpid; CMD_PQOS_MBM(cmd)->flags = PERF_PQOS_FLAG_TOTAL_BW | PERF_PQOS_FLAG_LOCAL_BW; perf_pqos_cmt_stop(CMD_PQOS_MBM(cmd)->pid, CMD_PQOS_MBM(cmd)->lwpid); ret = perf_pqos_proc_setup(CMD_PQOS_MBM(cmd)->pid, CMD_PQOS_MBM(cmd)->lwpid, CMD_PQOS_MBM(cmd)->flags); } return (ret); }
int os_preop_switch2pqoscmt(cmd_t *cmd, boolean_t *smpl) { page_t *cur = page_current_get(); win_type_t type = PAGE_WIN_TYPE(cur); int ret = 0; switch (type) { case WIN_TYPE_MONIPROC: CMD_PQOS_CMT(cmd)->pid = DYN_MONI_PROC(cur)->pid; CMD_PQOS_CMT(cmd)->lwpid = 0; CMD_PQOS_CMT(cmd)->flags = PERF_PQOS_FLAG_LLC; break; case WIN_TYPE_RAW_NUM: case WIN_TYPE_TOPNPROC: CMD_PQOS_CMT(cmd)->pid = 0; CMD_PQOS_CMT(cmd)->lwpid = 0; CMD_PQOS_CMT(cmd)->flags = PERF_PQOS_FLAG_LLC; break; case WIN_TYPE_MONILWP: CMD_PQOS_CMT(cmd)->pid = DYN_MONI_LWP(cur)->pid; CMD_PQOS_CMT(cmd)->lwpid = DYN_MONI_LWP(cur)->lwpid; CMD_PQOS_CMT(cmd)->flags = PERF_PQOS_FLAG_LLC; break; case WIN_TYPE_PQOS_MBM_MONIPROC: case WIN_TYPE_PQOS_MBM_MONILWP: CMD_PQOS_CMT(cmd)->pid = DYN_PQOS_MBM_PROC(cur)->pid; CMD_PQOS_CMT(cmd)->lwpid = DYN_PQOS_MBM_PROC(cur)->lwpid; CMD_PQOS_CMT(cmd)->flags = PERF_PQOS_FLAG_LLC; break; default: return (-1); } perf_pqos_cmt_stop(CMD_PQOS_CMT(cmd)->pid, CMD_PQOS_CMT(cmd)->lwpid); if (perf_profiling_smpl(B_FALSE) != 0) return -1; if (disp_flag2_wait() != DISP_FLAG_PROFILING_DATA_READY) return -1; if (CMD_PQOS_CMT(cmd)->pid == 0) { ret = perf_pqos_active_proc_setup(CMD_PQOS_CMT(cmd)->flags, B_FALSE); } else { ret = perf_pqos_proc_setup(CMD_PQOS_CMT(cmd)->pid, CMD_PQOS_CMT(cmd)->lwpid, CMD_PQOS_CMT(cmd)->flags); } return (ret); }
/* * Called when user hits the 'ENTER' key. */ static void scroll_enter(void) { page_t *page; dyn_win_t *dyn_win; if ((page = page_current_get()) != NULL) { dyn_win = &page->dyn_win; if (dyn_win->scroll_enter != NULL) { (dyn_win->scroll_enter)(dyn_win); } } }
/* * Called when user hits the 'UP'/'DOWN' key. */ static void key_scroll(int scroll_type) { page_t *page; dyn_win_t *dyn_win; if ((page = page_current_get()) != NULL) { dyn_win = &page->dyn_win; if (dyn_win->scroll != NULL) { (dyn_win->scroll)(dyn_win, scroll_type); } } }
int os_preop_leavecallchain(cmd_t *cmd, boolean_t *smpl) { page_t *cur = page_current_get(); count_id_t countid; if ((countid = DYN_CALLCHAIN(cur)->countid) != 0) { perf_profiling_restore(countid); } *smpl = B_TRUE; return (0); }
/* ARGSUSED */ static int op_sort(cmd_t *cmd, boolean_t smpl) { page_t *cur; int cmd_id; if ((cur = page_current_get()) != NULL) { cmd_id = CMD_ID(cmd); sortkey_set(cmd_id, cur); (void) op_refresh(cmd, B_FALSE); } 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); }
int os_op_callchain_count(cmd_t *cmd, boolean_t smpl) { page_t *cur; count_id_t countid; int cmd_id; if ((cur = page_current_get()) != NULL) { cmd_id = CMD_ID(cmd); if ((countid = callchain_countid_set(cmd_id, cur)) == COUNT_INVALID) { return (0); } perf_profiling_partpause(countid); op_refresh(cmd, smpl); } return (0); }
static int callchain_id_get(void) { page_t *cur = page_current_get(); if (cur == NULL) { return (CMD_INVALID_ID); } switch (PAGE_WIN_TYPE(cur)) { case WIN_TYPE_MONIPROC: case WIN_TYPE_MONILWP: return (CMD_CALLCHAIN_ID); case WIN_TYPE_LAT_PROC: case WIN_TYPE_LAT_LWP: return (CMD_LLCALLCHAIN_ID); default: return (CMD_INVALID_ID); } }
int os_op_switch2ll(cmd_t *cmd, boolean_t smpl) { page_t *cur = page_current_get(); int type = PAGE_WIN_TYPE(cur); switch (type) { case WIN_TYPE_MONIPROC: CMD_LAT(cmd)->pid = DYN_MONI_PROC(cur)->pid; CMD_LAT(cmd)->lwpid = 0; break; case WIN_TYPE_MONILWP: CMD_LAT(cmd)->pid = DYN_MONI_LWP(cur)->pid; CMD_LAT(cmd)->lwpid = DYN_MONI_LWP(cur)->lwpid; break; default: return (-1); } return (op_page_next(cmd, smpl)); }
int os_preop_switch2accdst(cmd_t *cmd, boolean_t *smpl) { page_t *cur = page_current_get(); win_type_t type = PAGE_WIN_TYPE(cur); switch (type) { case WIN_TYPE_LAT_PROC: CMD_ACCDST(cmd)->pid = DYN_LAT(cur)->pid; CMD_ACCDST(cmd)->lwpid = 0; break; case WIN_TYPE_LAT_LWP: CMD_ACCDST(cmd)->pid = DYN_LAT(cur)->pid; CMD_ACCDST(cmd)->lwpid = DYN_LAT(cur)->lwpid; break; default: return (-1); } return (0); }
/* * The common entry to process all commands. */ void cmd_execute(cmd_t *cmd, boolean_t *badcmd) { cmd_id_t cmd_id; win_type_t type; page_t *cur; switch_t *s; boolean_t b = B_TRUE, smpl = B_FALSE; if ((cmd_id = CMD_ID(cmd)) == CMD_INVALID_ID) { goto L_EXIT; } b = B_FALSE; if ((cur = page_current_get()) == NULL) { /* It's the first window. */ type = WIN_TYPE_RAW_NUM; } else { type = PAGE_WIN_TYPE(cur); } s = &s_switch[type][cmd_id]; if (s->preop != NULL) { (void) s->preop(cmd, &smpl); } if (s->op != NULL) { (void) s->op(cmd, smpl); } L_EXIT: if (badcmd != NULL) { *badcmd = b; } }
int os_preop_switch2callchain(cmd_t *cmd, boolean_t *smpl) { page_t *cur = page_current_get(); win_type_t type = PAGE_WIN_TYPE(cur); switch (type) { case WIN_TYPE_MONIPROC: CMD_CALLCHAIN(cmd)->pid = DYN_MONI_PROC(cur)->pid; CMD_CALLCHAIN(cmd)->lwpid = 0; break; case WIN_TYPE_MONILWP: CMD_CALLCHAIN(cmd)->pid = DYN_MONI_LWP(cur)->pid; CMD_CALLCHAIN(cmd)->lwpid = DYN_MONI_LWP(cur)->lwpid; break; default: return (-1); } *smpl = B_TRUE; return (perf_profiling_partpause(COUNT_RMA)); }
/* 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); }