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 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 31 ThreadBarMenu::~ThreadBarMenu() 32 { 33 free(fThreadsRec); 34 if (gCurrentThreadBarMenu == this) 35 gCurrentThreadBarMenu = NULL; 36 } 37 38 39 void 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 50 ThreadBarMenu::Reset(team_id team) 51 { 52 fTeam = team; 53 RemoveItems(0, CountItems(), true); 54 Init(); 55 } 56 57 58 void 59 ThreadBarMenu::AttachedToWindow() 60 { 61 BMenu::AttachedToWindow(); 62 } 63 64 65 void 66 ThreadBarMenu::Draw(BRect r) 67 { 68 gCurrentThreadBarMenu = this; 69 BMenu::Draw(r); 70 } 71 72 73 void 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 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