Exemple #1
0
static int
llcallchain_bufinfo_show(dyn_llcallchain_t *dyn, track_proc_t *proc,
	track_lwp_t *lwp)
{
	char content[WIN_LINECHAR_MAX];
	lat_line_t *lat_buf, *line;
	win_reg_t *reg;
	int lwpid = 0, nlines, lat;
	
	/*
	 * Display the caption of data table:
	 * "ADDR SIZE ACCESS% LAT(ns) DESC"
	 */
	reg = &dyn->buf_caption;
	reg_erase(reg);	
	(void) snprintf(content, sizeof (content),
	    "%16s%8s%11s%11s%34s",
	    CAPTION_ADDR, CAPTION_SIZE, CAPTION_BUFHIT,
	    CAPTION_AVGLAT, CAPTION_DESC);
	reg_line_write(&dyn->buf_caption, 1, ALIGN_LEFT, content);
	dump_write("%s\n", content);
	reg_refresh_nout(reg);
	
	/*
	 * Get the stat of buffer.
	 */	
	reg = &dyn->buf_data;
	reg_erase(reg);	

	if (lwp != NULL) {
		lwpid = lwp->id;	
	}
	 
	if ((lat_buf = win_lat_buf_create(proc, lwpid, &nlines)) == NULL) {
		return (-1);
	}

	/*
	 * Fill in the memory access information.
	 */
	win_lat_buf_fill(lat_buf, nlines, proc, lwp, &lat);
	
	/*
	 * Check if the linear address is located in a buffer in
	 * process address space.
	 */ 
	if ((line = bsearch((void *)(dyn->addr), lat_buf, nlines,
		sizeof (lat_line_t), bufaddr_cmp)) != NULL) {
		win_lat_str_build(content, WIN_LINECHAR_MAX, 0, line);
		reg_line_write(reg, 0, ALIGN_LEFT, content);
		dump_write("%s\n", content);
	}
	
	reg_refresh_nout(reg);
	free(lat_buf);
	return (0);
}
Exemple #2
0
static boolean_t
latnode_data_show(track_proc_t *proc, dyn_latnode_t *dyn, map_entry_t *entry,
	boolean_t *note_out)
{
	win_reg_t *reg;
	track_lwp_t *lwp = NULL;
	char content[WIN_LINECHAR_MAX], intval_buf[16], size_str[32];

	*note_out = B_FALSE;

	if ((dyn->lwpid != 0) &&
	    (lwp = proc_lwp_find(proc, dyn->lwpid)) == NULL) {
		win_warn_msg(WARN_INVALID_LWPID);
		win_note_show(NOTE_INVALID_LWPID);
		*note_out = B_TRUE;
		return (B_FALSE);
	}

	reg = &dyn->msg;
	reg_erase(reg);
	disp_intval(intval_buf, 16);
	(void) snprintf(content, sizeof (content),
	    "Break down of memory area for physical memory on node (interval: %s)",
	    intval_buf);
	reg_line_write(reg, 1, ALIGN_LEFT, content);
	dump_write("\n*** %s\n", content);
	reg_refresh_nout(reg);

	reg = &dyn->note;
	reg_erase(reg);	
	win_size2str(dyn->size, size_str, sizeof (size_str));
	if (lwp != NULL) {
		(void) snprintf(content, sizeof (content),
		    "Memory area(%"PRIX64", %s), thread(%d)",
		    dyn->addr, size_str, lwp->id);
	} else {
		(void) snprintf(content, sizeof (content),
		    "Memory area(%"PRIX64", %s), process(%d)",
		    dyn->addr, size_str, proc->pid);
	}

	reg_line_write(reg, 1, ALIGN_LEFT, content);
	dump_write("\n*** %s\n", content);
	reg_refresh_nout(reg);

	latnode_data_get(proc, lwp, dyn);

	if (lwp != NULL) {
		lwp_refcount_dec(lwp);
	}

	return (B_TRUE);
}
Exemple #3
0
static int
llcallchain_list_show(dyn_llcallchain_t *dyn, track_proc_t *proc,
	track_lwp_t *lwp)
{
	perf_llrecgrp_t *llrec_grp;
	char content[WIN_LINECHAR_MAX];
	os_perf_llrec_t *rec_arr;
	sym_chainlist_t chainlist;
	win_reg_t *reg;
	int i;

	reg = &dyn->chain_caption;
	reg_erase(reg);	
	snprintf(content, WIN_LINECHAR_MAX, "Call-chain list:");
	reg_line_write(reg, 1, ALIGN_LEFT, content);
	dump_write("%s\n", content);
	reg_refresh_nout(reg);

	reg = &dyn->pad;
	reg_erase(reg);	
	dump_write("\n");
	reg_refresh_nout(reg);

	if (lwp != NULL) {
		llrec_grp = &lwp->llrec_grp;
	} else {
		llrec_grp = &proc->llrec_grp;
	}

	if (sym_load(proc, SYM_TYPE_FUNC) != 0) {
		debug_print(NULL, 2, "Failed to load the process symbol "
			"(pid = %d)\n", proc->pid);
		return (-1);
	}

	memset(&chainlist, 0, sizeof (sym_chainlist_t));
	rec_arr = llrec_grp->rec_arr;

	for (i = 0; i < llrec_grp->nrec_cur; i++) {
		if ((rec_arr[i].addr < dyn->addr) ||
			(rec_arr[i].addr >= dyn->addr + dyn->size)) {
			continue;
		}

		sym_callchain_add(&proc->sym, rec_arr[i].callchain.ips,
			rec_arr[i].callchain.ip_num, &chainlist);		
	}

	chainlist_show(&chainlist, &dyn->chain_data);
	return (0);
}
Exemple #4
0
static int
chainlist_show(sym_chainlist_t *chainlist, win_reg_t *reg)
{
	sym_callchain_t *chain;
	int nentry, nchain;
	int i, j = 0, k, nlines;
	char content[WIN_LINECHAR_MAX];
	callchain_line_t *buf, *line;

	sym_callchain_resort(chainlist);
	nentry = sym_chainlist_nentry(chainlist, &nchain);

	reg_erase(reg);
	if (nentry == 0) {
		snprintf(content, WIN_LINECHAR_MAX,
			"<- Detecting call-chain ... -> ");
		reg_line_write(reg, 0, ALIGN_LEFT, content);
		dump_write("%s\n", content);
		reg_refresh_nout(reg);
		return (0);
	}
	
	nlines = nentry + 2 * nchain;
	if ((buf = zalloc(nlines * sizeof (callchain_line_t))) == NULL) {
		return (-1);
	}
	
	for (i = 0; i < nchain; i++) {
		if ((chain = sym_callchain_detach(chainlist)) == NULL) {
			break;
		}
		
		line = &buf[j++];
		snprintf(line->content, WIN_LINECHAR_MAX,
			"<- call-chain %d: ->", i + 1);

		for (k = 0; k < chain->nentry; k++) {
			line = &buf[j++];			
			strncpy(line->content, chain->entry_arr[k].name, WIN_LINECHAR_MAX);
			line->content[WIN_LINECHAR_MAX - 1] = 0;
		}

		line = &buf[j++];
		strcpy(line->content, "");
		sym_callchain_free(chain);
	}

	if (reg->buf != NULL) {
		free(reg->buf);
	}

	reg->buf = (void *)buf;
	reg->nlines_total = nlines - 1;
	reg_scroll_show(reg, (void *)(reg->buf), nlines - 1, callchain_str_build);
	reg_refresh_nout(reg);
	sym_chainlist_free(chainlist);
	return (0);
}
Exemple #5
0
/*
 * Display the hidden lines on screen.
 */
