/* * Copyright 2000, Georges-Edouard Berenger. All rights reserved. * Distributed under the terms of the MIT License. */ #include "ThreadBarMenu.h" #include "PriorityMenu.h" #include "ProcessController.h" #include "ThreadBarMenuItem.h" #include #include #define EXTRA 20 ThreadBarMenu::ThreadBarMenu(const char *title, team_id team, int32 threadCount) : BMenu(title), fThreadsRecCount(threadCount + EXTRA), fTeam(team) { SetFont(be_plain_font); fThreadsRec = (ThreadRec*) malloc(sizeof(ThreadRec) * fThreadsRecCount); Init(); fRound = 0; // for syslog AddNew(); } ThreadBarMenu::~ThreadBarMenu() { free(fThreadsRec); if (gCurrentThreadBarMenu == this) gCurrentThreadBarMenu = NULL; } void ThreadBarMenu::Init() { int k = 0; while (k < fThreadsRecCount) fThreadsRec[k++].thread = -1; fRound = 1; } void ThreadBarMenu::Reset(team_id team) { fTeam = team; RemoveItems(0, CountItems(), true); Init(); } void ThreadBarMenu::AttachedToWindow() { BMenu::AttachedToWindow(); } void ThreadBarMenu::Draw(BRect r) { gCurrentThreadBarMenu = this; BMenu::Draw(r); } void ThreadBarMenu::AddNew() { thread_info info; int32 cookie = 0; int32 k = 0; while (get_next_thread_info(fTeam, &cookie, &info) == B_OK) { int lastk = k; while (k < fThreadsRecCount && fThreadsRec[k].thread != info.thread) k++; if (k == fThreadsRecCount) { k = 0; while (k < lastk && fThreadsRec[k].thread != info.thread) k++; if (k == lastk) k = fThreadsRecCount; // flag that the search didn't work. } if (k == fThreadsRecCount) { // printf("*** Thread %d %s/%s, user %lld, kernel %lld\n", info.thread, info.name, info.user_time, info.kernel_time); // this is a new thread... k = 0; while (k < fThreadsRecCount && !(fThreadsRec[k].thread == -1 || fThreadsRec[k].last_round+1 < fRound)) k++; if (k == fThreadsRecCount) { fThreadsRecCount += EXTRA; fThreadsRec = (ThreadRec*) realloc(fThreadsRec, sizeof(ThreadRec)*fThreadsRecCount); lastk = k; while (lastk < fThreadsRecCount) fThreadsRec[lastk++].thread = -1; } fThreadsRec[k].thread = info.thread; BMessage* kill_thread = new BMessage('KlTh'); kill_thread->AddInt32("thread", info.thread); PriorityMenu* prio = new PriorityMenu(info.thread, info.priority); prio->SetFont(be_plain_font); ThreadBarMenuItem* threadbarmenuitem = new ThreadBarMenuItem(info.name, info.thread, prio, kill_thread); threadbarmenuitem->SetTarget(gPCView); AddItem(threadbarmenuitem); } fThreadsRec[k].last_round = fRound; } fRound++; } void ThreadBarMenu::Update() { AddNew(); int32 k, del; del = -1; ThreadBarMenuItem *item; for (k = 0; (item = (ThreadBarMenuItem*) ItemAt(k)) != NULL; k++) { item->BarUpdate(); item->DrawBar(false); if (item->fKernel < 0) { if (del < 0) del = k; } else if (del >= 0) { RemoveItems(del, k-del, true); k = del; del = -1; } } if (del >= 0) RemoveItems(del, k-del, true); }