More refactoring:

* Renamed *ProfileResultImage to *ImageProfileResult.
* Separated the image result management from the *ProfileResult classes:
  - The general per-thread image management functionality does now live in
    Thread.
  - Introduced interface ImageProfileResultContainer which is implemented by
    Thread. An instance is passed to ProfileResult::AddSamples()/PrintResult().
* Made *ProfileResultImage independent of Image. The dependency is now to
  SharedImage only.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35556 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-02-21 17:16:59 +00:00
parent 9546aa512f
commit 6a28c22f5c
10 changed files with 402 additions and 304 deletions
+37 -30
View File
@@ -27,25 +27,26 @@ struct HitSymbol {
}; };
// #pragma mark - BasicProfileResultImage // #pragma mark - BasicImageProfileResult
BasicProfileResultImage::BasicProfileResultImage(Image* image) BasicImageProfileResult::BasicImageProfileResult(SharedImage* image,
image_id id)
: :
ProfileResultImage(image), ImageProfileResult(image, id),
fSymbolHits(NULL), fSymbolHits(NULL),
fUnknownHits(0) fUnknownHits(0)
{ {
} }
BasicProfileResultImage::~BasicProfileResultImage() BasicImageProfileResult::~BasicImageProfileResult()
{ {
} }
status_t status_t
BasicProfileResultImage::Init() BasicImageProfileResult::Init()
{ {
int32 symbolCount = fImage->SymbolCount(); int32 symbolCount = fImage->SymbolCount();
fSymbolHits = new(std::nothrow) int64[symbolCount]; fSymbolHits = new(std::nothrow) int64[symbolCount];
@@ -59,7 +60,7 @@ BasicProfileResultImage::Init()
bool bool
BasicProfileResultImage::AddHit(addr_t address) BasicImageProfileResult::AddHit(addr_t address)
{ {
int32 symbolIndex = fImage->FindSymbol(address); int32 symbolIndex = fImage->FindSymbol(address);
if (symbolIndex < 0) if (symbolIndex < 0)
@@ -73,7 +74,7 @@ BasicProfileResultImage::AddHit(addr_t address)
void void
BasicProfileResultImage::AddUnknownHit() BasicImageProfileResult::AddUnknownHit()
{ {
fUnknownHits++; fUnknownHits++;
fTotalHits++; fTotalHits++;
@@ -81,28 +82,28 @@ BasicProfileResultImage::AddUnknownHit()
void void
BasicProfileResultImage::AddSymbolHit(int32 symbolIndex) BasicImageProfileResult::AddSymbolHit(int32 symbolIndex)
{ {
fSymbolHits[symbolIndex]++; fSymbolHits[symbolIndex]++;
} }
void void
BasicProfileResultImage::AddImageHit() BasicImageProfileResult::AddImageHit()
{ {
fTotalHits++; fTotalHits++;
} }
const int64* const int64*
BasicProfileResultImage::SymbolHits() const BasicImageProfileResult::SymbolHits() const
{ {
return fSymbolHits; return fSymbolHits;
} }
int64 int64
BasicProfileResultImage::UnknownHits() const BasicImageProfileResult::UnknownHits() const
{ {
return fUnknownHits; return fUnknownHits;
} }
@@ -129,16 +130,16 @@ BasicProfileResult::AddDroppedTicks(int32 dropped)
void void
BasicProfileResult::PrintResults() BasicProfileResult::PrintResults(ImageProfileResultContainer* container)
{ {
// get hit images // get hit images
BasicProfileResultImage* images[fOldImages.Count() + fImages.Count()]; BasicImageProfileResult* images[container->CountImages()];
int32 imageCount = GetHitImages(images); int32 imageCount = GetHitImages(container, images);
// count symbols // count symbols
int32 symbolCount = 0; int32 symbolCount = 0;
for (int32 k = 0; k < imageCount; k++) { for (int32 k = 0; k < imageCount; k++) {
BasicProfileResultImage* image = images[k]; BasicImageProfileResult* image = images[k];
if (image->TotalHits() > image->UnknownHits()) if (image->TotalHits() > image->UnknownHits())
symbolCount += image->GetImage()->SymbolCount(); symbolCount += image->GetImage()->SymbolCount();
} }
@@ -148,7 +149,7 @@ BasicProfileResult::PrintResults()
int32 hitSymbolCount = 0; int32 hitSymbolCount = 0;
for (int32 k = 0; k < imageCount; k++) { for (int32 k = 0; k < imageCount; k++) {
BasicProfileResultImage* image = images[k]; BasicImageProfileResult* image = images[k];
if (image->TotalHits() > image->UnknownHits()) { if (image->TotalHits() > image->UnknownHits()) {
Symbol** symbols = image->GetImage()->Symbols(); Symbol** symbols = image->GetImage()->Symbols();
const int64* symbolHits = image->SymbolHits(); const int64* symbolHits = image->SymbolHits();
@@ -193,10 +194,10 @@ BasicProfileResult::PrintResults()
fprintf(gOptions.output, " ---------------------------------------" fprintf(gOptions.output, " ---------------------------------------"
"---------------------------------------\n"); "---------------------------------------\n");
for (int32 k = 0; k < imageCount; k++) { for (int32 k = 0; k < imageCount; k++) {
BasicProfileResultImage* image = images[k]; BasicImageProfileResult* image = images[k];
fprintf(gOptions.output, " %10lld %10lld %7ld %s\n", fprintf(gOptions.output, " %10lld %10lld %7ld %s\n",
image->TotalHits(), image->UnknownHits(), image->TotalHits(), image->UnknownHits(),
image->GetImage()->ID(), image->GetImage()->Name()); image->ID(), image->GetImage()->Name());
} }
} }
@@ -219,10 +220,10 @@ BasicProfileResult::PrintResults()
} }
BasicProfileResultImage* ImageProfileResult*
BasicProfileResult::CreateProfileResultImage(Image* image) BasicProfileResult::CreateImageProfileResult(SharedImage* image, image_id id)
{ {
return new(std::nothrow) BasicProfileResultImage(image); return new(std::nothrow) BasicImageProfileResult(image, id);
} }
@@ -230,7 +231,8 @@ BasicProfileResult::CreateProfileResultImage(Image* image)
void void
InclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount) InclusiveProfileResult::AddSamples(ImageProfileResultContainer* container,
addr_t* samples, int32 sampleCount)
{ {
// Sort the samples. This way hits of the same symbol are // Sort the samples. This way hits of the same symbol are
// successive and we can avoid incrementing the hit count of the // successive and we can avoid incrementing the hit count of the
@@ -238,15 +240,17 @@ InclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
std::sort(samples, samples + sampleCount); std::sort(samples, samples + sampleCount);
int32 unknownSamples = 0; int32 unknownSamples = 0;
BasicProfileResultImage* previousImage = NULL; BasicImageProfileResult* previousImage = NULL;
int32 previousSymbol = -1; int32 previousSymbol = -1;
for (int32 i = 0; i < sampleCount; i++) { for (int32 i = 0; i < sampleCount; i++) {
addr_t address = samples[i]; addr_t address = samples[i];
BasicProfileResultImage* image = FindImage(address); addr_t loadDelta;
BasicImageProfileResult* image = static_cast<BasicImageProfileResult*>(
container->FindImage(address, loadDelta));
int32 symbol = -1; int32 symbol = -1;
if (image != NULL) { if (image != NULL) {
symbol = image->GetImage()->FindSymbol(address); symbol = image->GetImage()->FindSymbol(address - loadDelta);
if (symbol < 0) { if (symbol < 0) {
// TODO: Count unknown image hits? // TODO: Count unknown image hits?
} else if (image != previousImage || symbol != previousSymbol) } else if (image != previousImage || symbol != previousSymbol)
@@ -273,18 +277,21 @@ InclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
void void
ExclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount) ExclusiveProfileResult::AddSamples(ImageProfileResultContainer* container,
addr_t* samples, int32 sampleCount)
{ {
BasicProfileResultImage* image = NULL; BasicImageProfileResult* image = NULL;
// the image in which we hit a symbol // the image in which we hit a symbol
BasicProfileResultImage* firstImage = NULL; BasicImageProfileResult* firstImage = NULL;
// the first image we hit, != image if no symbol was hit // the first image we hit, != image if no symbol was hit
for (int32 k = 0; k < sampleCount; k++) { for (int32 k = 0; k < sampleCount; k++) {
addr_t address = samples[k]; addr_t address = samples[k];
image = FindImage(address); addr_t loadDelta;
image = static_cast<BasicImageProfileResult*>(
container->FindImage(address, loadDelta));
if (image != NULL) { if (image != NULL) {
if (image->AddHit(address)) if (image->AddHit(address - loadDelta))
break; break;
if (firstImage == NULL) if (firstImage == NULL)
firstImage = image; firstImage = image;
+16 -12
View File
@@ -9,11 +9,12 @@
#include "ProfileResult.h" #include "ProfileResult.h"
class BasicProfileResultImage : public ProfileResultImage, class BasicImageProfileResult : public ImageProfileResult,
public DoublyLinkedListLinkImpl<BasicProfileResultImage> { public DoublyLinkedListLinkImpl<BasicImageProfileResult> {
public: public:
BasicProfileResultImage(Image* image); BasicImageProfileResult(SharedImage* image,
virtual ~BasicProfileResultImage(); image_id id);
virtual ~BasicImageProfileResult();
virtual status_t Init(); virtual status_t Init();
@@ -31,15 +32,16 @@ private:
}; };
class BasicProfileResult class BasicProfileResult : public ProfileResult {
: public AbstractProfileResult<BasicProfileResultImage> {
public: public:
BasicProfileResult(); BasicProfileResult();
virtual void AddDroppedTicks(int32 dropped); virtual void AddDroppedTicks(int32 dropped);
virtual void PrintResults(); virtual void PrintResults(
ImageProfileResultContainer* container);
virtual BasicProfileResultImage* CreateProfileResultImage(Image* image); virtual ImageProfileResult* CreateImageProfileResult(SharedImage* image,
image_id id);
protected: protected:
int64 fTotalTicks; int64 fTotalTicks;
@@ -51,15 +53,17 @@ protected:
class InclusiveProfileResult : public BasicProfileResult { class InclusiveProfileResult : public BasicProfileResult {
public: public:
virtual void AddSamples(addr_t* samples, virtual void AddSamples(
int32 sampleCount); ImageProfileResultContainer* container,
addr_t* samples, int32 sampleCount);
}; };
class ExclusiveProfileResult : public BasicProfileResult { class ExclusiveProfileResult : public BasicProfileResult {
public: public:
virtual void AddSamples(addr_t* samples, virtual void AddSamples(
int32 sampleCount); ImageProfileResultContainer* container,
addr_t* samples, int32 sampleCount);
}; };
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010, Ingo Weinhold, [email protected]. * Copyright 2008-2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -16,19 +16,20 @@
#include "ProfiledEntity.h" #include "ProfiledEntity.h"
// #pragma mark - CallgrindProfileResultImage // #pragma mark - CallgrindImageProfileResult
CallgrindProfileResultImage::CallgrindProfileResultImage(Image* image) CallgrindImageProfileResult::CallgrindImageProfileResult(SharedImage* image,
image_id id)
: :
ProfileResultImage(image), ImageProfileResult(image, id),
fFunctions(NULL), fFunctions(NULL),
fOutputIndex(0) fOutputIndex(0)
{ {
} }
CallgrindProfileResultImage::~CallgrindProfileResultImage() CallgrindImageProfileResult::~CallgrindImageProfileResult()
{ {
int32 symbolCount = fImage->SymbolCount(); int32 symbolCount = fImage->SymbolCount();
for (int32 i = 0; i < symbolCount; i++) { for (int32 i = 0; i < symbolCount; i++) {
@@ -44,7 +45,7 @@ CallgrindProfileResultImage::~CallgrindProfileResultImage()
status_t status_t
CallgrindProfileResultImage::Init() CallgrindImageProfileResult::Init()
{ {
int32 symbolCount = fImage->SymbolCount(); int32 symbolCount = fImage->SymbolCount();
fFunctions = new(std::nothrow) CallgrindFunction[symbolCount]; fFunctions = new(std::nothrow) CallgrindFunction[symbolCount];
@@ -58,8 +59,8 @@ CallgrindProfileResultImage::Init()
void void
CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex, CallgrindImageProfileResult::AddSymbolHit(int32 symbolIndex,
CallgrindProfileResultImage* calledImage, int32 calledSymbol) CallgrindImageProfileResult* calledImage, int32 calledSymbol)
{ {
fTotalHits++; fTotalHits++;
@@ -94,21 +95,21 @@ CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex,
CallgrindFunction* CallgrindFunction*
CallgrindProfileResultImage::Functions() const CallgrindImageProfileResult::Functions() const
{ {
return fFunctions; return fFunctions;
} }
int32 int32
CallgrindProfileResultImage::OutputIndex() const CallgrindImageProfileResult::OutputIndex() const
{ {
return fOutputIndex; return fOutputIndex;
} }
void void
CallgrindProfileResultImage::SetOutputIndex(int32 index) CallgrindImageProfileResult::SetOutputIndex(int32 index)
{ {
fOutputIndex = index; fOutputIndex = index;
} }
@@ -129,19 +130,23 @@ CallgrindProfileResult::CallgrindProfileResult()
void void
CallgrindProfileResult::AddSamples(addr_t* samples, int32 sampleCount) CallgrindProfileResult::AddSamples(ImageProfileResultContainer* container,
addr_t* samples, int32 sampleCount)
{ {
int32 unknownSamples = 0; int32 unknownSamples = 0;
CallgrindProfileResultImage* previousImage = NULL; CallgrindImageProfileResult* previousImage = NULL;
int32 previousSymbol = -1; int32 previousSymbol = -1;
// TODO: That probably doesn't work with recursive functions. // TODO: That probably doesn't work with recursive functions.
for (int32 i = 0; i < sampleCount; i++) { for (int32 i = 0; i < sampleCount; i++) {
addr_t address = samples[i]; addr_t address = samples[i];
CallgrindProfileResultImage* image = FindImage(address); addr_t loadDelta;
CallgrindImageProfileResult* image
= static_cast<CallgrindImageProfileResult*>(
container->FindImage(address, loadDelta));
int32 symbol = -1; int32 symbol = -1;
if (image != NULL) { if (image != NULL) {
symbol = image->GetImage()->FindSymbol(address); symbol = image->GetImage()->FindSymbol(address - loadDelta);
if (symbol >= 0) { if (symbol >= 0) {
image->AddSymbolHit(symbol, previousImage, previousSymbol); image->AddSymbolHit(symbol, previousImage, previousSymbol);
previousImage = image; previousImage = image;
@@ -166,7 +171,7 @@ CallgrindProfileResult::AddDroppedTicks(int32 dropped)
void void
CallgrindProfileResult::PrintResults() CallgrindProfileResult::PrintResults(ImageProfileResultContainer* container)
{ {
// create output file // create output file
@@ -206,11 +211,11 @@ CallgrindProfileResult::PrintResults()
fprintf(out, "summary: %lld %lld\n", fTotalTicks, fTotalTicks * fInterval); fprintf(out, "summary: %lld %lld\n", fTotalTicks, fTotalTicks * fInterval);
// get hit images // get hit images
CallgrindProfileResultImage* images[fOldImages.Count() + fImages.Count()]; CallgrindImageProfileResult* images[container->CountImages()];
int32 imageCount = GetHitImages(images); int32 imageCount = GetHitImages(container, images);
for (int32 i = 0; i < imageCount; i++) { for (int32 i = 0; i < imageCount; i++) {
CallgrindProfileResultImage* image = images[i]; CallgrindImageProfileResult* image = images[i];
CallgrindFunction* functions = image->Functions(); CallgrindFunction* functions = image->Functions();
int32 imageSymbolCount = image->GetImage()->SymbolCount(); int32 imageSymbolCount = image->GetImage()->SymbolCount();
@@ -257,16 +262,17 @@ CallgrindProfileResult::PrintResults()
} }
CallgrindProfileResultImage* ImageProfileResult*
CallgrindProfileResult::CreateProfileResultImage(Image* image) CallgrindProfileResult::CreateImageProfileResult(SharedImage* image,
image_id id)
{ {
return new(std::nothrow) CallgrindProfileResultImage(image); return new(std::nothrow) CallgrindImageProfileResult(image, id);
} }
void void
CallgrindProfileResult::_PrintFunction(FILE* out, CallgrindProfileResult::_PrintFunction(FILE* out,
CallgrindProfileResultImage* image, int32 functionIndex, bool called) CallgrindImageProfileResult* image, int32 functionIndex, bool called)
{ {
if (image->OutputIndex() == 0) { if (image->OutputIndex() == 0) {
// need to print the image name // need to print the image name
+18 -15
View File
@@ -11,16 +11,16 @@
#include "ProfileResult.h" #include "ProfileResult.h"
class CallgrindProfileResultImage; class CallgrindImageProfileResult;
struct CallgrindCalledFunction { struct CallgrindCalledFunction {
CallgrindCalledFunction* next; CallgrindCalledFunction* next;
CallgrindProfileResultImage* image; CallgrindImageProfileResult* image;
int32 function; int32 function;
int64 hits; int64 hits;
CallgrindCalledFunction(CallgrindProfileResultImage* image, int32 function) CallgrindCalledFunction(CallgrindImageProfileResult* image, int32 function)
: :
next(NULL), next(NULL),
image(image), image(image),
@@ -39,16 +39,17 @@ struct CallgrindFunction {
}; };
class CallgrindProfileResultImage : public ProfileResultImage, class CallgrindImageProfileResult : public ImageProfileResult,
public DoublyLinkedListLinkImpl<CallgrindProfileResultImage> { public DoublyLinkedListLinkImpl<CallgrindImageProfileResult> {
public: public:
CallgrindProfileResultImage(Image* image); CallgrindImageProfileResult(SharedImage* image,
virtual ~CallgrindProfileResultImage(); image_id id);
virtual ~CallgrindImageProfileResult();
virtual status_t Init(); virtual status_t Init();
inline void AddSymbolHit(int32 symbolIndex, inline void AddSymbolHit(int32 symbolIndex,
CallgrindProfileResultImage* calledImage, CallgrindImageProfileResult* calledImage,
int32 calledSymbol); int32 calledSymbol);
inline CallgrindFunction* Functions() const; inline CallgrindFunction* Functions() const;
@@ -62,21 +63,23 @@ private:
}; };
class CallgrindProfileResult class CallgrindProfileResult : public ProfileResult {
: public AbstractProfileResult<CallgrindProfileResultImage> {
public: public:
CallgrindProfileResult(); CallgrindProfileResult();
virtual void AddSamples(addr_t* samples, virtual void AddSamples(
int32 sampleCount); ImageProfileResultContainer* container,
addr_t* samples, int32 sampleCount);
virtual void AddDroppedTicks(int32 dropped); virtual void AddDroppedTicks(int32 dropped);
virtual void PrintResults(); virtual void PrintResults(
ImageProfileResultContainer* container);
virtual CallgrindProfileResultImage* CreateProfileResultImage(Image* image); virtual ImageProfileResult* CreateImageProfileResult(SharedImage* image,
image_id id);
private: private:
void _PrintFunction(FILE* out, void _PrintFunction(FILE* out,
CallgrindProfileResultImage* image, CallgrindImageProfileResult* image,
int32 functionIndex, bool called); int32 functionIndex, bool called);
private: private:
int64 fTotalTicks; int64 fTotalTicks;
+22 -5
View File
@@ -7,26 +7,43 @@
#include "ProfileResult.h" #include "ProfileResult.h"
// #pragma mark - ProfileResultImage // #pragma mark - ImageProfileResultContainer
ProfileResultImage::ProfileResultImage(Image* image) ImageProfileResultContainer::~ImageProfileResultContainer()
{
}
// #pragma mark - ImageProfileResultContainer::Visitor
ImageProfileResultContainer::Visitor::~Visitor()
{
}
// #pragma mark - ImageProfileResult
ImageProfileResult::ImageProfileResult(SharedImage* image, image_id id)
: :
fImage(image), fImage(image),
fTotalHits(0) fTotalHits(0),
fImageID(id)
{ {
fImage->AddReference(); fImage->AddReference();
} }
ProfileResultImage::~ProfileResultImage() ImageProfileResult::~ImageProfileResult()
{ {
fImage->RemoveReference(); fImage->RemoveReference();
} }
status_t status_t
ProfileResultImage::Init() ImageProfileResult::Init()
{ {
return B_OK; return B_OK;
} }
+71 -188
View File
@@ -8,30 +8,53 @@
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include "Image.h" #include "SharedImage.h"
class ProfiledEntity; class ProfiledEntity;
class Team; class Team;
class ProfileResultImage { class ImageProfileResult {
public: public:
ProfileResultImage(Image* image); ImageProfileResult(SharedImage* image,
virtual ~ProfileResultImage(); image_id id);
virtual ~ImageProfileResult();
virtual status_t Init(); virtual status_t Init();
inline image_id ID() const; inline image_id ID() const;
inline Image* GetImage() const; inline SharedImage* GetImage() const;
inline bool ContainsAddress(addr_t address) const;
inline int64 TotalHits() const; inline int64 TotalHits() const;
protected: protected:
Image* fImage; SharedImage* fImage;
int64 fTotalHits; int64 fTotalHits;
image_id fImageID;
};
class ImageProfileResultContainer {
public:
class Visitor;
public:
virtual ~ImageProfileResultContainer();
virtual int32 CountImages() const = 0;
virtual ImageProfileResult* VisitImages(Visitor& visitor) const = 0;
virtual ImageProfileResult* FindImage(addr_t address,
addr_t& _loadDelta) const = 0;
};
class ImageProfileResultContainer::Visitor {
public:
virtual ~Visitor();
virtual bool VisitImage(ImageProfileResult* image) = 0;
}; };
@@ -44,16 +67,22 @@ public:
void SetInterval(bigtime_t interval); void SetInterval(bigtime_t interval);
virtual void SetLazyImages(bool lazy) = 0; virtual void AddSamples(
ImageProfileResultContainer* container,
virtual status_t AddImage(Image* image) = 0; addr_t* samples,
virtual void RemoveImage(Image* image) = 0;
virtual void SynchronizeImages(int32 event) = 0;
virtual void AddSamples(addr_t* samples,
int32 sampleCount) = 0; int32 sampleCount) = 0;
virtual void AddDroppedTicks(int32 dropped) = 0; virtual void AddDroppedTicks(int32 dropped) = 0;
virtual void PrintResults() = 0; virtual void PrintResults(
ImageProfileResultContainer* container) = 0;
virtual ImageProfileResult* CreateImageProfileResult(SharedImage* image,
image_id id) = 0;
protected:
template<typename ImageProfileResultType>
int32 GetHitImages(
ImageProfileResultContainer* container,
ImageProfileResultType** images) const;
protected: protected:
ProfiledEntity* fEntity; ProfiledEntity* fEntity;
@@ -61,204 +90,58 @@ protected:
}; };
template<typename ProfileResultImageType> // #pragma mark - ImageProfileResult
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<ProfileResultImageType> ImageList;
ImageList fImages;
ImageList fNewImages;
ImageList fOldImages;
bool fLazyImages;
};
// #pragma mark -
image_id image_id
ProfileResultImage::ID() const ImageProfileResult::ID() const
{ {
return fImage->ID(); return fImageID;
} }
bool SharedImage*
ProfileResultImage::ContainsAddress(addr_t address) const ImageProfileResult::GetImage() const
{
return fImage->ContainsAddress(address);
}
Image*
ProfileResultImage::GetImage() const
{ {
return fImage; return fImage;
} }
int64 int64
ProfileResultImage::TotalHits() const ImageProfileResult::TotalHits() const
{ {
return fTotalHits; return fTotalHits;
} }
// #pragma mark - AbstractProfileResult // #pragma mark - ProfileResult
template<typename ProfileResultImageType> template<typename ImageProfileResultType>
AbstractProfileResult<ProfileResultImageType>::AbstractProfileResult()
:
fImages(),
fNewImages(),
fOldImages(),
fLazyImages(true)
{
}
template<typename ProfileResultImageType>
AbstractProfileResult<ProfileResultImageType>::~AbstractProfileResult()
{
while (ProfileResultImageType* image = fImages.RemoveHead())
delete image;
while (ProfileResultImageType* image = fOldImages.RemoveHead())
delete image;
}
template<typename ProfileResultImageType>
void
AbstractProfileResult<ProfileResultImageType>::SetLazyImages(bool lazy)
{
fLazyImages = lazy;
}
template<typename ProfileResultImageType>
status_t
AbstractProfileResult<ProfileResultImageType>::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<typename ProfileResultImageType>
void
AbstractProfileResult<ProfileResultImageType>::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<typename ProfileResultImageType>
void
AbstractProfileResult<ProfileResultImageType>::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<typename ProfileResultImageType>
ProfileResultImageType*
AbstractProfileResult<ProfileResultImageType>::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<typename ProfileResultImageType>
int32 int32
AbstractProfileResult<ProfileResultImageType>::GetHitImages( ProfileResult::GetHitImages(ImageProfileResultContainer* container,
ProfileResultImageType** images) const ImageProfileResultType** images) const
{ {
int32 imageCount = 0; struct Visitor : ImageProfileResultContainer::Visitor {
ImageProfileResultType** images;
int32 imageCount;
typename ImageList::ConstIterator it = fOldImages.GetIterator(); virtual bool VisitImage(ImageProfileResult* image)
while (ProfileResultImageType* image = it.Next()) { {
if (image->TotalHits() > 0) if (image->TotalHits() > 0) {
images[imageCount++] = image; images[imageCount++]
= static_cast<ImageProfileResultType*>(image);
} }
return false;
it = fImages.GetIterator();
while (ProfileResultImageType* image = it.Next()) {
if (image->TotalHits() > 0)
images[imageCount++] = image;
} }
} visitor;
return imageCount; visitor.images = images;
visitor.imageCount = 0;
container->VisitImages(visitor);
return visitor.imageCount;
} }
+4 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2008-2009, Ingo Weinhold, [email protected]. * Copyright 2008-2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -14,6 +14,7 @@
#include "debug_utils.h" #include "debug_utils.h"
#include "Image.h"
#include "Options.h" #include "Options.h"
@@ -104,7 +105,7 @@ status_t
Team::InitThread(Thread* thread) Team::InitThread(Thread* thread)
{ {
// The thread // The thread
thread->GetProfileResult()->SetLazyImages(!_SynchronousProfiling()); thread->SetLazyImages(!_SynchronousProfiling());
// create the sample area // create the sample area
char areaName[B_OS_NAME_LENGTH]; char areaName[B_OS_NAME_LENGTH];
@@ -267,7 +268,7 @@ Team::_RemoveImage(int32 index, int32 event)
if (_SynchronousProfiling()) { if (_SynchronousProfiling()) {
ThreadList::Iterator it = fThreads.GetIterator(); ThreadList::Iterator it = fThreads.GetIterator();
while (Thread* thread = it.Next()) while (Thread* thread = it.Next())
thread->GetProfileResult()->RemoveImage(image); thread->RemoveImage(image);
} else { } else {
// Note: We don't tell the threads that the image has been removed. They // 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 // will be updated lazily when their next profiler update arrives. This
+3 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2008-2009, Ingo Weinhold, [email protected]. * Copyright 2008-2010, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef TEAM_H #ifndef TEAM_H
@@ -14,6 +14,8 @@
#include "Thread.h" #include "Thread.h"
class Image;
class SharedImage;
struct system_profiler_team_added; struct system_profiler_team_added;
+161 -8
View File
@@ -13,10 +13,32 @@
#include "debug_utils.h" #include "debug_utils.h"
#include "Image.h"
#include "Options.h" #include "Options.h"
#include "Team.h" #include "Team.h"
// #pragma mark - ThreadImage
ThreadImage::ThreadImage(Image* image, ImageProfileResult* result)
:
fImage(image),
fResult(result)
{
fImage->AcquireReference();
}
ThreadImage::~ThreadImage()
{
fImage->ReleaseReference();
delete fResult;
}
// #pragma mark - ThreadI
Thread::Thread(thread_id threadID, const char* name, Team* team) Thread::Thread(thread_id threadID, const char* name, Team* team)
: :
@@ -25,7 +47,8 @@ Thread::Thread(thread_id threadID, const char* name, Team* team)
fTeam(team), fTeam(team),
fSampleArea(-1), fSampleArea(-1),
fSamples(NULL), fSamples(NULL),
fProfileResult(NULL) fProfileResult(NULL),
fLazyImages(true)
{ {
} }
@@ -36,6 +59,11 @@ Thread::~Thread()
delete_area(fSampleArea); delete_area(fSampleArea);
delete fProfileResult; delete fProfileResult;
while (ThreadImage* image = fImages.RemoveHead())
delete image;
while (ThreadImage* image = fOldImages.RemoveHead())
delete image;
} }
@@ -90,11 +118,64 @@ Thread::SetInterval(bigtime_t interval)
} }
void
Thread::SetLazyImages(bool lazy)
{
fLazyImages = lazy;
}
status_t
Thread::AddImage(Image* image)
{
ImageProfileResult* result = fProfileResult->CreateImageProfileResult(
image->GetSharedImage(), image->ID());
if (result == NULL)
return B_NO_MEMORY;
status_t error = result->Init();
if (error != B_OK) {
delete result;
return error;
}
ThreadImage* threadImage = new(std::nothrow) ThreadImage(image, result);
if (threadImage == NULL) {
delete result;
return B_NO_MEMORY;
}
if (fLazyImages)
fNewImages.Add(threadImage);
else
fImages.Add(threadImage);
return B_OK;
}
void
Thread::RemoveImage(Image* image)
{
ImageList::Iterator it = fImages.GetIterator();
while (ThreadImage* threadImage = it.Next()) {
if (threadImage->GetImage() == image) {
it.Remove();
if (threadImage->Result()->TotalHits() > 0)
fOldImages.Add(threadImage);
else
delete threadImage;
break;
}
}
}
void void
Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth, Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
bool variableStackDepth, int32 event) bool variableStackDepth, int32 event)
{ {
fProfileResult->SynchronizeImages(event); _SynchronizeImages(event);
if (variableStackDepth) { if (variableStackDepth) {
addr_t* samples = fSamples; addr_t* samples = fSamples;
@@ -106,7 +187,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
int32 eventParameterCount int32 eventParameterCount
= sampleCount & B_DEBUG_PROFILE_EVENT_PARAMETER_MASK; = sampleCount & B_DEBUG_PROFILE_EVENT_PARAMETER_MASK;
if (sampleCount == B_DEBUG_PROFILE_IMAGE_EVENT) { if (sampleCount == B_DEBUG_PROFILE_IMAGE_EVENT) {
fProfileResult->SynchronizeImages((int32)samples[0]); _SynchronizeImages((int32)samples[0]);
} else { } else {
fprintf(stderr, "unknown profile event: %#lx\n", fprintf(stderr, "unknown profile event: %#lx\n",
sampleCount); sampleCount);
@@ -117,7 +198,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
continue; continue;
} }
fProfileResult->AddSamples(samples, sampleCount); fProfileResult->AddSamples(this, samples, sampleCount);
samples += sampleCount; samples += sampleCount;
count -= sampleCount + 1; count -= sampleCount + 1;
@@ -126,7 +207,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
count = count / stackDepth * stackDepth; count = count / stackDepth * stackDepth;
for (int32 i = 0; i < count; i += stackDepth) for (int32 i = 0; i < count; i += stackDepth)
fProfileResult->AddSamples(fSamples + i, stackDepth); fProfileResult->AddSamples(this, fSamples + i, stackDepth);
} }
fProfileResult->AddDroppedTicks(dropped); fProfileResult->AddDroppedTicks(dropped);
@@ -136,12 +217,84 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
void void
Thread::AddSamples(addr_t* samples, int32 sampleCount) Thread::AddSamples(addr_t* samples, int32 sampleCount)
{ {
fProfileResult->AddSamples(samples, sampleCount); fProfileResult->AddSamples(this, samples, sampleCount);
} }
void void
Thread::PrintResults() const Thread::PrintResults()
{ {
fProfileResult->PrintResults(); fProfileResult->PrintResults(this);
}
int32
Thread::CountImages() const
{
return fImages.Count() + fOldImages.Count();
}
ImageProfileResult*
Thread::VisitImages(Visitor& visitor) const
{
ImageList::ConstIterator it = fOldImages.GetIterator();
while (ThreadImage* image = it.Next()) {
if (visitor.VisitImage(image->Result()))
return image->Result();
}
it = fImages.GetIterator();
while (ThreadImage* image = it.Next()) {
if (visitor.VisitImage(image->Result()))
return image->Result();
}
return NULL;
}
ImageProfileResult*
Thread::FindImage(addr_t address, addr_t& _loadDelta) const
{
ImageList::ConstIterator it = fImages.GetIterator();
while (ThreadImage* image = it.Next()) {
if (image->GetImage()->ContainsAddress(address)) {
_loadDelta = image->GetImage()->LoadDelta();
return image->Result();
}
}
return NULL;
}
void
Thread::_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->Result()->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();
int32 deleted = image->GetImage()->DeletionEvent();
if (deleted >= 0 && event >= deleted) {
// image already deleted
delete image;
} else
fImages.Add(image);
}
}
} }
+40 -18
View File
@@ -14,10 +14,27 @@
#include "ProfileResult.h" #include "ProfileResult.h"
class Image;
class Team; class Team;
class Thread : public ProfiledEntity, public DoublyLinkedListLinkImpl<Thread> { class ThreadImage : public DoublyLinkedListLinkImpl<ThreadImage> {
public:
ThreadImage(Image* image,
ImageProfileResult* result);
~ThreadImage();
Image* GetImage() const { return fImage; }
ImageProfileResult* Result() const { return fResult; }
private:
Image* fImage;
ImageProfileResult* fResult;
};
class Thread : public ProfiledEntity, public DoublyLinkedListLinkImpl<Thread>,
private ImageProfileResultContainer {
public: public:
Thread(thread_id threadID, const char* name, Thread(thread_id threadID, const char* name,
Team* team); Team* team);
@@ -40,14 +57,29 @@ public:
void SetSampleArea(area_id area, addr_t* samples); void SetSampleArea(area_id area, addr_t* samples);
void SetInterval(bigtime_t interval); void SetInterval(bigtime_t interval);
inline status_t AddImage(Image* image); void SetLazyImages(bool lazy);
inline void RemoveImage(Image* image);
status_t AddImage(Image* image);
void RemoveImage(Image* image);
void AddSamples(int32 count, int32 dropped, void AddSamples(int32 count, int32 dropped,
int32 stackDepth, bool variableStackDepth, int32 stackDepth, bool variableStackDepth,
int32 event); int32 event);
void AddSamples(addr_t* samples, int32 sampleCount); void AddSamples(addr_t* samples, int32 sampleCount);
void PrintResults() const; void PrintResults();
private:
typedef DoublyLinkedList<ThreadImage> ImageList;
private:
// ImageProfileResultContainer
virtual int32 CountImages() const;
virtual ImageProfileResult* VisitImages(Visitor& visitor) const;
virtual ImageProfileResult* FindImage(addr_t address,
addr_t& _loadDelta) const;
private:
void _SynchronizeImages(int32 event);
private: private:
thread_id fID; thread_id fID;
@@ -56,6 +88,10 @@ private:
area_id fSampleArea; area_id fSampleArea;
addr_t* fSamples; addr_t* fSamples;
ProfileResult* fProfileResult; ProfileResult* fProfileResult;
ImageList fImages;
ImageList fNewImages;
ImageList fOldImages;
bool fLazyImages;
}; };
@@ -94,18 +130,4 @@ Thread::GetProfileResult() const
} }
status_t
Thread::AddImage(Image* image)
{
return fProfileResult->AddImage(image);
}
void
Thread::RemoveImage(Image* image)
{
fProfileResult->RemoveImage(image);
}
#endif // THREAD_H #endif // THREAD_H