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