1 /*
2 * Copyright 2000, Georges-Edouard Berenger. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6 #include "ThreadBarMenu.h"
7
8 #include "PriorityMenu.h"
9 #include "ProcessController.h"
10 #include "ThreadBarMenuItem.h"
11
12 #include <stdlib.h>
13 #include <stdio.h>
14
15 #define EXTRA 20
16
17
ThreadBarMenu(const char * title,team_id team,int32 threadCount)18 ThreadBarMenu::ThreadBarMenu(const char *title, team_id team, int32 threadCount)
19 : BMenu(title),
20 fThreadsRecCount(threadCount + EXTRA),
21 fTeam(team)
22 {
23 SetFont(be_plain_font);
24 fThreadsRec = (ThreadRec*) malloc(sizeof(ThreadRec) * fThreadsRecCount);
25 Init();
26 fRound = 0; // for syslog
27 AddNew();
28 }
29
30
~ThreadBarMenu()31 ThreadBarMenu::~ThreadBarMenu()
32 {
33 free(fThreadsRec);
34 if (gCurrentThreadBarMenu == this)
35 gCurrentThreadBarMenu = NULL;
36 }
37
38
39 void
Init()40 ThreadBarMenu::Init()
41 {
42 int k = 0;
43 while (k < fThreadsRecCount)
44 fThreadsRec[k++].thread = -1;
45 fRound = 1;
46 }
47
48
49 void
Reset(team_id team)50 ThreadBarMenu::Reset(team_id team)
51 {
52 fTeam = team;
53 RemoveItems(0, CountItems(), true);
54 Init();
55 }
56
57
58 void
AttachedToWindow()59 ThreadBarMenu::AttachedToWindow()
60 {
61 BMenu::AttachedToWindow();
62 }
63
64
65 void
Draw(BRect r)66 ThreadBarMenu::Draw(BRect r)
67 {
68 gCurrentThreadBarMenu = this;
69 BMenu::Draw(r);
70 }
71
72
73 void
AddNew()74 ThreadBarMenu::AddNew()
75 {
76 thread_info info;
77 int32 cookie = 0;
78 int32 k = 0;
79 while (get_next_thread_info(fTeam, &cookie, &info) == B_OK) {
80 int lastk = k;
81 while (k < fThreadsRecCount && fThreadsRec[k].thread != info.thread)
82 k++;
83 if (k == fThreadsRecCount) {
84 k = 0;
85 while (k < lastk && fThreadsRec[k].thread != info.thread)
86 k++;
87 if (k == lastk)
88 k = fThreadsRecCount; // flag that the search didn't work.
89 }
90 if (k == fThreadsRecCount) {
91 // printf("*** Thread %d %s/%s, user %lld, kernel %lld\n", info.thread, info.name, info.user_time, info.kernel_time);
92 // this is a new thread...
93 k = 0;
94 while (k < fThreadsRecCount && !(fThreadsRec[k].thread == -1 || fThreadsRec[k].last_round+1 < fRound))
95 k++;
96 if (k == fThreadsRecCount) {
97 fThreadsRecCount += EXTRA;
98 fThreadsRec = (ThreadRec*) realloc(fThreadsRec, sizeof(ThreadRec)*fThreadsRecCount);
99 lastk = k;
100 while (lastk < fThreadsRecCount)
101 fThreadsRec[lastk++].thread = -1;
102 }
103 fThreadsRec[k].thread = info.thread;
104 BMessage* kill_thread = new BMessage('KlTh');
105 kill_thread->AddInt32("thread", info.thread);
106
107 PriorityMenu* prio = new PriorityMenu(info.thread, info.priority);
108 prio->SetFont(be_plain_font);
109 ThreadBarMenuItem* threadbarmenuitem = new ThreadBarMenuItem(info.name, info.thread, prio, kill_thread);
110 threadbarmenuitem->SetTarget(gPCView);
111 AddItem(threadbarmenuitem);
112 }
113 fThreadsRec[k].last_round = fRound;
114 }
115 fRound++;
116 }
117
118
119 void
Update()120 ThreadBarMenu::Update()
121 {
122 AddNew();
123 int32 k, del;
124 del = -1;
125 ThreadBarMenuItem *item;
126
127 for (k = 0; (item = (ThreadBarMenuItem*) ItemAt(k)) != NULL; k++) {
128 item->BarUpdate();
129 item->DrawBar(false);
130 if (item->fKernel < 0) {
131 if (del < 0)
132 del = k;
133 } else if (del >= 0) {
134 RemoveItems(del, k-del, true);
135 k = del;
136 del = -1;
137 }
138 }
139 if (del >= 0)
140 RemoveItems(del, k-del, true);
141 }
142