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 18ThreadBarMenu::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 31ThreadBarMenu::~ThreadBarMenu() 32{ 33 free(fThreadsRec); 34 if (gCurrentThreadBarMenu == this) 35 gCurrentThreadBarMenu = NULL; 36} 37 38 39void 40ThreadBarMenu::Init() 41{ 42 int k = 0; 43 while (k < fThreadsRecCount) 44 fThreadsRec[k++].thread = -1; 45 fRound = 1; 46} 47 48 49void 50ThreadBarMenu::Reset(team_id team) 51{ 52 fTeam = team; 53 RemoveItems(0, CountItems(), true); 54 Init(); 55} 56 57 58void 59ThreadBarMenu::AttachedToWindow() 60{ 61 BMenu::AttachedToWindow(); 62} 63 64 65void 66ThreadBarMenu::Draw(BRect r) 67{ 68 gCurrentThreadBarMenu = this; 69 BMenu::Draw(r); 70} 71 72 73void 74ThreadBarMenu::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 119void 120ThreadBarMenu::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