xref: /haiku/src/apps/processcontroller/ThreadBarMenu.cpp (revision ed7a35012e2c301208b3a6b720cf389876f47ac5)
1*ed7a3501SAxel Dörfler /*
2*ed7a3501SAxel Dörfler 
3*ed7a3501SAxel Dörfler 	ThreadBarMenu.cpp
4*ed7a3501SAxel Dörfler 
5*ed7a3501SAxel Dörfler 	ProcessController
6*ed7a3501SAxel Dörfler 	� 2000, Georges-Edouard Berenger, All Rights Reserved.
7*ed7a3501SAxel Dörfler 	Copyright (C) 2004 beunited.org
8*ed7a3501SAxel Dörfler 
9*ed7a3501SAxel Dörfler 	This library is free software; you can redistribute it and/or
10*ed7a3501SAxel Dörfler 	modify it under the terms of the GNU Lesser General Public
11*ed7a3501SAxel Dörfler 	License as published by the Free Software Foundation; either
12*ed7a3501SAxel Dörfler 	version 2.1 of the License, or (at your option) any later version.
13*ed7a3501SAxel Dörfler 
14*ed7a3501SAxel Dörfler 	This library is distributed in the hope that it will be useful,
15*ed7a3501SAxel Dörfler 	but WITHOUT ANY WARRANTY; without even the implied warranty of
16*ed7a3501SAxel Dörfler 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17*ed7a3501SAxel Dörfler 	Lesser General Public License for more details.
18*ed7a3501SAxel Dörfler 
19*ed7a3501SAxel Dörfler 	You should have received a copy of the GNU Lesser General Public
20*ed7a3501SAxel Dörfler 	License along with this library; if not, write to the Free Software
21*ed7a3501SAxel Dörfler 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22*ed7a3501SAxel Dörfler 
23*ed7a3501SAxel Dörfler */
24*ed7a3501SAxel Dörfler 
25*ed7a3501SAxel Dörfler #include "ThreadBarMenu.h"
26*ed7a3501SAxel Dörfler #include "ThreadBarMenuItem.h"
27*ed7a3501SAxel Dörfler #include "PriorityMenu.h"
28*ed7a3501SAxel Dörfler #include "PCView.h"
29*ed7a3501SAxel Dörfler #include <stdlib.h>
30*ed7a3501SAxel Dörfler #include <stdio.h>
31*ed7a3501SAxel Dörfler 
32*ed7a3501SAxel Dörfler #define EXTRA 20
33*ed7a3501SAxel Dörfler 
34*ed7a3501SAxel Dörfler ThreadBarMenu::ThreadBarMenu(const char *title, team_id team, int32 thread_count):
35*ed7a3501SAxel Dörfler 	BMenu(title), fThreadsRecCount(thread_count+EXTRA), fTeam(team)
36*ed7a3501SAxel Dörfler {
37*ed7a3501SAxel Dörfler 	SetFont(be_plain_font);
38*ed7a3501SAxel Dörfler 	fThreadsRec = (ThreadRec*) malloc(sizeof(ThreadRec)*fThreadsRecCount);
39*ed7a3501SAxel Dörfler 	Init();
40*ed7a3501SAxel Dörfler 	fRound = 0;	// for syslog
41*ed7a3501SAxel Dörfler 	AddNew();
42*ed7a3501SAxel Dörfler }
43*ed7a3501SAxel Dörfler 
44*ed7a3501SAxel Dörfler ThreadBarMenu::~ThreadBarMenu()
45*ed7a3501SAxel Dörfler {
46*ed7a3501SAxel Dörfler 	free(fThreadsRec);
47*ed7a3501SAxel Dörfler 	if (gCurrentThreadBarMenu == this)
48*ed7a3501SAxel Dörfler 		gCurrentThreadBarMenu = NULL;
49*ed7a3501SAxel Dörfler }
50*ed7a3501SAxel Dörfler 
51*ed7a3501SAxel Dörfler void ThreadBarMenu::Init()
52*ed7a3501SAxel Dörfler {
53*ed7a3501SAxel Dörfler 	int			k = 0;
54*ed7a3501SAxel Dörfler 	while (k < fThreadsRecCount)
55*ed7a3501SAxel Dörfler 		fThreadsRec[k++].thread = -1;
56*ed7a3501SAxel Dörfler 	fRound = 1;
57*ed7a3501SAxel Dörfler }
58*ed7a3501SAxel Dörfler 
59*ed7a3501SAxel Dörfler void ThreadBarMenu::Reset(team_id team)
60*ed7a3501SAxel Dörfler {
61*ed7a3501SAxel Dörfler 	fTeam = team;
62*ed7a3501SAxel Dörfler 	RemoveItems(0, CountItems(), true);
63*ed7a3501SAxel Dörfler 	Init();
64*ed7a3501SAxel Dörfler }
65*ed7a3501SAxel Dörfler 
66*ed7a3501SAxel Dörfler void ThreadBarMenu::AttachedToWindow()
67*ed7a3501SAxel Dörfler {
68*ed7a3501SAxel Dörfler 	BMenu::AttachedToWindow();
69*ed7a3501SAxel Dörfler }
70*ed7a3501SAxel Dörfler 
71*ed7a3501SAxel Dörfler void ThreadBarMenu::Draw(BRect r)
72*ed7a3501SAxel Dörfler {
73*ed7a3501SAxel Dörfler 	gCurrentThreadBarMenu = this;
74*ed7a3501SAxel Dörfler 	BMenu::Draw(r);
75*ed7a3501SAxel Dörfler }
76*ed7a3501SAxel Dörfler 
77*ed7a3501SAxel Dörfler void ThreadBarMenu::AddNew()
78*ed7a3501SAxel Dörfler {
79*ed7a3501SAxel Dörfler 	thread_info	info;
80*ed7a3501SAxel Dörfler 	int32 		cookie = 0;
81*ed7a3501SAxel Dörfler 	int32		k = 0;
82*ed7a3501SAxel Dörfler 	while (get_next_thread_info(fTeam, &cookie, &info) == B_OK) {
83*ed7a3501SAxel Dörfler 		int	lastk = k;
84*ed7a3501SAxel Dörfler 		while (k < fThreadsRecCount && fThreadsRec[k].thread != info.thread)
85*ed7a3501SAxel Dörfler 			k++;
86*ed7a3501SAxel Dörfler 		if (k == fThreadsRecCount) {
87*ed7a3501SAxel Dörfler 			k = 0;
88*ed7a3501SAxel Dörfler 			while (k < lastk && fThreadsRec[k].thread != info.thread)
89*ed7a3501SAxel Dörfler 				k++;
90*ed7a3501SAxel Dörfler 			if (k == lastk)
91*ed7a3501SAxel Dörfler 				k = fThreadsRecCount; // flag that the search didn't work.
92*ed7a3501SAxel Dörfler 		}
93*ed7a3501SAxel Dörfler 		if (k == fThreadsRecCount) {
94*ed7a3501SAxel Dörfler //			printf("*** Thread %d %s/%s, user %Ld, kernel %Ld\n", info.thread, info.name, info.user_time, info.kernel_time);
95*ed7a3501SAxel Dörfler 			// this is a new thread...
96*ed7a3501SAxel Dörfler 			k = 0;
97*ed7a3501SAxel Dörfler 			while (k < fThreadsRecCount && !(fThreadsRec[k].thread == -1 || fThreadsRec[k].last_round+1 < fRound))
98*ed7a3501SAxel Dörfler 				k++;
99*ed7a3501SAxel Dörfler 			if (k == fThreadsRecCount) {
100*ed7a3501SAxel Dörfler 				fThreadsRecCount += EXTRA;
101*ed7a3501SAxel Dörfler 				fThreadsRec = (ThreadRec*) realloc(fThreadsRec, sizeof(ThreadRec)*fThreadsRecCount);
102*ed7a3501SAxel Dörfler 				lastk = k;
103*ed7a3501SAxel Dörfler 				while (lastk < fThreadsRecCount)
104*ed7a3501SAxel Dörfler 					fThreadsRec[lastk++].thread = -1;
105*ed7a3501SAxel Dörfler 			}
106*ed7a3501SAxel Dörfler 			fThreadsRec[k].thread = info.thread;
107*ed7a3501SAxel Dörfler 			BMessage* kill_thread = new BMessage('KlTh');
108*ed7a3501SAxel Dörfler 			kill_thread->AddInt32("thread", info.thread);
109*ed7a3501SAxel Dörfler 
110*ed7a3501SAxel Dörfler 			PriorityMenu* prio = new PriorityMenu(info.thread, info.priority);
111*ed7a3501SAxel Dörfler 			prio->SetFont(be_plain_font);
112*ed7a3501SAxel Dörfler 			ThreadBarMenuItem* threadbarmenuitem = new ThreadBarMenuItem(info.name, info.thread, prio, kill_thread);
113*ed7a3501SAxel Dörfler 			threadbarmenuitem->SetTarget(gPCView);
114*ed7a3501SAxel Dörfler 			AddItem(threadbarmenuitem);
115*ed7a3501SAxel Dörfler 		}
116*ed7a3501SAxel Dörfler 		fThreadsRec[k].last_round = fRound;
117*ed7a3501SAxel Dörfler 	}
118*ed7a3501SAxel Dörfler 	fRound++;
119*ed7a3501SAxel Dörfler }
120*ed7a3501SAxel Dörfler 
121*ed7a3501SAxel Dörfler void ThreadBarMenu::Update()
122*ed7a3501SAxel Dörfler {
123*ed7a3501SAxel Dörfler 	AddNew();
124*ed7a3501SAxel Dörfler 	int32	k, del;
125*ed7a3501SAxel Dörfler 	del = -1;
126*ed7a3501SAxel Dörfler 	ThreadBarMenuItem *item;
127*ed7a3501SAxel Dörfler 	for (k = 0; (item = (ThreadBarMenuItem*) ItemAt(k)) != NULL; k++) {
128*ed7a3501SAxel Dörfler 		item->BarUpdate();
129*ed7a3501SAxel Dörfler 		item->DrawBar(false);
130*ed7a3501SAxel Dörfler 		if (item->fKernel < 0) {
131*ed7a3501SAxel Dörfler 			if (del < 0)
132*ed7a3501SAxel Dörfler 				del = k;
133*ed7a3501SAxel Dörfler 		} else if (del >= 0) {
134*ed7a3501SAxel Dörfler 			RemoveItems(del, k-del, true);
135*ed7a3501SAxel Dörfler 			k = del;
136*ed7a3501SAxel Dörfler 			del = -1;
137*ed7a3501SAxel Dörfler 		}
138*ed7a3501SAxel Dörfler 	}
139*ed7a3501SAxel Dörfler 	if (del >= 0)
140*ed7a3501SAxel Dörfler 		RemoveItems(del, k-del, true);
141*ed7a3501SAxel Dörfler }
142