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