static void
reg_hidden_show(win_reg_t *r, int idx_start)
{
	int i, idx_end;
	char line[WIN_LINECHAR_MAX];

	if (r->hdl == NULL) {
		return;
	}

	if ((idx_end = idx_start + r->nlines_scr) > r->nlines_total) {
		idx_end = r->nlines_total;
	}

	reg_erase(r);
	for (i = idx_start; i < idx_end; i++) {
		r->line_get(r, i, line, WIN_LINECHAR_MAX);
		reg_line_write(r, i - idx_start, ALIGN_LEFT, line);
	}
}
Exemple #6
0
static int
latnode_data_get(track_proc_t *proc, track_lwp_t *lwp, dyn_latnode_t *dyn)
{
	lat_line_t *buf;
	char content[WIN_LINECHAR_MAX];
	int nlines, lwpid = 0, lat = 0;

	reg_erase(&dyn->caption);
	reg_refresh_nout(&dyn->caption);
	reg_erase(&dyn->data);
	reg_refresh_nout(&dyn->data);

	if (lwp != NULL) {
		lwpid = lwp->id;		
	}

	if ((buf = latnode_buf_create(proc, lwpid, dyn->addr,
		dyn->size, &nlines)) == NULL) {
		reg_line_write(&dyn->caption, 1, ALIGN_LEFT,
		    "Failed to get the process NUMA mapping!");
		reg_refresh_nout(&dyn->caption);
		return (-1);
	}

	win_lat_buf_fill(buf, nlines, proc, lwp, &lat);

	/*
	 * Sort by the number of buffer accessing.
	 */
	qsort(buf, nlines, sizeof (lat_line_t), win_lat_cmp);

	/*
	 * Display the caption of data table:
	 * "ADDR SIZE NODE ACCESS% LAT(ns) DESC"
	 */
	(void) snprintf(content, sizeof (content),
	    "%16s%8s%8s%11s%11s",
	    CAPTION_ADDR, CAPTION_SIZE, CAPTION_NID, CAPTION_BUFHIT,
	    CAPTION_AVGLAT);

	reg_line_write(&dyn->caption, 1, ALIGN_LEFT, content);
	reg_refresh_nout(&dyn->caption);

	/*
	 * Save data of buffer statistics in scrolling buffer.
	 */
	dyn->data.nlines_total = nlines;
	if (dyn->data.buf != NULL) {
		free(dyn->data.buf);
	}

	/*
	 * Display the buffer with statistics in scrolling buffer
	 */
	dyn->data.buf = (void *)buf;
	reg_scroll_show(&dyn->data, (void *)(dyn->data.buf),
	    nlines, win_lat_str_build);
	reg_refresh_nout(&dyn->data);

	return (0);
}
Exemple #7
0
static void
llcallchain_data_show(dyn_win_t *win, boolean_t *note_out)
{
	dyn_llcallchain_t *dyn;
	pid_t pid;
	int lwpid;
	uint64_t size;
	track_proc_t *proc;
	track_lwp_t *lwp = NULL;
	win_reg_t *reg;
	char content[WIN_LINECHAR_MAX], intval_buf[16];
	char size_str[32];

	dyn = (dyn_llcallchain_t *)(win->dyn);
	pid = dyn->pid;
	lwpid = dyn->lwpid;
	size = dyn->size;
	*note_out = B_FALSE;

	if ((proc = proc_find(pid)) == NULL) {
		win_warn_msg(WARN_INVALID_PID);
		win_note_show(NOTE_INVALID_PID);
		*note_out = B_TRUE;
		return;
	}

	if ((lwpid > 0) && ((lwp = proc_lwp_find(proc, lwpid)) == NULL)) {
		proc_refcount_dec(proc);
		win_warn_msg(WARN_INVALID_LWPID);
		win_note_show(NOTE_INVALID_LWPID);
		*note_out = B_TRUE;
		return;
	}

	reg = &dyn->msg;
	reg_erase(reg);	
	disp_intval(intval_buf, 16);
	win_size2str(size, size_str, sizeof (size_str));

	if (lwp == NULL) {
		(void) snprintf(content, WIN_LINECHAR_MAX,
			"Call-chain when process accesses the memory area (pid: %d)"
	    	" (interval: %s)", pid, intval_buf);
	} else {
		(void) snprintf(content, WIN_LINECHAR_MAX,
			"Call-chain when thread accesses the memory area (lwpid: %d)"
	    	" (interval: %s)", lwpid, intval_buf);
	}

	dump_write("\n*** %s\n", content);
	reg_line_write(reg, 1, ALIGN_LEFT, content);
	reg_refresh_nout(reg);

	llcallchain_bufinfo_show(dyn, proc, lwp);
	llcallchain_list_show(dyn, proc, lwp);
	
	if (lwp != NULL) {
		lwp_refcount_dec(lwp);
	}

	proc_refcount_dec(proc);
}
Exemple #8
0
/*
 * Display the performance statistics per node.
 */
