diff --git a/src/bin/debug/profile/BasicThreadProfileResult.cpp b/src/bin/debug/profile/BasicProfileResult.cpp similarity index 75% rename from src/bin/debug/profile/BasicThreadProfileResult.cpp rename to src/bin/debug/profile/BasicProfileResult.cpp index 03a9ac2dc7..c6458aec83 100644 --- a/src/bin/debug/profile/BasicThreadProfileResult.cpp +++ b/src/bin/debug/profile/BasicProfileResult.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ -#include "BasicThreadProfileResult.h" + +#include "BasicProfileResult.h" #include @@ -11,6 +12,7 @@ #include #include "Options.h" +#include "ProfiledEntity.h" struct HitSymbol { @@ -25,25 +27,25 @@ struct HitSymbol { }; -// #pragma mark - BasicThreadImage +// #pragma mark - BasicProfileResultImage -BasicThreadImage::BasicThreadImage(Image* image) +BasicProfileResultImage::BasicProfileResultImage(Image* image) : - ThreadImage(image), + ProfileResultImage(image), fSymbolHits(NULL), fUnknownHits(0) { } -BasicThreadImage::~BasicThreadImage() +BasicProfileResultImage::~BasicProfileResultImage() { } status_t -BasicThreadImage::Init() +BasicProfileResultImage::Init() { int32 symbolCount = fImage->SymbolCount(); fSymbolHits = new(std::nothrow) int64[symbolCount]; @@ -57,7 +59,7 @@ BasicThreadImage::Init() bool -BasicThreadImage::AddHit(addr_t address) +BasicProfileResultImage::AddHit(addr_t address) { int32 symbolIndex = fImage->FindSymbol(address); if (symbolIndex < 0) @@ -71,7 +73,7 @@ BasicThreadImage::AddHit(addr_t address) void -BasicThreadImage::AddUnknownHit() +BasicProfileResultImage::AddUnknownHit() { fUnknownHits++; fTotalHits++; @@ -79,37 +81,37 @@ BasicThreadImage::AddUnknownHit() void -BasicThreadImage::AddSymbolHit(int32 symbolIndex) +BasicProfileResultImage::AddSymbolHit(int32 symbolIndex) { fSymbolHits[symbolIndex]++; } void -BasicThreadImage::AddImageHit() +BasicProfileResultImage::AddImageHit() { fTotalHits++; } const int64* -BasicThreadImage::SymbolHits() const +BasicProfileResultImage::SymbolHits() const { return fSymbolHits; } int64 -BasicThreadImage::UnknownHits() const +BasicProfileResultImage::UnknownHits() const { return fUnknownHits; } -// #pragma mark - BasicThreadProfileResult +// #pragma mark - BasicProfileResult -BasicThreadProfileResult::BasicThreadProfileResult() +BasicProfileResult::BasicProfileResult() : fTotalTicks(0), fUnkownTicks(0), @@ -120,23 +122,23 @@ BasicThreadProfileResult::BasicThreadProfileResult() void -BasicThreadProfileResult::AddDroppedTicks(int32 dropped) +BasicProfileResult::AddDroppedTicks(int32 dropped) { fDroppedTicks += dropped; } void -BasicThreadProfileResult::PrintResults() +BasicProfileResult::PrintResults() { // get hit images - BasicThreadImage* images[fOldImages.Count() + fImages.Count()]; + BasicProfileResultImage* images[fOldImages.Count() + fImages.Count()]; int32 imageCount = GetHitImages(images); // count symbols int32 symbolCount = 0; for (int32 k = 0; k < imageCount; k++) { - BasicThreadImage* image = images[k]; + BasicProfileResultImage* image = images[k]; if (image->TotalHits() > image->UnknownHits()) symbolCount += image->GetImage()->SymbolCount(); } @@ -146,7 +148,7 @@ BasicThreadProfileResult::PrintResults() int32 hitSymbolCount = 0; for (int32 k = 0; k < imageCount; k++) { - BasicThreadImage* image = images[k]; + BasicProfileResultImage* image = images[k]; if (image->TotalHits() > image->UnknownHits()) { Symbol** symbols = image->GetImage()->Symbols(); const int64* symbolHits = image->SymbolHits(); @@ -166,8 +168,9 @@ BasicThreadProfileResult::PrintResults() 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, "\nprofiling results for %s \"%s\" " + "(%" B_PRId32 "):\n", fEntity->EntityType(), fEntity->EntityName(), + fEntity->EntityID()); fprintf(gOptions.output, " tick interval: %lld us\n", fInterval); fprintf(gOptions.output, " total ticks: %lld (%lld us)\n", totalTicks, totalTicks * fInterval); @@ -190,7 +193,7 @@ BasicThreadProfileResult::PrintResults() fprintf(gOptions.output, " ---------------------------------------" "---------------------------------------\n"); for (int32 k = 0; k < imageCount; k++) { - BasicThreadImage* image = images[k]; + BasicProfileResultImage* image = images[k]; fprintf(gOptions.output, " %10lld %10lld %7ld %s\n", image->TotalHits(), image->UnknownHits(), image->GetImage()->ID(), image->GetImage()->Name()); @@ -216,18 +219,18 @@ BasicThreadProfileResult::PrintResults() } -BasicThreadImage* -BasicThreadProfileResult::CreateThreadImage(Image* image) +BasicProfileResultImage* +BasicProfileResult::CreateProfileResultImage(Image* image) { - return new(std::nothrow) BasicThreadImage(image); + return new(std::nothrow) BasicProfileResultImage(image); } -// #pragma mark - InclusiveThreadProfileResult +// #pragma mark - InclusiveProfileResult void -InclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +InclusiveProfileResult::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 @@ -235,12 +238,12 @@ InclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) std::sort(samples, samples + sampleCount); int32 unknownSamples = 0; - BasicThreadImage* previousImage = NULL; + BasicProfileResultImage* previousImage = NULL; int32 previousSymbol = -1; for (int32 i = 0; i < sampleCount; i++) { addr_t address = samples[i]; - BasicThreadImage* image = FindImage(address); + BasicProfileResultImage* image = FindImage(address); int32 symbol = -1; if (image != NULL) { symbol = image->GetImage()->FindSymbol(address); @@ -266,15 +269,15 @@ InclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) } -// #pragma mark - ExclusiveThreadProfileResult +// #pragma mark - ExclusiveProfileResult void -ExclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +ExclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount) { - BasicThreadImage* image = NULL; + BasicProfileResultImage* image = NULL; // the image in which we hit a symbol - BasicThreadImage* firstImage = NULL; + BasicProfileResultImage* firstImage = NULL; // the first image we hit, != image if no symbol was hit for (int32 k = 0; k < sampleCount; k++) { diff --git a/src/bin/debug/profile/BasicThreadProfileResult.h b/src/bin/debug/profile/BasicProfileResult.h similarity index 53% rename from src/bin/debug/profile/BasicThreadProfileResult.h rename to src/bin/debug/profile/BasicProfileResult.h index 77c8b33108..76bb0042ac 100644 --- a/src/bin/debug/profile/BasicThreadProfileResult.h +++ b/src/bin/debug/profile/BasicProfileResult.h @@ -1,18 +1,19 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, 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" +#ifndef BASIC_PROFILE_RESULT_H +#define BASIC_PROFILE_RESULT_H -class BasicThreadImage : public ThreadImage, - public DoublyLinkedListLinkImpl { +#include "ProfileResult.h" + + +class BasicProfileResultImage : public ProfileResultImage, + public DoublyLinkedListLinkImpl { public: - BasicThreadImage(Image* image); - virtual ~BasicThreadImage(); + BasicProfileResultImage(Image* image); + virtual ~BasicProfileResultImage(); virtual status_t Init(); @@ -30,15 +31,15 @@ private: }; -class BasicThreadProfileResult - : public AbstractThreadProfileResult { +class BasicProfileResult + : public AbstractProfileResult { public: - BasicThreadProfileResult(); + BasicProfileResult(); virtual void AddDroppedTicks(int32 dropped); virtual void PrintResults(); - virtual BasicThreadImage* CreateThreadImage(Image* image); + virtual BasicProfileResultImage* CreateProfileResultImage(Image* image); protected: int64 fTotalTicks; @@ -48,18 +49,18 @@ protected: }; -class InclusiveThreadProfileResult : public BasicThreadProfileResult { +class InclusiveProfileResult : public BasicProfileResult { public: virtual void AddSamples(addr_t* samples, int32 sampleCount); }; -class ExclusiveThreadProfileResult : public BasicThreadProfileResult { +class ExclusiveProfileResult : public BasicProfileResult { public: virtual void AddSamples(addr_t* samples, int32 sampleCount); }; -#endif // BASIC_THREAD_PROFILE_RESULT_H +#endif // BASIC_PROFILE_RESULT_H diff --git a/src/bin/debug/profile/CallgrindThreadProfileResult.cpp b/src/bin/debug/profile/CallgrindProfileResult.cpp similarity index 75% rename from src/bin/debug/profile/CallgrindThreadProfileResult.cpp rename to src/bin/debug/profile/CallgrindProfileResult.cpp index e38b45931c..a1636ce3c4 100644 --- a/src/bin/debug/profile/CallgrindThreadProfileResult.cpp +++ b/src/bin/debug/profile/CallgrindProfileResult.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ -#include "CallgrindThreadProfileResult.h" + +#include "CallgrindProfileResult.h" #include #include @@ -12,21 +13,22 @@ #include #include "Options.h" +#include "ProfiledEntity.h" -// #pragma mark - CallgrindThreadImage +// #pragma mark - CallgrindProfileResultImage -CallgrindThreadImage::CallgrindThreadImage(Image* image) +CallgrindProfileResultImage::CallgrindProfileResultImage(Image* image) : - ThreadImage(image), + ProfileResultImage(image), fFunctions(NULL), fOutputIndex(0) { } -CallgrindThreadImage::~CallgrindThreadImage() +CallgrindProfileResultImage::~CallgrindProfileResultImage() { int32 symbolCount = fImage->SymbolCount(); for (int32 i = 0; i < symbolCount; i++) { @@ -42,7 +44,7 @@ CallgrindThreadImage::~CallgrindThreadImage() status_t -CallgrindThreadImage::Init() +CallgrindProfileResultImage::Init() { int32 symbolCount = fImage->SymbolCount(); fFunctions = new(std::nothrow) CallgrindFunction[symbolCount]; @@ -56,8 +58,8 @@ CallgrindThreadImage::Init() void -CallgrindThreadImage::AddSymbolHit(int32 symbolIndex, - CallgrindThreadImage* calledImage, int32 calledSymbol) +CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex, + CallgrindProfileResultImage* calledImage, int32 calledSymbol) { fTotalHits++; @@ -92,30 +94,30 @@ CallgrindThreadImage::AddSymbolHit(int32 symbolIndex, CallgrindFunction* -CallgrindThreadImage::Functions() const +CallgrindProfileResultImage::Functions() const { return fFunctions; } int32 -CallgrindThreadImage::OutputIndex() const +CallgrindProfileResultImage::OutputIndex() const { return fOutputIndex; } void -CallgrindThreadImage::SetOutputIndex(int32 index) +CallgrindProfileResultImage::SetOutputIndex(int32 index) { fOutputIndex = index; } -// #pragma mark - CallgrindThreadProfileResult +// #pragma mark - CallgrindProfileResult -CallgrindThreadProfileResult::CallgrindThreadProfileResult() +CallgrindProfileResult::CallgrindProfileResult() : fTotalTicks(0), fUnkownTicks(0), @@ -127,16 +129,16 @@ CallgrindThreadProfileResult::CallgrindThreadProfileResult() void -CallgrindThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +CallgrindProfileResult::AddSamples(addr_t* samples, int32 sampleCount) { int32 unknownSamples = 0; - CallgrindThreadImage* previousImage = NULL; + CallgrindProfileResultImage* previousImage = NULL; int32 previousSymbol = -1; // TODO: That probably doesn't work with recursive functions. for (int32 i = 0; i < sampleCount; i++) { addr_t address = samples[i]; - CallgrindThreadImage* image = FindImage(address); + CallgrindProfileResultImage* image = FindImage(address); int32 symbol = -1; if (image != NULL) { symbol = image->GetImage()->FindSymbol(address); @@ -157,31 +159,31 @@ CallgrindThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) void -CallgrindThreadProfileResult::AddDroppedTicks(int32 dropped) +CallgrindProfileResult::AddDroppedTicks(int32 dropped) { fDroppedTicks += dropped; } void -CallgrindThreadProfileResult::PrintResults() +CallgrindProfileResult::PrintResults() { // create output file // create output dir mkdir(gOptions.callgrind_directory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - // get the thread name and replace slashes by hyphens - char threadName[B_OS_NAME_LENGTH]; - strlcpy(threadName, fThread->Name(), sizeof(threadName)); - char* slash = threadName; + // get the entity name and replace slashes by hyphens + char entityName[B_OS_NAME_LENGTH]; + strlcpy(entityName, fEntity->EntityName(), sizeof(entityName)); + char* slash = entityName; while ((slash = strchr(slash, '/')) != NULL) *slash = '-'; // create the file name char fileName[B_PATH_NAME_LENGTH]; snprintf(fileName, sizeof(fileName), "%s/callgrind.out.%ld.%s.%lldms", - gOptions.callgrind_directory, fThread->ID(), threadName, + gOptions.callgrind_directory, fEntity->EntityID(), entityName, fTotalTicks * fInterval); // create the file @@ -195,8 +197,8 @@ CallgrindThreadProfileResult::PrintResults() // write the header fprintf(out, "version: 1\n"); fprintf(out, "creator: Haiku profile\n"); - fprintf(out, "pid: %ld\n", fThread->ID()); - fprintf(out, "cmd: %s\n", fThread->Name()); + fprintf(out, "pid: %ld\n", fEntity->EntityID()); + fprintf(out, "cmd: %s\n", fEntity->EntityName()); fprintf(out, "part: 1\n\n"); fprintf(out, "positions: line\n"); @@ -204,11 +206,11 @@ CallgrindThreadProfileResult::PrintResults() fprintf(out, "summary: %lld %lld\n", fTotalTicks, fTotalTicks * fInterval); // get hit images - CallgrindThreadImage* images[fOldImages.Count() + fImages.Count()]; + CallgrindProfileResultImage* images[fOldImages.Count() + fImages.Count()]; int32 imageCount = GetHitImages(images); for (int32 i = 0; i < imageCount; i++) { - CallgrindThreadImage* image = images[i]; + CallgrindProfileResultImage* image = images[i]; CallgrindFunction* functions = image->Functions(); int32 imageSymbolCount = image->GetImage()->SymbolCount(); @@ -255,16 +257,16 @@ CallgrindThreadProfileResult::PrintResults() } -CallgrindThreadImage* -CallgrindThreadProfileResult::CreateThreadImage(Image* image) +CallgrindProfileResultImage* +CallgrindProfileResult::CreateProfileResultImage(Image* image) { - return new(std::nothrow) CallgrindThreadImage(image); + return new(std::nothrow) CallgrindProfileResultImage(image); } void -CallgrindThreadProfileResult::_PrintFunction(FILE* out, - CallgrindThreadImage* image, int32 functionIndex, bool called) +CallgrindProfileResult::_PrintFunction(FILE* out, + CallgrindProfileResultImage* image, int32 functionIndex, bool called) { if (image->OutputIndex() == 0) { // need to print the image name diff --git a/src/bin/debug/profile/CallgrindThreadProfileResult.h b/src/bin/debug/profile/CallgrindProfileResult.h similarity index 53% rename from src/bin/debug/profile/CallgrindThreadProfileResult.h rename to src/bin/debug/profile/CallgrindProfileResult.h index 74f28cbc0c..6ecfdc103b 100644 --- a/src/bin/debug/profile/CallgrindThreadProfileResult.h +++ b/src/bin/debug/profile/CallgrindProfileResult.h @@ -1,25 +1,26 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ -#ifndef CALLGRIND_THREAD_PROFILE_RESULT_H -#define CALLGRIND_THREAD_PROFILE_RESULT_H +#ifndef CALLGRIND_PROFILE_RESULT_H +#define CALLGRIND_PROFILE_RESULT_H + #include -#include "Thread.h" +#include "ProfileResult.h" -class CallgrindThreadImage; +class CallgrindProfileResultImage; struct CallgrindCalledFunction { - CallgrindCalledFunction* next; - CallgrindThreadImage* image; - int32 function; - int64 hits; + CallgrindCalledFunction* next; + CallgrindProfileResultImage* image; + int32 function; + int64 hits; - CallgrindCalledFunction(CallgrindThreadImage* image, int32 function) + CallgrindCalledFunction(CallgrindProfileResultImage* image, int32 function) : next(NULL), image(image), @@ -38,16 +39,16 @@ struct CallgrindFunction { }; -class CallgrindThreadImage : public ThreadImage, - public DoublyLinkedListLinkImpl { +class CallgrindProfileResultImage : public ProfileResultImage, + public DoublyLinkedListLinkImpl { public: - CallgrindThreadImage(Image* image); - virtual ~CallgrindThreadImage(); + CallgrindProfileResultImage(Image* image); + virtual ~CallgrindProfileResultImage(); virtual status_t Init(); inline void AddSymbolHit(int32 symbolIndex, - CallgrindThreadImage* calledImage, + CallgrindProfileResultImage* calledImage, int32 calledSymbol); inline CallgrindFunction* Functions() const; @@ -61,21 +62,21 @@ private: }; -class CallgrindThreadProfileResult - : public AbstractThreadProfileResult { +class CallgrindProfileResult + : public AbstractProfileResult { public: - CallgrindThreadProfileResult(); + CallgrindProfileResult(); virtual void AddSamples(addr_t* samples, int32 sampleCount); virtual void AddDroppedTicks(int32 dropped); virtual void PrintResults(); - virtual CallgrindThreadImage* CreateThreadImage(Image* image); + virtual CallgrindProfileResultImage* CreateProfileResultImage(Image* image); private: void _PrintFunction(FILE* out, - CallgrindThreadImage* image, + CallgrindProfileResultImage* image, int32 functionIndex, bool called); private: int64 fTotalTicks; @@ -86,4 +87,4 @@ private: }; -#endif // CALLGRIND_THREAD_PROFILE_RESULT_H +#endif // CALLGRIND_PROFILE_RESULT_H diff --git a/src/bin/debug/profile/Jamfile b/src/bin/debug/profile/Jamfile index 72d47fba64..6b88df472a 100644 --- a/src/bin/debug/profile/Jamfile +++ b/src/bin/debug/profile/Jamfile @@ -10,9 +10,11 @@ SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; BinCommand profile : - BasicThreadProfileResult.cpp - CallgrindThreadProfileResult.cpp + BasicProfileResult.cpp + CallgrindProfileResult.cpp Image.cpp + ProfiledEntity.cpp + ProfileResult.cpp SharedImage.cpp Team.cpp Thread.cpp diff --git a/src/bin/debug/profile/ProfileResult.cpp b/src/bin/debug/profile/ProfileResult.cpp new file mode 100644 index 0000000000..e7658dc2fe --- /dev/null +++ b/src/bin/debug/profile/ProfileResult.cpp @@ -0,0 +1,63 @@ +/* + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "ProfileResult.h" + + +// #pragma mark - ProfileResultImage + + +ProfileResultImage::ProfileResultImage(Image* image) + : + fImage(image), + fTotalHits(0) +{ + fImage->AddReference(); +} + + +ProfileResultImage::~ProfileResultImage() +{ + fImage->RemoveReference(); +} + + +status_t +ProfileResultImage::Init() +{ + return B_OK; +} + + +// #pragma mark - ProfileResult + + +ProfileResult::ProfileResult() + : + fEntity(NULL), + fInterval(1) +{ +} + + +ProfileResult::~ProfileResult() +{ +} + + +status_t +ProfileResult::Init(ProfiledEntity* entity) +{ + fEntity = entity; + return B_OK; +} + + +void +ProfileResult::SetInterval(bigtime_t interval) +{ + fInterval = interval; +} diff --git a/src/bin/debug/profile/ProfileResult.h b/src/bin/debug/profile/ProfileResult.h new file mode 100644 index 0000000000..7df8306075 --- /dev/null +++ b/src/bin/debug/profile/ProfileResult.h @@ -0,0 +1,265 @@ +/* + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef PROFILE_RESULT_H +#define PROFILE_RESULT_H + + +#include + +#include "Image.h" + + +class ProfiledEntity; +class Team; + + +class ProfileResultImage { +public: + ProfileResultImage(Image* image); + virtual ~ProfileResultImage(); + + 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 ProfileResult { +public: + ProfileResult(); + virtual ~ProfileResult(); + + virtual status_t Init(ProfiledEntity* entity); + + void SetInterval(bigtime_t interval); + + virtual void SetLazyImages(bool lazy) = 0; + + virtual status_t AddImage(Image* image) = 0; + virtual void RemoveImage(Image* image) = 0; + virtual void SynchronizeImages(int32 event) = 0; + + virtual void AddSamples(addr_t* samples, + int32 sampleCount) = 0; + virtual void AddDroppedTicks(int32 dropped) = 0; + virtual void PrintResults() = 0; + +protected: + ProfiledEntity* fEntity; + bigtime_t fInterval; +}; + + +template +class AbstractProfileResult : public ProfileResult { +public: + AbstractProfileResult(); + virtual ~AbstractProfileResult(); + + virtual void SetLazyImages(bool lazy); + + virtual status_t AddImage(Image* image); + virtual void RemoveImage(Image* image); + virtual void SynchronizeImages(int32 event); + + ProfileResultImageType* FindImage(addr_t address) const; + int32 GetHitImages( + ProfileResultImageType** images) const; + + virtual ProfileResultImageType* CreateProfileResultImage(Image* image) = 0; + +protected: + typedef DoublyLinkedList ImageList; + + ImageList fImages; + ImageList fNewImages; + ImageList fOldImages; + bool fLazyImages; +}; + + +// #pragma mark - + + +image_id +ProfileResultImage::ID() const +{ + return fImage->ID(); +} + + +bool +ProfileResultImage::ContainsAddress(addr_t address) const +{ + return fImage->ContainsAddress(address); +} + + +Image* +ProfileResultImage::GetImage() const +{ + return fImage; +} + + +int64 +ProfileResultImage::TotalHits() const +{ + return fTotalHits; +} + + +// #pragma mark - AbstractProfileResult + + +template +AbstractProfileResult::AbstractProfileResult() + : + fImages(), + fNewImages(), + fOldImages(), + fLazyImages(true) +{ +} + + +template +AbstractProfileResult::~AbstractProfileResult() +{ + while (ProfileResultImageType* image = fImages.RemoveHead()) + delete image; + while (ProfileResultImageType* image = fOldImages.RemoveHead()) + delete image; +} + + +template +void +AbstractProfileResult::SetLazyImages(bool lazy) +{ + fLazyImages = lazy; +} + + +template +status_t +AbstractProfileResult::AddImage(Image* image) +{ + ProfileResultImageType* resultImage = CreateProfileResultImage(image); + if (resultImage == NULL) + return B_NO_MEMORY; + + status_t error = resultImage->Init(); + if (error != B_OK) { + delete resultImage; + return error; + } + + if (fLazyImages) + fNewImages.Add(resultImage); + else + fImages.Add(resultImage); + + return B_OK; +} + + +template +void +AbstractProfileResult::RemoveImage(Image* image) +{ + typename ImageList::Iterator it = fImages.GetIterator(); + while (ProfileResultImageType* resultImage = it.Next()) { + if (resultImage->GetImage() == image) { + it.Remove(); + if (resultImage->TotalHits() > 0) + fOldImages.Add(resultImage); + else + delete resultImage; + break; + } + } +} + + +template +void +AbstractProfileResult::SynchronizeImages(int32 event) +{ + // remove obsolete images + typename ImageList::Iterator it = fImages.GetIterator(); + while (ProfileResultImageType* 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 (ProfileResultImageType* image = it.Next()) { + if (image->GetImage()->CreationEvent() <= event) { + it.Remove(); + int32 deleted = image->GetImage()->DeletionEvent(); + if (deleted >= 0 && event >= deleted) { + // image already deleted + delete image; + } else + fImages.Add(image); + } + } +} + + +template +ProfileResultImageType* +AbstractProfileResult::FindImage(addr_t address) const +{ + typename ImageList::ConstIterator it = fImages.GetIterator(); + while (ProfileResultImageType* image = it.Next()) { + if (image->ContainsAddress(address)) + return image; + } + return NULL; +} + + +template +int32 +AbstractProfileResult::GetHitImages( + ProfileResultImageType** images) const +{ + int32 imageCount = 0; + + typename ImageList::ConstIterator it = fOldImages.GetIterator(); + while (ProfileResultImageType* image = it.Next()) { + if (image->TotalHits() > 0) + images[imageCount++] = image; + } + + it = fImages.GetIterator(); + while (ProfileResultImageType* image = it.Next()) { + if (image->TotalHits() > 0) + images[imageCount++] = image; + } + + return imageCount; +} + + +#endif // PROFILE_RESULT_H diff --git a/src/bin/debug/profile/ProfiledEntity.cpp b/src/bin/debug/profile/ProfiledEntity.cpp new file mode 100644 index 0000000000..b1a61051ac --- /dev/null +++ b/src/bin/debug/profile/ProfiledEntity.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "ProfiledEntity.h" + + +ProfiledEntity::~ProfiledEntity() +{ +} diff --git a/src/bin/debug/profile/ProfiledEntity.h b/src/bin/debug/profile/ProfiledEntity.h new file mode 100644 index 0000000000..3a4e522d62 --- /dev/null +++ b/src/bin/debug/profile/ProfiledEntity.h @@ -0,0 +1,22 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef PROFILED_ENTITY_H +#define PROFILED_ENTITY_H + + +#include + + +class ProfiledEntity { +public: + virtual ~ProfiledEntity(); + + virtual int32 EntityID() const = 0; + virtual const char* EntityName() const = 0; + virtual const char* EntityType() const = 0; +}; + + +#endif // PROFILED_ENTITY_H diff --git a/src/bin/debug/profile/Team.cpp b/src/bin/debug/profile/Team.cpp index 4f9d6c3732..d201f51a9e 100644 --- a/src/bin/debug/profile/Team.cpp +++ b/src/bin/debug/profile/Team.cpp @@ -104,7 +104,7 @@ status_t Team::InitThread(Thread* thread) { // The thread - thread->ProfileResult()->SetLazyImages(!_SynchronousProfiling()); + thread->GetProfileResult()->SetLazyImages(!_SynchronousProfiling()); // create the sample area char areaName[B_OS_NAME_LENGTH]; @@ -267,7 +267,7 @@ Team::_RemoveImage(int32 index, int32 event) if (_SynchronousProfiling()) { ThreadList::Iterator it = fThreads.GetIterator(); while (Thread* thread = it.Next()) - thread->ProfileResult()->RemoveImage(image); + thread->GetProfileResult()->RemoveImage(image); } else { // Note: We don't tell the threads that the image has been removed. They // will be updated lazily when their next profiler update arrives. This diff --git a/src/bin/debug/profile/Thread.cpp b/src/bin/debug/profile/Thread.cpp index 33ad812042..e8035e301c 100644 --- a/src/bin/debug/profile/Thread.cpp +++ b/src/bin/debug/profile/Thread.cpp @@ -1,8 +1,9 @@ /* - * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ + #include "Thread.h" #include @@ -16,33 +17,6 @@ #include "Team.h" -// #pragma mark - ThreadImage - - -ThreadImage::ThreadImage(Image* image) - : - fImage(image), - fTotalHits(0) -{ - fImage->AddReference(); -} - - -ThreadImage::~ThreadImage() -{ - fImage->RemoveReference(); -} - - -status_t -ThreadImage::Init() -{ - return B_OK; -} - - -// #pragma mark - Thread - Thread::Thread(thread_id threadID, const char* name, Team* team) : @@ -65,8 +39,29 @@ Thread::~Thread() } +int32 +Thread::EntityID() const +{ + return ID(); +} + + +const char* +Thread::EntityName() const +{ + return Name(); +} + + +const char* +Thread::EntityType() const +{ + return "thread"; +} + + void -Thread::SetProfileResult(ThreadProfileResult* result) +Thread::SetProfileResult(ProfileResult* result) { delete fProfileResult; fProfileResult = result; @@ -150,34 +145,3 @@ Thread::PrintResults() const { fProfileResult->PrintResults(); } - - -// #pragma mark - ThreadProfileResult - - -ThreadProfileResult::ThreadProfileResult() - : - fThread(NULL), - fInterval(1) -{ -} - - -ThreadProfileResult::~ThreadProfileResult() -{ -} - - -status_t -ThreadProfileResult::Init(Thread* thread) -{ - fThread = thread; - return B_OK; -} - - -void -ThreadProfileResult::SetInterval(bigtime_t interval) -{ - fInterval = interval; -} diff --git a/src/bin/debug/profile/Thread.h b/src/bin/debug/profile/Thread.h index 64719496ca..774d0a6a6a 100644 --- a/src/bin/debug/profile/Thread.h +++ b/src/bin/debug/profile/Thread.h @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef THREAD_H @@ -10,47 +10,30 @@ #include -#include "Image.h" +#include "ProfiledEntity.h" +#include "ProfileResult.h" class Team; -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 { +class Thread : public ProfiledEntity, public DoublyLinkedListLinkImpl { public: Thread(thread_id threadID, const char* name, Team* team); - ~Thread(); + virtual ~Thread(); inline thread_id ID() const; inline const char* Name() const; inline addr_t* Samples() const; inline Team* GetTeam() const; - inline ThreadProfileResult* ProfileResult() const; - void SetProfileResult(ThreadProfileResult* result); + virtual int32 EntityID() const; + virtual const char* EntityName() const; + virtual const char* EntityType() const; + + inline ProfileResult* GetProfileResult() const; + void SetProfileResult(ProfileResult* result); void UpdateInfo(const char* name); @@ -72,97 +55,10 @@ private: ::Team* fTeam; area_id fSampleArea; addr_t* fSamples; - ThreadProfileResult* fProfileResult; + ProfileResult* fProfileResult; }; -class ThreadProfileResult { -public: - ThreadProfileResult(); - virtual ~ThreadProfileResult(); - - virtual status_t Init(Thread* thread); - - void SetInterval(bigtime_t interval); - - virtual void SetLazyImages(bool lazy) = 0; - - virtual status_t AddImage(Image* image) = 0; - virtual void RemoveImage(Image* image) = 0; - virtual void SynchronizeImages(int32 event) = 0; - - virtual void AddSamples(addr_t* samples, - int32 sampleCount) = 0; - virtual void AddDroppedTicks(int32 dropped) = 0; - virtual void PrintResults() = 0; - -protected: - Thread* fThread; - bigtime_t fInterval; -}; - - -template -class AbstractThreadProfileResult : public ThreadProfileResult { -public: - AbstractThreadProfileResult(); - virtual ~AbstractThreadProfileResult(); - - virtual void SetLazyImages(bool lazy); - - virtual status_t AddImage(Image* image); - virtual void RemoveImage(Image* image); - virtual void SynchronizeImages(int32 event); - - ThreadImageType* FindImage(addr_t address) const; - int32 GetHitImages(ThreadImageType** images) const; - - virtual ThreadImageType* CreateThreadImage(Image* image) = 0; - -protected: - typedef DoublyLinkedList ImageList; - - ImageList fImages; - ImageList fNewImages; - ImageList fOldImages; - bool fLazyImages; -}; - - -// #pragma mark - - - -image_id -ThreadImage::ID() const -{ - return fImage->ID(); -} - - -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 - - - thread_id Thread::ID() const { @@ -191,8 +87,8 @@ Thread::GetTeam() const } -ThreadProfileResult* -Thread::ProfileResult() const +ProfileResult* +Thread::GetProfileResult() const { return fProfileResult; } @@ -212,145 +108,4 @@ Thread::RemoveImage(Image* image) } -// #pragma mark - AbstractThreadProfileResult - - -template -AbstractThreadProfileResult::AbstractThreadProfileResult() - : - fImages(), - fNewImages(), - fOldImages(), - fLazyImages(true) -{ -} - - -template -AbstractThreadProfileResult::~AbstractThreadProfileResult() -{ - while (ThreadImageType* image = fImages.RemoveHead()) - delete image; - while (ThreadImageType* image = fOldImages.RemoveHead()) - delete image; -} - - -template -void -AbstractThreadProfileResult::SetLazyImages(bool lazy) -{ - fLazyImages = lazy; -} - - -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; - } - - if (fLazyImages) - fNewImages.Add(threadImage); - else - fImages.Add(threadImage); - - return B_OK; -} - - -template -void -AbstractThreadProfileResult::RemoveImage(Image* image) -{ - typename ImageList::Iterator it = fImages.GetIterator(); - while (ThreadImageType* threadImage = it.Next()) { - if (threadImage->GetImage() == image) { - it.Remove(); - if (threadImage->TotalHits() > 0) - fOldImages.Add(threadImage); - else - delete threadImage; - break; - } - } -} - - -template -void -AbstractThreadProfileResult::SynchronizeImages(int32 event) -{ - // remove obsolete images - typename 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(); - int32 deleted = image->GetImage()->DeletionEvent(); - if (deleted >= 0 && event >= deleted) { - // image already deleted - delete image; - } else - fImages.Add(image); - } - } -} - - -template -ThreadImageType* -AbstractThreadProfileResult::FindImage(addr_t address) const -{ - typename ImageList::ConstIterator it = fImages.GetIterator(); - while (ThreadImageType* image = it.Next()) { - if (image->ContainsAddress(address)) - return image; - } - return NULL; -} - - -template -int32 -AbstractThreadProfileResult::GetHitImages( - ThreadImageType** images) const -{ - int32 imageCount = 0; - - typename ImageList::ConstIterator it = fOldImages.GetIterator(); - while (ThreadImageType* image = it.Next()) { - if (image->TotalHits() > 0) - images[imageCount++] = image; - } - - it = fImages.GetIterator(); - while (ThreadImageType* image = it.Next()) { - if (image->TotalHits() > 0) - images[imageCount++] = image; - } - - return imageCount; -} - #endif // THREAD_H diff --git a/src/bin/debug/profile/profile.cpp b/src/bin/debug/profile/profile.cpp index a7518ce935..412f8b27db 100644 --- a/src/bin/debug/profile/profile.cpp +++ b/src/bin/debug/profile/profile.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -30,8 +30,8 @@ #include -#include "BasicThreadProfileResult.h" -#include "CallgrindThreadProfileResult.h" +#include "BasicProfileResult.h" +#include "CallgrindProfileResult.h" #include "debug_utils.h" #include "Image.h" #include "Options.h" @@ -145,7 +145,7 @@ public: if (thread == NULL) return B_NO_MEMORY; - status_t error = _CreateThreadProfileResult(thread); + status_t error = _CreateProfileResult(thread); if (error != B_OK) { delete thread; return error; @@ -333,15 +333,15 @@ private: return B_OK; } - status_t _CreateThreadProfileResult(Thread* thread) + status_t _CreateProfileResult(Thread* thread) { - ThreadProfileResult* profileResult; + ProfileResult* profileResult; if (gOptions.callgrind_directory != NULL) - profileResult = new(std::nothrow) CallgrindThreadProfileResult; + profileResult = new(std::nothrow) CallgrindProfileResult; else if (gOptions.analyze_full_stack) - profileResult = new(std::nothrow) InclusiveThreadProfileResult; + profileResult = new(std::nothrow) InclusiveProfileResult; else - profileResult = new(std::nothrow) ExclusiveThreadProfileResult; + profileResult = new(std::nothrow) ExclusiveProfileResult; if (profileResult == NULL) return B_NO_MEMORY;