diff --git a/src/bin/debug/profile/BasicThreadProfileResult.cpp b/src/bin/debug/profile/BasicThreadProfileResult.cpp new file mode 100644 index 0000000000..2f1cd7ee57 --- /dev/null +++ b/src/bin/debug/profile/BasicThreadProfileResult.cpp @@ -0,0 +1,305 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "BasicThreadProfileResult.h" + +#include + +#include +#include + +#include "Options.h" + + +struct HitSymbol { + int64 hits; + Symbol* symbol; + + inline bool operator<(const HitSymbol& other) const + { + return hits > other.hits; + } +}; + + +// #pragma mark - BasicThreadImage + + +BasicThreadImage::BasicThreadImage(Image* image) + : + ThreadImage(image), + fSymbolHits(NULL), + fUnknownHits(0) +{ +} + + +BasicThreadImage::~BasicThreadImage() +{ +} + + +status_t +BasicThreadImage::Init() +{ + int32 symbolCount = fImage->SymbolCount(); + fSymbolHits = new(std::nothrow) int64[symbolCount]; + if (fSymbolHits == NULL) + return B_NO_MEMORY; + + memset(fSymbolHits, 0, 8 * symbolCount); + + return B_OK; +} + + +void +BasicThreadImage::AddHit(addr_t address) +{ + int32 symbolIndex = fImage->FindSymbol(address); + if (symbolIndex >= 0) + fSymbolHits[symbolIndex]++; + else + fUnknownHits++; + + fTotalHits++; +} + + +void +BasicThreadImage::AddSymbolHit(int32 symbolIndex) +{ + fSymbolHits[symbolIndex]++; +} + + +void +BasicThreadImage::AddImageHit() +{ + fTotalHits++; +} + + +const int64* +BasicThreadImage::SymbolHits() const +{ + return fSymbolHits; +} + + +int64 +BasicThreadImage::UnknownHits() const +{ + return fUnknownHits; +} + + +// #pragma mark - BasicThreadProfileResult + + +BasicThreadProfileResult::BasicThreadProfileResult() + : + fTotalTicks(0), + fUnkownTicks(0), + fDroppedTicks(0), + fTotalSampleCount(0) +{ +} + + +void +BasicThreadProfileResult::AddDroppedTicks(int32 dropped) +{ + fDroppedTicks += dropped; +} + + +void +BasicThreadProfileResult::PrintResults() +{ + // count images and symbols + int32 imageCount = 0; + int32 symbolCount = 0; + + ImageList::Iterator it = fOldImages.GetIterator(); + while (BasicThreadImage* image = it.Next()) { + if (image->TotalHits() > 0) { + imageCount++; + if (image->TotalHits() > image->UnknownHits()) + symbolCount += image->GetImage()->SymbolCount(); + } + } + + it = fImages.GetIterator(); + while (BasicThreadImage* image = it.Next()) { + if (image->TotalHits() > 0) { + imageCount++; + if (image->TotalHits() > image->UnknownHits()) + symbolCount += image->GetImage()->SymbolCount(); + } + } + + BasicThreadImage* images[imageCount]; + imageCount = 0; + + it = fOldImages.GetIterator(); + while (BasicThreadImage* image = it.Next()) { + if (image->TotalHits() > 0) + images[imageCount++] = image; + } + + it = fImages.GetIterator(); + while (BasicThreadImage* image = it.Next()) { + if (image->TotalHits() > 0) + images[imageCount++] = image; + } + + // find and sort the hit symbols + HitSymbol hitSymbols[symbolCount]; + int32 hitSymbolCount = 0; + + for (int32 k = 0; k < imageCount; k++) { + BasicThreadImage* image = images[k]; + if (image->TotalHits() > image->UnknownHits()) { + Symbol** symbols = image->GetImage()->Symbols(); + const int64* symbolHits = image->SymbolHits(); + int32 imageSymbolCount = image->GetImage()->SymbolCount(); + for (int32 i = 0; i < imageSymbolCount; i++) { + if (symbolHits[i] > 0) { + HitSymbol& hitSymbol = hitSymbols[hitSymbolCount++]; + hitSymbol.hits = symbolHits[i]; + hitSymbol.symbol = symbols[i]; + } + } + } + } + + if (hitSymbolCount > 1) + std::sort(hitSymbols, hitSymbols + hitSymbolCount); + + int64 totalTicks = fTotalTicks; + fprintf(gOptions.output, "\nprofiling results for thread \"%s\" " + "(%ld):\n", fThread->Name(), fThread->ID()); + fprintf(gOptions.output, " tick interval: %lld us\n", fInterval); + fprintf(gOptions.output, " total ticks: %lld (%lld us)\n", + totalTicks, totalTicks * fInterval); + if (totalTicks == 0) + totalTicks = 1; + fprintf(gOptions.output, " unknown ticks: %lld (%lld us, %6.2f%%)\n", + fUnkownTicks, fUnkownTicks * fInterval, + 100.0 * fUnkownTicks / totalTicks); + fprintf(gOptions.output, " dropped ticks: %lld (%lld us, %6.2f%%)\n", + fDroppedTicks, fDroppedTicks * fInterval, + 100.0 * fDroppedTicks / totalTicks); + if (gOptions.analyze_full_stack) { + fprintf(gOptions.output, " samples/tick: %.1f\n", + (double)fTotalSampleCount / totalTicks); + } + + if (imageCount > 0) { + fprintf(gOptions.output, "\n"); + fprintf(gOptions.output, " hits unknown image\n"); + fprintf(gOptions.output, " ---------------------------------------" + "---------------------------------------\n"); + for (int32 k = 0; k < imageCount; k++) { + BasicThreadImage* image = images[k]; + const image_info& imageInfo = image->GetImage()->Info(); + fprintf(gOptions.output, " %10lld %10lld %7ld %s\n", + image->TotalHits(), image->UnknownHits(), imageInfo.id, + imageInfo.name); + } + } + + if (hitSymbolCount > 0) { + fprintf(gOptions.output, "\n"); + fprintf(gOptions.output, " hits in us in %% " + "image function\n"); + fprintf(gOptions.output, " ---------------------------------------" + "---------------------------------------\n"); + for (int32 i = 0; i < hitSymbolCount; i++) { + const HitSymbol& hitSymbol = hitSymbols[i]; + const Symbol* symbol = hitSymbol.symbol; + fprintf(gOptions.output, " %10lld %10lld %6.2f %6ld %s\n", + hitSymbol.hits, hitSymbol.hits * fInterval, + 100.0 * hitSymbol.hits / totalTicks, symbol->image->ID(), + symbol->Name()); + } + } else + fprintf(gOptions.output, " no functions were hit\n"); +} + + +BasicThreadImage* +BasicThreadProfileResult::CreateThreadImage(Image* image) +{ + return new(std::nothrow) BasicThreadImage(image); +} + + +// #pragma mark - InclusiveThreadProfileResult + + +void +InclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +{ + // Sort the samples. This way hits of the same symbol are + // successive and we can avoid incrementing the hit count of the + // same symbol twice. Same for images. + std::sort(samples, samples + sampleCount); + + int32 unknownSamples = 0; + BasicThreadImage* previousImage = NULL; + int32 previousSymbol = -1; + + for (int32 i = 0; i < sampleCount; i++) { + addr_t address = samples[i]; + BasicThreadImage* image = FindImage(address); + int32 symbol = -1; + if (image != NULL) { + symbol = image->GetImage()->FindSymbol(address); + if (symbol < 0) { + // TODO: Count unknown image hits? + } else if (symbol != previousSymbol) + image->AddSymbolHit(symbol); + + if (image != previousImage) + image->AddImageHit(); + } else + unknownSamples++; + + previousImage = image; + previousSymbol = symbol; + } + + if (unknownSamples == sampleCount) + fUnkownTicks++; + + fTotalTicks++; + fTotalSampleCount += sampleCount; +} + + +// #pragma mark - ExclusiveThreadProfileResult + + +void +ExclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +{ + BasicThreadImage* image = NULL; + for (int32 k = 0; k < sampleCount; k++) { + addr_t address = samples[k]; + image = FindImage(address); + if (image != NULL) { + image->AddHit(address); + break; + } + } + + if (image == NULL) + fUnkownTicks++; + + fTotalTicks++; + fTotalSampleCount += sampleCount; +} diff --git a/src/bin/debug/profile/BasicThreadProfileResult.h b/src/bin/debug/profile/BasicThreadProfileResult.h new file mode 100644 index 0000000000..1c0ce319f2 --- /dev/null +++ b/src/bin/debug/profile/BasicThreadProfileResult.h @@ -0,0 +1,64 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef BASIC_THREAD_PROFILE_RESULT_H +#define BASIC_THREAD_PROFILE_RESULT_H + +#include "Thread.h" + + +class BasicThreadImage : public ThreadImage, + public DoublyLinkedListLinkImpl { +public: + BasicThreadImage(Image* image); + virtual ~BasicThreadImage(); + + virtual status_t Init(); + + inline void AddHit(addr_t address); + inline void AddSymbolHit(int32 symbolIndex); + inline void AddImageHit(); + + inline const int64* SymbolHits() const; + inline int64 UnknownHits() const; + +private: + int64* fSymbolHits; + int64 fUnknownHits; +}; + + +class BasicThreadProfileResult + : public AbstractThreadProfileResult { +public: + BasicThreadProfileResult(); + + virtual void AddDroppedTicks(int32 dropped); + virtual void PrintResults(); + + virtual BasicThreadImage* CreateThreadImage(Image* image); + +protected: + int64 fTotalTicks; + int64 fUnkownTicks; + int64 fDroppedTicks; + int64 fTotalSampleCount; +}; + + +class InclusiveThreadProfileResult : public BasicThreadProfileResult { +public: + virtual void AddSamples(addr_t* samples, + int32 sampleCount); +}; + + +class ExclusiveThreadProfileResult : public BasicThreadProfileResult { +public: + virtual void AddSamples(addr_t* samples, + int32 sampleCount); +}; + + +#endif // BASIC_THREAD_PROFILE_RESULT_H diff --git a/src/bin/debug/profile/Jamfile b/src/bin/debug/profile/Jamfile index c1fcc4dfa0..fdf2d5b017 100644 --- a/src/bin/debug/profile/Jamfile +++ b/src/bin/debug/profile/Jamfile @@ -10,6 +10,7 @@ SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; BinCommand profile : + BasicThreadProfileResult.cpp Image.cpp Team.cpp Thread.cpp diff --git a/src/bin/debug/profile/Thread.cpp b/src/bin/debug/profile/Thread.cpp index 1ac2a1bcd7..4381a45d37 100644 --- a/src/bin/debug/profile/Thread.cpp +++ b/src/bin/debug/profile/Thread.cpp @@ -16,106 +16,32 @@ #include "Team.h" -struct HitSymbol { - int64 hits; - Symbol* symbol; - - inline bool operator<(const HitSymbol& other) const - { - return hits > other.hits; - } -}; +// #pragma mark - ThreadImage -class ThreadImage : public DoublyLinkedListLinkImpl { -public: - ThreadImage(Image* image) - : - fImage(image), - fSymbolHits(NULL), - fTotalHits(0), - fUnknownHits(0) - { - fImage->AddReference(); - } - - virtual ~ThreadImage() - { - fImage->RemoveReference(); - } - - status_t Init() - { - int32 symbolCount = fImage->SymbolCount(); - fSymbolHits = new(std::nothrow) int64[symbolCount]; - if (fSymbolHits == NULL) - return B_NO_MEMORY; - - memset(fSymbolHits, 0, 8 * symbolCount); - - return B_OK; - } - - image_id ID() const - { - return fImage->ID(); - } - - bool ContainsAddress(addr_t address) const - { - return fImage->ContainsAddress(address); - } - - void AddHit(addr_t address) - { - int32 symbolIndex = fImage->FindSymbol(address); - if (symbolIndex >= 0) - fSymbolHits[symbolIndex]++; - else - fUnknownHits++; - - fTotalHits++; - } - - void AddSymbolHit(int32 symbolIndex) - { - fSymbolHits[symbolIndex]++; - } - - void AddImageHit() - { - fTotalHits++; - } - - Image* GetImage() const - { - return fImage; - } - - const int64* SymbolHits() const - { - return fSymbolHits; - } - - int64 TotalHits() const - { - return fTotalHits; - } - - int64 UnknownHits() const - { - return fUnknownHits; - } - -private: - Image* fImage; - int64* fSymbolHits; - int64 fTotalHits; - int64 fUnknownHits; -}; +ThreadImage::ThreadImage(Image* image) + : + fImage(image), + fTotalHits(0) +{ + fImage->AddReference(); +} -// #pragma mark - +ThreadImage::~ThreadImage() +{ + fImage->RemoveReference(); +} + + +status_t +ThreadImage::Init() +{ + return B_OK; +} + + +// #pragma mark - Thread Thread::Thread(const thread_info& info, Team* team) @@ -256,291 +182,3 @@ ThreadProfileResult::SetInterval(bigtime_t interval) { fInterval = interval; } - - -// #pragma mark - AbstractThreadProfileResult - - -AbstractThreadProfileResult::AbstractThreadProfileResult() - : - fImages(), - fNewImages(), - fOldImages() -{ -} - - -AbstractThreadProfileResult::~AbstractThreadProfileResult() -{ - while (ThreadImage* image = fImages.RemoveHead()) - delete image; - while (ThreadImage* image = fOldImages.RemoveHead()) - delete image; -} - - -status_t -AbstractThreadProfileResult::AddImage(Image* image) -{ - ThreadImage* threadImage = CreateThreadImage(image); - if (threadImage == NULL) - return B_NO_MEMORY; - - status_t error = threadImage->Init(); - if (error != B_OK) { - delete threadImage; - return error; - } - - fNewImages.Add(threadImage); - - return B_OK; -} - - -void -AbstractThreadProfileResult::SynchronizeImages(int32 event) -{ - // remove obsolete images - ImageList::Iterator it = fImages.GetIterator(); - while (ThreadImage* image = it.Next()) { - int32 deleted = image->GetImage()->DeletionEvent(); - if (deleted >= 0 && event >= deleted) { - it.Remove(); - if (image->TotalHits() > 0) - fOldImages.Add(image); - else - delete image; - } - } - - // add new images - it = fNewImages.GetIterator(); - while (ThreadImage* image = it.Next()) { - if (image->GetImage()->CreationEvent() >= event) { - it.Remove(); - fImages.Add(image); - } - } -} - - -ThreadImage* -AbstractThreadProfileResult::FindImage(addr_t address) const -{ - ImageList::ConstIterator it = fImages.GetIterator(); - while (ThreadImage* image = it.Next()) { - if (image->ContainsAddress(address)) - return image; - } - return NULL; -} - - -// #pragma mark - BasicThreadProfileResult - - -BasicThreadProfileResult::BasicThreadProfileResult() - : - fTotalTicks(0), - fUnkownTicks(0), - fDroppedTicks(0), - fTotalSampleCount(0) -{ -} - - -void -BasicThreadProfileResult::AddDroppedTicks(int32 dropped) -{ - fDroppedTicks += dropped; -} - - -void -BasicThreadProfileResult::PrintResults() -{ - // count images and symbols - int32 imageCount = 0; - int32 symbolCount = 0; - - ImageList::Iterator it = fOldImages.GetIterator(); - while (ThreadImage* image = it.Next()) { - if (image->TotalHits() > 0) { - imageCount++; - if (image->TotalHits() > image->UnknownHits()) - symbolCount += image->GetImage()->SymbolCount(); - } - } - - it = fImages.GetIterator(); - while (ThreadImage* image = it.Next()) { - if (image->TotalHits() > 0) { - imageCount++; - if (image->TotalHits() > image->UnknownHits()) - symbolCount += image->GetImage()->SymbolCount(); - } - } - - ThreadImage* images[imageCount]; - imageCount = 0; - - it = fOldImages.GetIterator(); - while (ThreadImage* image = it.Next()) { - if (image->TotalHits() > 0) - images[imageCount++] = image; - } - - it = fImages.GetIterator(); - while (ThreadImage* image = it.Next()) { - if (image->TotalHits() > 0) - images[imageCount++] = image; - } - - // find and sort the hit symbols - HitSymbol hitSymbols[symbolCount]; - int32 hitSymbolCount = 0; - - for (int32 k = 0; k < imageCount; k++) { - ThreadImage* image = images[k]; - if (image->TotalHits() > image->UnknownHits()) { - Symbol** symbols = image->GetImage()->Symbols(); - const int64* symbolHits = image->SymbolHits(); - int32 imageSymbolCount = image->GetImage()->SymbolCount(); - for (int32 i = 0; i < imageSymbolCount; i++) { - if (symbolHits[i] > 0) { - HitSymbol& hitSymbol = hitSymbols[hitSymbolCount++]; - hitSymbol.hits = symbolHits[i]; - hitSymbol.symbol = symbols[i]; - } - } - } - } - - if (hitSymbolCount > 1) - std::sort(hitSymbols, hitSymbols + hitSymbolCount); - - int64 totalTicks = fTotalTicks; - fprintf(gOptions.output, "\nprofiling results for thread \"%s\" " - "(%ld):\n", fThread->Name(), fThread->ID()); - fprintf(gOptions.output, " tick interval: %lld us\n", fInterval); - fprintf(gOptions.output, " total ticks: %lld (%lld us)\n", - totalTicks, totalTicks * fInterval); - if (totalTicks == 0) - totalTicks = 1; - fprintf(gOptions.output, " unknown ticks: %lld (%lld us, %6.2f%%)\n", - fUnkownTicks, fUnkownTicks * fInterval, - 100.0 * fUnkownTicks / totalTicks); - fprintf(gOptions.output, " dropped ticks: %lld (%lld us, %6.2f%%)\n", - fDroppedTicks, fDroppedTicks * fInterval, - 100.0 * fDroppedTicks / totalTicks); - if (gOptions.analyze_full_stack) { - fprintf(gOptions.output, " samples/tick: %.1f\n", - (double)fTotalSampleCount / totalTicks); - } - - if (imageCount > 0) { - fprintf(gOptions.output, "\n"); - fprintf(gOptions.output, " hits unknown image\n"); - fprintf(gOptions.output, " ---------------------------------------" - "---------------------------------------\n"); - for (int32 k = 0; k < imageCount; k++) { - ThreadImage* image = images[k]; - const image_info& imageInfo = image->GetImage()->Info(); - fprintf(gOptions.output, " %10lld %10lld %7ld %s\n", - image->TotalHits(), image->UnknownHits(), imageInfo.id, - imageInfo.name); - } - } - - if (hitSymbolCount > 0) { - fprintf(gOptions.output, "\n"); - fprintf(gOptions.output, " hits in us in %% " - "image function\n"); - fprintf(gOptions.output, " ---------------------------------------" - "---------------------------------------\n"); - for (int32 i = 0; i < hitSymbolCount; i++) { - const HitSymbol& hitSymbol = hitSymbols[i]; - const Symbol* symbol = hitSymbol.symbol; - fprintf(gOptions.output, " %10lld %10lld %6.2f %6ld %s\n", - hitSymbol.hits, hitSymbol.hits * fInterval, - 100.0 * hitSymbol.hits / totalTicks, symbol->image->ID(), - symbol->Name()); - } - } else - fprintf(gOptions.output, " no functions were hit\n"); -} - - -ThreadImage* -BasicThreadProfileResult::CreateThreadImage(Image* image) -{ - return new(std::nothrow) ThreadImage(image); -} - - -// #pragma mark - InclusiveThreadProfileResult - - -void -InclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) -{ - // Sort the samples. This way hits of the same symbol are - // successive and we can avoid incrementing the hit count of the - // same symbol twice. Same for images. - std::sort(samples, samples + sampleCount); - - int32 unknownSamples = 0; - ThreadImage* previousImage = NULL; - int32 previousSymbol = -1; - - for (int32 i = 0; i < sampleCount; i++) { - addr_t address = samples[i]; - ThreadImage* image = FindImage(address); - int32 symbol = -1; - if (image != NULL) { - symbol = image->GetImage()->FindSymbol(address); - if (symbol < 0) { - // TODO: Count unknown image hits? - } else if (symbol != previousSymbol) - image->AddSymbolHit(symbol); - - if (image != previousImage) - image->AddImageHit(); - } else - unknownSamples++; - - previousImage = image; - previousSymbol = symbol; - } - - if (unknownSamples == sampleCount) - fUnkownTicks++; - - fTotalTicks++; - fTotalSampleCount += sampleCount; -} - - -// #pragma mark - ExclusiveThreadProfileResult - - -void -ExclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) -{ - ThreadImage* image = NULL; - for (int32 k = 0; k < sampleCount; k++) { - addr_t address = samples[k]; - image = FindImage(address); - if (image != NULL) { - image->AddHit(address); - break; - } - } - - if (image == NULL) - fUnkownTicks++; - - fTotalTicks++; - fTotalSampleCount += sampleCount; -} diff --git a/src/bin/debug/profile/Thread.h b/src/bin/debug/profile/Thread.h index 123d37777b..170a18490b 100644 --- a/src/bin/debug/profile/Thread.h +++ b/src/bin/debug/profile/Thread.h @@ -15,6 +15,26 @@ class ThreadImage; class ThreadProfileResult; +class ThreadImage { +public: + ThreadImage(Image* image); + virtual ~ThreadImage(); + + virtual status_t Init(); + + inline image_id ID() const; + inline Image* GetImage() const; + + inline bool ContainsAddress(addr_t address) const; + + inline int64 TotalHits() const; + +protected: + Image* fImage; + int64 fTotalHits; +}; + + class Thread : public DoublyLinkedListLinkImpl { public: Thread(const thread_info& info, Team* team); @@ -75,6 +95,7 @@ protected: }; +template class AbstractThreadProfileResult : public ThreadProfileResult { public: AbstractThreadProfileResult(); @@ -83,17 +104,17 @@ public: virtual status_t AddImage(Image* image); virtual void SynchronizeImages(int32 event); - ThreadImage* FindImage(addr_t address) const; + ThreadImageType* FindImage(addr_t address) const; virtual void AddSamples(addr_t* samples, int32 sampleCount) = 0; virtual void AddDroppedTicks(int32 dropped) = 0; virtual void PrintResults() = 0; - virtual ThreadImage* CreateThreadImage(Image* image) = 0; + virtual ThreadImageType* CreateThreadImage(Image* image) = 0; protected: - typedef DoublyLinkedList ImageList; + typedef DoublyLinkedList ImageList; ImageList fImages; ImageList fNewImages; @@ -101,35 +122,35 @@ protected: }; -class BasicThreadProfileResult : public AbstractThreadProfileResult { -public: - BasicThreadProfileResult(); - - virtual void AddDroppedTicks(int32 dropped); - virtual void PrintResults(); - - virtual ThreadImage* CreateThreadImage(Image* image); - -protected: - int64 fTotalTicks; - int64 fUnkownTicks; - int64 fDroppedTicks; - int64 fTotalSampleCount; -}; +// #pragma mark - -class InclusiveThreadProfileResult : public BasicThreadProfileResult { -public: - virtual void AddSamples(addr_t* samples, - int32 sampleCount); -}; +image_id +ThreadImage::ID() const +{ + return fImage->ID(); +} -class ExclusiveThreadProfileResult : public BasicThreadProfileResult { -public: - virtual void AddSamples(addr_t* samples, - int32 sampleCount); -}; +bool +ThreadImage::ContainsAddress(addr_t address) const +{ + return fImage->ContainsAddress(address); +} + + +Image* +ThreadImage::GetImage() const +{ + return fImage; +} + + +int64 +ThreadImage::TotalHits() const +{ + return fTotalHits; +} // #pragma mark - @@ -170,4 +191,88 @@ Thread::ProfileResult() const } +// #pragma mark - AbstractThreadProfileResult + + +template +AbstractThreadProfileResult::AbstractThreadProfileResult() + : + fImages(), + fNewImages(), + fOldImages() +{ +} + + +template +AbstractThreadProfileResult::~AbstractThreadProfileResult() +{ + while (ThreadImageType* image = fImages.RemoveHead()) + delete image; + while (ThreadImageType* image = fOldImages.RemoveHead()) + delete image; +} + + +template +status_t +AbstractThreadProfileResult::AddImage(Image* image) +{ + ThreadImageType* threadImage = CreateThreadImage(image); + if (threadImage == NULL) + return B_NO_MEMORY; + + status_t error = threadImage->Init(); + if (error != B_OK) { + delete threadImage; + return error; + } + + fNewImages.Add(threadImage); + + return B_OK; +} + + +template +void +AbstractThreadProfileResult::SynchronizeImages(int32 event) +{ + // remove obsolete images + ImageList::Iterator it = fImages.GetIterator(); + while (ThreadImageType* image = it.Next()) { + int32 deleted = image->GetImage()->DeletionEvent(); + if (deleted >= 0 && event >= deleted) { + it.Remove(); + if (image->TotalHits() > 0) + fOldImages.Add(image); + else + delete image; + } + } + + // add new images + it = fNewImages.GetIterator(); + while (ThreadImageType* image = it.Next()) { + if (image->GetImage()->CreationEvent() >= event) { + it.Remove(); + fImages.Add(image); + } + } +} + + +template +ThreadImageType* +AbstractThreadProfileResult::FindImage(addr_t address) const +{ + ImageList::ConstIterator it = fImages.GetIterator(); + while (ThreadImageType* image = it.Next()) { + if (image->ContainsAddress(address)) + return image; + } + return NULL; +} + + #endif // THREAD_H diff --git a/src/bin/debug/profile/profile.cpp b/src/bin/debug/profile/profile.cpp index 293a57cbab..c5bc344dc2 100644 --- a/src/bin/debug/profile/profile.cpp +++ b/src/bin/debug/profile/profile.cpp @@ -23,6 +23,7 @@ #include +#include "BasicThreadProfileResult.h" #include "debug_utils.h" #include "Image.h" #include "Options.h"