Polymon

Michael Hendrie pmix at hendrie.id.au
Mon Jan 30 09:47:10 UTC 2012


Somehow this reply ended up in my spam folder.

Have just tested and the patch seems to resolve the segfault issue and provide some guidance on using polymon.

Thanks for the help!

On 20/01/2012, at 9:04 AM, Dmitry Kurochkin wrote:

> Hello Michael.
> 
> I am afraid the polymon is not very well documented.  I was able to
> reproduce the segfault you reported.  The attached patch should fix it
> and few other problems.  Also the patch adds a basic help screen (press
> 'h') which would hopefully help you to get started.  More info regarding
> polymon usage can be found in the mailing list archives [1].
> 
> Regards,
>  Dmitry
> 
> [1] http://www.web-polygraph.org/mail-archive/users/199912/0069.html
> polymon-fixes_v4.0.10.patch - patch for Web Polygraph v4.0.10
> 
> Various polymon improvements: few segfault fixes and basic help screen.
> 
> diff --git a/src/monitor/polymon.cc b/src/monitor/polymon.cc
> index 4b70415..d349b46 100644
> --- src/monitor/polymon.cc
> +++ src/monitor/polymon.cc
> @@ -147,73 +147,88 @@ struct HostFilter {
> 
> 
> // used in some "matrix" windows to remember screen content
> class WinMatrix {
> 	public:
> 		WinMatrix(int aMaxY, int aMaxX);
> 
> 		double operator ()(int y, int x) const { return theImage[safePos(y,x)]; }
> 		double &operator ()(int y, int x) { return theImage[safePos(y,x)]; }
> 
> 	protected:
> 		int safePos(int y, int x) const;
> 
> 	protected:
> 		Array<double> theImage;
> 		int theMaxY;
> 		int theMaxX;
> };
> 
> // WINDOW wrapper with a title and event handlers
> -class Window: public WINDOW {
> +class Window {
> 	public:
> 		typedef void (Window::*EventHandler)(const Host &);
> 
> 	public:
> 		Window(const char *aTitle);
> 		virtual ~Window();
> 
> 		virtual void noteAdd(const Host &) {}
> 		virtual void noteDel(const Host &) {}
> 		virtual void noteUpd(const Host &) {}
> 
> +	private:
> +		// disable copying
> +		Window(const Window &);
> +		Window &operator =(const Window &);
> +
> 	public:
> -		const char *theTitle;
> +		WINDOW *const handle;
> +		const char *title;
> };
> 
> // general monitor information
> class InfoWindow: public Window {
> 	public:
> 		InfoWindow(const char *aTitle);
> 
> 		virtual void noteAdd(const Host &);
> 		virtual void noteDel(const Host &);
> 		virtual void noteUpd(const Host &);
> 
> 	protected:
> 		void update();
> 
> 	protected:
> 		int theMsgCnt;       // msgs seen so far
> 		int theListnCnt;     // derived from CopyCnt in the fwded msg
> };
> 
> +// help window
> +class HelpWindow: public Window {
> +	public:
> +		HelpWindow();
> +
> +	protected:
> +		void update();
> +};
> +
> // summary information about SmxWindows
> class MsgSum;
> class SumWindow: public Window {
> 	public:
> 		SumWindow(const char *aTitle);
> 
> 		virtual void noteAdd(const Host &);
> 		virtual void noteDel(const Host &);
> 		virtual void noteUpd(const Host &);
> 
> 	protected:
> 		void update();
> 		void displaySide(int &y, int x, const MsgSum &sum);
> 		void displayLine(int y, int x, const char *label, const AggrStat &stats, const char *meas, double scale = 1);
> };
> 
> // single measurement matrix window
> class SmxWindow: public Window {
> 	public:
> 		SmxWindow(const char *aTitle);
> @@ -267,41 +282,41 @@ class MsgSum {
> 
> 	public:
> 		String theLabels;
> 		AggrStat theReqRate;
> 		AggrStat theRepRate;
> 		AggrStat theBwidth;
> 		AggrStat theRespTime;
> 		AggrStat theDHR;
> 		AggrStat theConnUse;
> 		AggrStat theErrRatio;
> 		AggrStat theXactTotCnt;
> 		AggrStat theTotErrRatio;
> 		AggrStat theSockInstCnt;
> };
> 
> /* smx windows for all attributes */
> 
> struct RunLabelSmxWin: public SmxWindow {
> 	RunLabelSmxWin(const char *aTitle): SmxWindow(aTitle) {}
> 	virtual void displayMsg(int y, int x, const StatusFwdMsg &msg) {
> -		mvwprintw(this, y, x, (char*)"%7.6s", msg.theLabel);
> +		mvwprintw(handle, y, x, (char*)"%7.6s", msg.theLabel);
> 	}
> };
> 
> struct RunTimeSmxWin: public SmxWindow {
> 	RunTimeSmxWin(const char *aTitle): SmxWindow(aTitle) {}
> 	virtual void displayMsg(int y, int x, const StatusFwdMsg &msg);
> };
> 
> struct ReqRateSmxWin: public NumxWindow {
> 	ReqRateSmxWin(const char *aTitle): NumxWindow(aTitle, "%7.1f") {}
> 	virtual double msg2num(const StatusFwdMsg &msg) {
> 		return (double)msg.theReqRate;
> 	}
> };
> 
> struct RepRateSmxWin: public NumxWindow {
> 	RepRateSmxWin(const char *aTitle): NumxWindow(aTitle, "%7.1f") {}
> 	virtual double msg2num(const StatusFwdMsg &msg) {
> 		return (double)msg.theRepRate;
> 	}
> @@ -374,50 +389,53 @@ class MsgGapSmxWin: public SmxWindow {
> 	public:
> 		MsgGapSmxWin(const char *aTitle): SmxWindow(aTitle) {}
> 
> 		virtual void noteUpd(const Host &host);
> 
> 	protected:
> 		virtual void displayMsg(int y, int x, const StatusFwdMsg &msg);
> 
> 	protected:
> 		StatusFwdMsg theLastMsg;
> };
> 
> 
> /* globals */
> 
> static NetAddr TheDisp;
> 
> static FileScanner *TheScanner = 0;
> static bool DoShutdown = false;
> 
> -static Array<Host*> TheHosts;
> +static PtrArray<Host*> TheHosts;
> static Array<Host*> TheHostIdx; // address -> host map
> static int TheBusyHostCnt = 0;
> -static Array<String*> TheLabels;
> +static PtrArray<String*> TheLabels;
> static int TheUniqLblCnt = 0;
> 
> -static Array<Window*> TheWins;
> +static PtrArray<Window*> TheWins;
> static int TheWinPos = 0; // current window
> static Window *TheInfoWin = 0; // special
> 
> +static Window *TheHelpWin = 0; // help window
> +static bool ShowingHelp = false; // true iff help window is shown
> +
> static HostFilter TheFilter;
> static char TheFiltWarn[80] = "";
> static int TheSelHostCnt = 0;
> 
> static const int TheXMargin = 5;
> static const int TheYMargin = 4;
> static const int TheXCellWidth = 7;
> static const int TheYCellWidth = 2;
> 
> static void NoteMsg(const StatusFwdMsg &msg);
> static void Broadcast(Window::EventHandler weh, const Host &host);
> static void DeleteIdleHosts();
> static bool AddFirstLabel(const Host *skip, const String &l);
> static bool DelLastLabel(const Host *skip, const String &l);
> static void SelectHost(Host *host);
> static int SwitchWin(int idx);
> static int SwitchLblFilter(int idx);
> static int SwitchCatFilter(int idx);
> static void BuildFiltWarn(ostream &os);
> 
> @@ -429,53 +447,67 @@ inline int Dbl2Int(double v) { return (int)rint(v); }
> KbdMonitor::KbdMonitor(int aFD): theFD(aFD) {
> 	theReserv = TheScanner->setFD(theFD, dirRead, this);
> }
> 
> KbdMonitor::~KbdMonitor() {
> 	if (theReserv)
> 		TheScanner->clearRes(theReserv);
> }
> 
> void KbdMonitor::noteReadReady(int) {
> 
> 	switch (getch()) {
> 		case '0': SwitchWin(0); break;
> 
> 		case KEY_LEFT: SwitchWin(TheWinPos-1); break;
> 		case KEY_RIGHT: SwitchWin(TheWinPos+1); break;
> 
> 		case KEY_DOWN: SwitchLblFilter(TheFilter.lbl.pos - 1); break;
> 		case KEY_UP: SwitchLblFilter(TheFilter.lbl.pos + 1); break;
> 
> +		case 'H':
> +		case 'h':
> +			if (!ShowingHelp) {
> +				ShowingHelp = true;
> +				touchwin(TheHelpWin->handle);
> +				wrefresh(TheHelpWin->handle);
> +				return;
> +			} else
> +				SwitchWin(TheWinPos);
> +			break;
> +
> 		case 'S': SwitchCatFilter(TheFilter.logCat.pos - 1); break;
> 		case 's': SwitchCatFilter(TheFilter.logCat.pos + 1); break;
> 
> 		case 'R': SwitchLblFilter(0); SwitchCatFilter(0); DeleteIdleHosts(); // fall through
> 		case 'r': clearok(curscr, true); SwitchWin(TheWinPos); break;
> 
> 		case 'q':
> 		case 'Q': DoShutdown = true; break;
> 
> 		default: return;
> 	}
> 
> -	redrawwin(TheWins[TheWinPos]);
> +	if (ShowingHelp)
> +		ShowingHelp = false;
> +
> +	wrefresh(TheWins[TheWinPos]->handle);
> }
> 
> /* MsgMonitor */
> 
> MsgMonitor::MsgMonitor(Socket aSock): theSock(aSock), theSize(0) {
> 	theReserv = TheScanner->setFD(theSock.fd(), dirRead, this);
> }
> 
> MsgMonitor::~MsgMonitor() {
> 	if (theReserv)
> 		TheScanner->clearRes(theReserv);
> 	if (theSock)
> 		theSock.close();
> }
> 
> void MsgMonitor::noteReadReady(int) {
> 	static const int msgsz = sizeof(StatusFwdMsg);
> 
> 	const int sz = theSock.read(theBuf + theSize, sizeof(theBuf) - theSize);
> 
> @@ -491,41 +523,41 @@ void MsgMonitor::noteReadReady(int) {
> 		cerr << "dispatcher at " << TheDisp << " quit." << endl;
> 		DoShutdown = true;
> 		return;
> 	}
> 
> 	theSize += sz;
> 
> 	while (theSize >= msgsz) {
> 		StatusFwdMsg msg;
> 		memcpy(&msg, theBuf, msgsz);
> 		theSize -= msgsz;
> 		memmove(theBuf, theBuf + msgsz, theSize);
> 
> 		// handle the message
> 		msg.ntoh();
> 		msg.theRcvTime = TheClock;
> 		NoteMsg(msg);
> 	}
> 	Assert(theSize >= 0);
> 
> -	wrefresh(TheWins[TheWinPos]);
> +	wrefresh(TheWins[TheWinPos]->handle);
> }
> 
> 
> /* Ticker */
> 
> Ticker::Ticker(Time aPeriod): thePeriod(aPeriod) {
> 	sleepFor(thePeriod);
> }
> 
> Ticker::~Ticker() {
> }
> 
> void Ticker::wakeUp(const Alarm &alarm) {
> 	AlarmUser::wakeUp(alarm);
> 
> 	DeleteIdleHosts();
> 
> 	sleepFor(thePeriod);
> }
> 
> @@ -560,216 +592,237 @@ bool Host::matches(const HostFilter &filter) const {
> }
> 
> 
> /* WinMatrix */
> 
> WinMatrix::WinMatrix(int aMaxY, int aMaxX): 
> 	theImage((aMaxY+1) * (aMaxX+1)), theMaxY(aMaxY), theMaxX(aMaxX) {
> 	theImage.count(theImage.capacity());
> 	theImage.memset(0);
> }
> 
> int WinMatrix::safePos(int y, int x) const {
> 	Assert(y <= theMaxY && x <= theMaxX);
> 	const int p = y*(theMaxX+1) + x;
> 	Assert(p < theImage.count());
> 	return p;
> }
> 
> /* Window */
> 
> -Window::Window(const char *aTitle): WINDOW(*newwin(0,0,0,0)), theTitle(aTitle) {
> -	leaveok(this, true); // do not bother about cursor pos
> +Window::Window(const char *aTitle): handle(newwin(0,0,0,0)), title(aTitle) {
> +	leaveok(handle, true); // do not bother about cursor pos
> 
> 	int maxx, maxy;
> -	getmaxyx(this, maxy, maxx);
> +	(void)maxy; // silence g++ "set but not used" warning
> +	getmaxyx(handle, maxy, maxx);
> 
> -	werase(this);
> +	werase(handle);
> 
> 	// print window title
> -	wattron(this, A_BOLD);
> -	wattron(this, A_UNDERLINE);
> -	mvwaddstr(this, 0, (maxx - strlen(theTitle))/2, (char*)theTitle);
> -	wattroff(this, A_UNDERLINE);
> -	wattroff(this, A_BOLD);
> +	wattron(handle, A_BOLD);
> +	wattron(handle, A_UNDERLINE);
> +	mvwaddstr(handle, 0, (maxx - strlen(title))/2, (char*)title);
> +	wattroff(handle, A_UNDERLINE);
> +	wattroff(handle, A_BOLD);
> }
> 
> Window::~Window() {
> -	delwin(this);
> +	delwin(handle);
> }
> 
> 
> /* InfoWindow */
> 
> InfoWindow::InfoWindow(char const *aTitle): Window(aTitle),
> 	theMsgCnt(0), theListnCnt(0) {
> 	update();
> }
> 
> void InfoWindow::update() {
> 	const int x = 2;
> 	int y = 3;
> -	mvwprintw(this, y++, x, (char*)"%20s %s:%d", "dispatcher:", TheDisp.addrA().cstr(), TheDisp.port());
> -	mvwprintw(this, y++, x, (char*)"%20s %7d", "listeners:", theListnCnt);
> +	mvwprintw(handle, y++, x, (char*)"%20s %s:%d", "dispatcher:", TheDisp.addrA().cstr(), TheDisp.port());
> +	mvwprintw(handle, y++, x, (char*)"%20s %7d", "listeners:", theListnCnt);
> 	y++;
> -	mvwprintw(this, y++, x, (char*)"%20s %7d", "messages received:", theMsgCnt);
> -	mvwprintw(this, y++, x, (char*)"%20s %7d", "mean message size:", sizeof(StatusNotifMsg));
> -	mvwprintw(this, y++, x, (char*)"%20s %7d", "selected hosts:", TheSelHostCnt);
> -	mvwprintw(this, y++, x, (char*)"%20s %7d", "busy hosts:", TheBusyHostCnt);
> -	mvwprintw(this, y++, x, (char*)"%20s %7d", "experiments:", TheUniqLblCnt);
> +	mvwprintw(handle, y++, x, (char*)"%20s %7d", "messages received:", theMsgCnt);
> +	mvwprintw(handle, y++, x, (char*)"%20s %7d", "mean message size:", sizeof(StatusNotifMsg));
> +	mvwprintw(handle, y++, x, (char*)"%20s %7d", "selected hosts:", TheSelHostCnt);
> +	mvwprintw(handle, y++, x, (char*)"%20s %7d", "busy hosts:", TheBusyHostCnt);
> +	mvwprintw(handle, y++, x, (char*)"%20s %7d", "experiments:", TheUniqLblCnt);
> }
> 
> void InfoWindow::noteAdd(const Host &host) {
> 	Window::noteAdd(host);
> 	update();
> }
> 
> void InfoWindow::noteDel(const Host &host) {
> 	Window::noteDel(host);
> 	update();
> }
> 
> void InfoWindow::noteUpd(const Host &host) {
> 	Window::noteUpd(host);
> 	if (host.log().depth()) {
> 		theMsgCnt++;
> 		theListnCnt = host.log()[0].theCopyCnt;
> 	}
> 	update();
> }
> 
> 
> +/* HelpWindow */
> +
> +HelpWindow::HelpWindow(): Window("Help") {
> +	update();
> +}
> +
> +void HelpWindow::update() {
> +	const int x = 2;
> +	int y = 2;
> +	mvwprintw(handle, y++, x, "0:\t\tMonitor Info.");
> +	mvwprintw(handle, y++, x, "LEFT/RIGHT:\tNext/previous tab.");
> +	mvwprintw(handle, y++, x, "UP/DOWN:\tChange label filters.");
> +	mvwprintw(handle, y++, x, "h:\t\tShow/close this help tab.");
> +	mvwprintw(handle, y++, x, "S/s:\t\tChange client/server-side filters.");
> +	mvwprintw(handle, y++, x, "R:\t\tReset filters, remove idle hosts, and refresh screen.");
> +	mvwprintw(handle, y++, x, "r:\t\tRefresh screen.");
> +	mvwprintw(handle, y++, x, "Q/q:\t\tQuit.");
> +}
> +
> +
> /* SumWindow */
> 
> SumWindow::SumWindow(char const *aTitle): Window(aTitle) {
> 	update();
> }
> 
> void SumWindow::update() {
> 
> 	// collect summary info from hosts
> 	MsgSum cltSum, srvSum;
> 	for (int i = 0; i < TheHosts.count(); ++i) {
> 		if (const Host *host = TheHosts[i]) {
> 			if (host->log().depth()) {
> 				const StatusFwdMsg &msg = host->log()[0];
> 				if (host->isClient())
> 					cltSum += msg;
> 				else
> 					srvSum += msg;
> 			}
> 		}
> 	}
> 
> 	const int x = 2;
> 
> 	int y = 2;
> -	mvwprintw(this, y++, x, (char*)"%s (%d hosts)", "Client side:", cltSum.hostCount());
> +	mvwprintw(handle, y++, x, (char*)"%s (%d hosts)", "Client side:", cltSum.hostCount());
> 	displaySide(y, x+2, cltSum);
> 
> 	y += 1;
> -	mvwprintw(this, y++, x, (char*)"%s (%d hosts)", "Server side:", srvSum.hostCount());
> +	mvwprintw(handle, y++, x, (char*)"%s (%d hosts)", "Server side:", srvSum.hostCount());
> 	displaySide(y, x+2, srvSum);
> 
> 	y += 1;
> -	mvwprintw(this, y++, x+2, (char*)"%20s %7s %8s %9s %9s %s",
> +	mvwprintw(handle, y++, x+2, (char*)"%20s %7s %8s %9s %9s %s",
> 		"measurement:", "min", "mean", "max", "sum", "unit");
> }
> 
> void SumWindow::displaySide(int &y, int x, const MsgSum &sum) {
> -	//mvwprintw(this, y++, x, (char*)"%20s %s", "labels:", 
> +	//mvwprintw(handle, y++, x, (char*)"%20s %s", "labels:",
> 	//	(const char*)sum.theLabels);
> 
> 	displayLine(y++, x, "load:", sum.theReqRate, "req/sec");
> 	displayLine(y++, x, "throughput:", sum.theRepRate, "rep/sec");
> 	//displayLine(y++, x, "bandwidth:", sum.theBwidth, "Mbit/sec", 1024.*1024/8);
> 
> 	displayLine(y++, x, "response time:", sum.theRespTime, "msec");
> 	displayLine(y++, x, "DHR:", sum.theDHR, "%");
> 	//displayLine(y++, x, "connection use:", sum.theConnUse, "xact/conn");
> 
> 	displayLine(y++, x, "errors total:", sum.theTotErrRatio, "%");
> 	//displayLine(y++, x, "errors now:", sum.theErrRatio, "%");
> 	displayLine(y++, x, "xactions total:", sum.theXactTotCnt, "x10^6", 1e6);
> 	displayLine(y++, x, "open sockets now:", sum.theSockInstCnt, "");
> }
> 
> void SumWindow::displayLine(int y, int x, const char *label, const AggrStat &stats, const char *meas, double scale) {
> -	mvwprintw(this, y, x, (char*)"%20s %7d %8d %9d %9d %s",
> +	mvwprintw(handle, y, x, (char*)"%20s %7d %8d %9d %9d %s",
> 		label,
> 		Dbl2Int(stats.min()/scale),
> 		Dbl2Int(stats.mean()/scale), 
> 		Dbl2Int(stats.max()/scale),
> 		Dbl2Int(stats.sum()/scale),
> 		meas);
> }
> 
> void SumWindow::noteAdd(const Host &host) {
> 	Window::noteAdd(host);
> 	update();
> }
> 
> void SumWindow::noteDel(const Host &host) {
> 	Window::noteDel(host);
> 	update();
> }
> 
> void SumWindow::noteUpd(const Host &host) {
> 	Window::noteUpd(host);
> 	update();
> }
> 
> 
> /* SmxWindow */
> 
> SmxWindow::SmxWindow(char const *aTitle): Window(aTitle) {
> 
> -	wattron(this, A_BOLD);
> +	wattron(handle, A_BOLD);
> 
> 	// horizontal lables
> 	for (int i = 0; i < 10; ++i)
> -		mvwprintw(this, 2, Id2X(i), (char*)"%7d", i+1);
> +		mvwprintw(handle, 2, Id2X(i), (char*)"%7d", i+1);
> 
> 	// vertical labels
> 	for (int i = 0; i < 100; i += 10)
> -		mvwprintw(this, Id2Y(i), 0, (char*)"%2d", i);
> +		mvwprintw(handle, Id2Y(i), 0, (char*)"%2d", i);
> 
> -	wattroff(this, A_BOLD);
> +	wattroff(handle, A_BOLD);
> }
> 
> void SmxWindow::noteAdd(const Host &host) {
> 	Window::noteAdd(host);
> 	displayMsg(Host2Y(host), Host2X(host), host.log()[0]);
> }
> 
> void SmxWindow::noteDel(const Host &host) {
> 	Window::noteDel(host);
> 	eraseSlot(Host2Y(host), Host2X(host));
> }
> 
> void SmxWindow::noteUpd(const Host &host) {
> 	Window::noteUpd(host);
> 	displayMsg(Host2Y(host), Host2X(host), host.log()[0]);
> }
> 
> void SmxWindow::eraseSlot(int y, int x) {
> -	mvwprintw(this, y, x, (char*)"%7s ", "");
> +	mvwprintw(handle, y, x, (char*)"%7s ", "");
> }
> 
> int SmxWindow::Host2Y(const Host &host) {
> 	return Id2Y((host.lna() & 255) - 1);
> }
> 
> int SmxWindow::Host2X(const Host &host) {
> 	return Id2X((host.lna() & 255) - 1);
> }
> 
> int SmxWindow::Id2Y(int host_id) {
> 	return TheYMargin + ((host_id % 100) / 10) * TheYCellWidth;
> }
> 
> int SmxWindow::Id2X(int host_id) {
> 	return TheXMargin + (host_id % 10) * TheXCellWidth;
> }
> 
> 
> /* NumxWindow */
> @@ -781,98 +834,98 @@ NumxWindow::NumxWindow(const char *aTitle, const char *aFmt):
> 	update();
> }
> 
> void NumxWindow::noteAdd(const Host &host) {
> 	theNumCnt++;
> 	SmxWindow::noteAdd(host);
> }
> 
> void NumxWindow::noteDel(const Host &host) {
> 	theNumCnt--;
> 	SmxWindow::noteDel(host);
> }
> 
> void NumxWindow::noteUpd(const Host &host) {
> 	SmxWindow::noteUpd(host);
> }
> 
> void NumxWindow::displayMsg(int y, int x, const StatusFwdMsg &msg) {
> 	const double n = msg2num(msg);
> 	theNumSum -= theMatrix(y, x);
> -	mvwprintw(this, y, x, (char*)theFmt, n);
> +	mvwprintw(handle, y, x, (char*)theFmt, n);
> 	theMatrix(y, x) = n;
> 	theNumSum += n;
> 	update();
> }
> 
> void NumxWindow::eraseSlot(int y, int x) {
> 	theNumSum -= theMatrix(y, x);
> 	SmxWindow::eraseSlot(y, x);
> 	theMatrix(y, x) = 0;
> 	update();
> }
> 
> void NumxWindow::update() {
> 	int maxx, maxy;
> -	getmaxyx(this, maxy, maxx);
> +	getmaxyx(handle, maxy, maxx);
> 
>     int y = maxy-1;
> 
> -	wattron(this, A_BOLD);
> -	mvwaddstr(this, y, Id2X(2) + TheXCellWidth-4, (char*)"cnt:");
> -	mvwaddstr(this, y, Id2X(4) + TheXCellWidth-4, (char*)"avg:");
> -	mvwaddstr(this, y, Id2X(6) + TheXCellWidth-4, (char*)"sum:");
> -	wattroff(this, A_BOLD);
> +	wattron(handle, A_BOLD);
> +	mvwaddstr(handle, y, Id2X(2) + TheXCellWidth-4, (char*)"cnt:");
> +	mvwaddstr(handle, y, Id2X(4) + TheXCellWidth-4, (char*)"avg:");
> +	mvwaddstr(handle, y, Id2X(6) + TheXCellWidth-4, (char*)"sum:");
> +	wattroff(handle, A_BOLD);
> 
> -	mvwprintw(this, y, Id2X(3), (char*)"%7d", theNumCnt);
> -	mvwprintw(this, y, Id2X(5), (char*)theFmt, Ratio(theNumSum,theNumCnt));
> -	mvwprintw(this, y, Id2X(7), (char*)theFmt, theNumSum);
> +	mvwprintw(handle, y, Id2X(3), (char*)"%7d", theNumCnt);
> +	mvwprintw(handle, y, Id2X(5), (char*)theFmt, Ratio(theNumSum,theNumCnt));
> +	mvwprintw(handle, y, Id2X(7), (char*)theFmt, theNumSum);
> }
> 
> 
> /* RunTimeSmxWin */
> 
> void RunTimeSmxWin::displayMsg(int y, int x, const StatusFwdMsg &msg) {
> 	const int sec = (msg.theSndTime - msg.theStartTime).sec();
> 	const int min = (sec/60) % 60;
> 	const int hour = sec/3600;
> 	if (hour > 0)
> -		mvwprintw(this, y, x, (char*)"%4d:%02d", hour, min);
> +		mvwprintw(handle, y, x, (char*)"%4d:%02d", hour, min);
> 	else
> -		mvwprintw(this, y, x, (char*)"%4d.%02d", min, sec%60);
> +		mvwprintw(handle, y, x, (char*)"%4d.%02d", min, sec%60);
> }
> 
> 
> /* MsgGapSmxWin */
> 
> void MsgGapSmxWin::noteUpd(const Host &host) {
> 	if (host.log().depth() > 1)
> 		theLastMsg = host.log()[1];
> 	SmxWindow::noteUpd(host);
> }
> 
> void MsgGapSmxWin::displayMsg(int y, int x, const StatusFwdMsg &msg) {
> 	if (theLastMsg.theRcvTime >= 0)
> -		mvwprintw(this, y, x, (char*)"%7d", 
> +		mvwprintw(handle, y, x, (char*)"%7d",
> 			(msg.theRcvTime - theLastMsg.theRcvTime).sec());
> 	else
> -		mvwprintw(this, y, x, (char*)"%7s", "?");
> +		mvwprintw(handle, y, x, (char*)"%7s", "?");
> }
> 
> MsgSum::MsgSum(): theLabels("") {
> }
> 
> MsgSum &MsgSum::operator +=(const StatusFwdMsg &msg) {
> 	/*if (msg.theLabel && !theLabels.str(msg.theLabel)) { // XXX: not sufficient
> 		if (theLabels)
> 			theLabels += ",";
> 		theLabels += msg.theLabel;
> 	}*/
> 
> 	theReqRate.record(Dbl2Int(msg.theReqRate));
> 	theRepRate.record(Dbl2Int(msg.theRepRate));
> 	theBwidth.record(Dbl2Int(msg.theBwidth));
> 	theRespTime.record(msg.theRespTime.msec());
> 	theDHR.record(Dbl2Int(msg.theDHR*100));
> 	theConnUse.record(Dbl2Int(msg.theConnUse));
> 	theErrRatio.record(Dbl2Int(msg.theErrRatio*100));
> 	theXactTotCnt.record(msg.theXactTotCnt);
> @@ -963,40 +1016,43 @@ void DeleteIdleHosts() {
> 		if (Host *host = TheHosts[h]) {
> 			if (host->busy()) {
> 				// XXX pre-IPv6 code used 's_addr' as an int
> 				const int idx = host->addr().addrN().octet(0) % TheHostIdx.count();
> 				TheHostIdx[idx] = host;
> 				if (host->selected())
> 					TheSelHostCnt++;
> 			} else {
> 				TheBusyHostCnt--;
> 				Broadcast(&Window::noteDel, *host);
> 				DelLastLabel(host, host->runLabel());
> 				delete host;
> 				TheHosts[h] = 0;
> 			}
> 		}
> 	}
> }
> 
> static
> bool AddFirstLabel(const Host *skip, const String &l) {
> +	if (!l)
> +		return false; // empty label
> +
> 	for (int h = 0; h < TheHosts.count(); ++h) {
> 		if (TheHosts[h] == skip)
> 			continue;
> 		if (TheHosts[h] && l == TheHosts[h]->runLabel())
> 			return false; // not first label
> 	}
> 	TheUniqLblCnt++;
> 	for (int i = 1; i < TheLabels.count(); ++i) {
> 		if (!*TheLabels[i]) {
> 			*TheLabels[i] = l;
> 			return true;
> 		}
> 	}
> 	TheLabels.append(new String(l));
> 	return false;
> }
> 
> static
> bool DelLastLabel(const Host *skip, const String &l) {
> 	for (int h = 0; h < TheHosts.count(); ++h) {
> @@ -1004,83 +1060,83 @@ bool DelLastLabel(const Host *skip, const String &l) {
> 			continue;
> 		if (TheHosts[h] && l == TheHosts[h]->runLabel())
> 			return false; // not last label
> 	}
> 	TheUniqLblCnt--;
> 	for (int i = 1; i < TheLabels.count(); ++i) {
> 		if (*TheLabels[i] == l) {
> 			*TheLabels[i] = 0;
> 			if (i == TheLabels.count()-1)
> 				delete TheLabels.pop();
> 			return true;
> 		}
> 	}
> 	Assert(0);
> 	return false;
> }
> 
> static
> int SwitchWin(int idx) {
> 	TheWinPos = (idx + TheWins.count()) % TheWins.count();
> -	touchwin(TheWins[TheWinPos]);
> +	touchwin(TheWins[TheWinPos]->handle);
> 	return TheWinPos;
> }
> 
> static
> void SelectHost(Host *host) {
> 	const bool wasSel = host->selected();
> 	const bool isSel = host->matches(TheFilter);
> 	if (!wasSel && isSel) {
> 		host->selected(isSel);
> 		TheSelHostCnt++;
> 		Broadcast(&Window::noteAdd, *host);
> 	} else
> 	if (wasSel && !isSel) {
> 		TheSelHostCnt--;
> 		Broadcast(&Window::noteDel, *host);
> 		host->selected(isSel);
> 	}
> }
> 
> static
> void SelectHosts() {
> 	for (int h = 0; h < TheHosts.count(); ++h) {
> 		if (Host *host = TheHosts[h])
> 			SelectHost(host);
> 	}
> 
> 	// update selection warnings
> 	ofixedstream s(TheFiltWarn, sizeof(TheFiltWarn));
> 	BuildFiltWarn(s);
> 	for (int w = 0; w < TheWins.count(); ++w) {
> 		if (strlen(TheFiltWarn)) {
> -			wattron(TheWins[w], A_BOLD);
> -			mvwaddstr(TheWins[w], 1, 0, (char*)"Filters:");
> -			wattroff(TheWins[w], A_BOLD);
> -			mvwprintw(TheWins[w], 1, 10, (char*)"%-20s", TheFiltWarn);
> +			wattron(TheWins[w]->handle, A_BOLD);
> +			mvwaddstr(TheWins[w]->handle, 1, 0, (char*)"Filters:");
> +			wattroff(TheWins[w]->handle, A_BOLD);
> +			mvwprintw(TheWins[w]->handle, 1, 10, (char*)"%-20s", TheFiltWarn);
> 		} else {
> -			wattroff(TheWins[w], A_BOLD);
> -			mvwprintw(TheWins[w], 1, 0, (char*)"%-30s", "");
> +			wattroff(TheWins[w]->handle, A_BOLD);
> +			mvwprintw(TheWins[w]->handle, 1, 0, (char*)"%-30s", "");
> 		}
> 	}
> 
> -	touchwin(TheWins[TheWinPos]);
> +	touchwin(TheWins[TheWinPos]->handle);
> }
> 
> static
> int SwitchLblFilter(int idx) {
> 	TheFilter.lbl.pos = (idx + TheLabels.count()) % TheLabels.count();
> 
> 	if (TheFilter.lbl.pos)
> 		for (int i = 0; !*TheLabels[TheFilter.lbl.pos] && i < TheLabels.count(); ++i) {
> 			TheFilter.lbl.pos++;
> 			TheFilter.lbl.pos %= TheLabels.count();
> 		}
> 
> 	SelectHosts();
> 	return TheFilter.lbl.pos;
> }
> 
> static
> int SwitchCatFilter(int idx) {
> 	TheFilter.logCat.pos = (idx + lgcEnd) % lgcEnd;
> 	SelectHosts();
> @@ -1138,52 +1194,55 @@ int main(int argc, char *argv[]) {
> 	TheHostIdx.count(TheHostIdx.capacity());
> 	TheLabels.append(new String);
> 
> 	TheWins.append(TheInfoWin = new InfoWindow("Monitor Info"));
> 	TheWins.append(new SumWindow("Summary Information"));
> 	TheWins.append(new RunLabelSmxWin("Experiment Label"));
> 	TheWins.append(new RunTimeSmxWin("Run time [h:m.s]"));
> 	TheWins.append(new ReqRateSmxWin("Load [requests/sec]"));
> 	TheWins.append(new RepRateSmxWin("Throughput [replies/sec]"));
> 	TheWins.append(new BwidthSmxWin("Network Bandwidth [Mbps,replies]"));
> 	TheWins.append(new RespTimeSmxWin("Response Time [msec]"));
> 	TheWins.append(new DHRSmxWin("DHR [%]"));
> 	TheWins.append(new ConnUseSmxWin("Connection Use [xact/conn]"));
> 	TheWins.append(new ErrTotRatioSmxWin("Errors Total [%]"));
> 	TheWins.append(new ErrTotCntSmxWin("Errors Total Count x 1000"));
> 	TheWins.append(new XactTotCntSmxWin("Total Xaction Count x 1000"));
> 	TheWins.append(new ErrRatioSmxWin("Errors Now [%]"));
> 	TheWins.append(new SockInstCntSmxWin("Open Sockets Now"));
> 	TheWins.append(new MsgGapSmxWin("Message Gap [sec]"));
> 
> +	TheHelpWin = new HelpWindow;
> +
> 	signal(SIGPIPE, SIG_IGN);
> 	Clock::Update();
> 
> 	TheScanner = new PG_PREFFERED_FILE_SCANNER;
> 	TheScanner->configure();
> 
> 	MsgMonitor *msgSrv = new MsgMonitor(sock);
> 	KbdMonitor *kbdSrv = new KbdMonitor(0); // XXX: how to get stdin fd?
> 	Ticker *ticker = new Ticker(Time::Sec(60));
> 
> 	SwitchWin(0);
> -	redrawwin(TheWins[TheWinPos]);
> +	wrefresh(TheWins[TheWinPos]->handle);
> 
> 	while (!DoShutdown) {
> 		Clock::Update();
> 		Time tout = TheAlarmClock.on() ? 
> 			TheAlarmClock.timeLeft() : Time();
> 		TheScanner->scan(TheAlarmClock.on() ? 0 : &tout);
> 	}
> 
> 	delete ticker;
> 	delete msgSrv;
> 	delete kbdSrv;
> +	delete TheHelpWin;
> 	delete TheScanner;
> 
> 	endwin();
> 
> 	return 0;
> }
> 
> 
> #endif /* HAVE_NCURSES_H */




More information about the Users mailing list