void
os_nodedetail_data(dyn_nodedetail_t *dyn, win_reg_t *seg)
{
	char s1[256];
	node_t *node;
	win_countvalue_t value;
	node_meminfo_t meminfo;
	int i = 1;

	reg_erase(seg);
	node = node_get(dyn->nid);
	win_node_countvalue(node, &value);
	node_meminfo(node->nid, &meminfo);

	/*
	 * Display the CPU
	 */
	node_cpu_string(node, s1, sizeof (s1));
	nodedetail_line_show(seg, "CPU:", s1, i++);

	/*
	 * Display the CPU utilization
	 */
	(void) snprintf(s1, sizeof (s1), "%.1f%%", value.cpu * 100.0);	
	nodedetail_line_show(seg, "CPU%:", s1, i++);

	/*
	 * Display the number of RMA
	 */
	(void) snprintf(s1, sizeof (s1), "%.1fK", value.rma);	
	nodedetail_line_show(seg, "RMA:", s1, i++);

	/*
	 * Display the number of LMA if platform supports
	 */
	if (plat_offcore_num() > 1) {
		(void) snprintf(s1, sizeof (s1), "%.1fK", value.lma);	
	} else {
		(void) snprintf(s1, sizeof (s1), "%s", "-");	
	}

	nodedetail_line_show(seg, "LMA:", s1, i++);

	/*
	 * Display the size of total memory
	 */
	(void) snprintf(s1, sizeof (s1), "%.1fG",
		(double)((double)(meminfo.mem_total) / (double)(GB_BYTES)));
	nodedetail_line_show(seg, "MEM total:", s1, i++);

	/*
	 * Display the size of free memory
	 */
	(void) snprintf(s1, sizeof (s1), "%.1fG",
		(double)((double)(meminfo.mem_free) / (double)(GB_BYTES)));
	nodedetail_line_show(seg, "MEM free:", s1, i++);

	/*
	 * Display the size of active memory.
	 */
	(void) snprintf(s1, sizeof (s1), "%.2fG",
		(double)((double)(meminfo.active) / (double)(GB_BYTES)));	
	nodedetail_line_show(seg, "MEM active:", s1, i++);

	/*
	 * Display the size of inactive memory.
	 */
	(void) snprintf(s1, sizeof (s1), "%.2fG",
		(double)((double)(meminfo.inactive) / (double)(GB_BYTES)));
	nodedetail_line_show(seg, "MEM inactive:", s1, i++);

	/*
	 * Display the size of dirty memory.
	 */
	(void) snprintf(s1, sizeof (s1), "%.2fG",
		(double)((double)(meminfo.dirty) / (double)(GB_BYTES)));
	nodedetail_line_show(seg, "Dirty:", s1, i++);

	/*
	 * Display the size of writeback memory.
	 */
	(void) snprintf(s1, sizeof (s1), "%.2fG",
		(double)((double)(meminfo.dirty) / (double)(GB_BYTES)));
	nodedetail_line_show(seg, "Writeback:", s1, i++);

	/*
	 * Display the size of mapped memory.
	 */
	(void) snprintf(s1, sizeof (s1), "%.2fG",
		(double)((double)(meminfo.mapped) / (double)(GB_BYTES)));
	nodedetail_line_show(seg, "Mapped:", s1, i++);

	reg_refresh_nout(seg);
}