Pulled subclass BasicThreadProfileResult out of
AbstractThreadProfileResult. The latter only manages the images, now.
Moved the AddSamples() code into BasicThreadProfileResult subclasses that
handle it depending on whether the function hits are counted inclusively
or exclusively ("-f" option).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27782 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -39,7 +39,7 @@ public:
|
||||
fImage->AddReference();
|
||||
}
|
||||
|
||||
~ThreadImage()
|
||||
virtual ~ThreadImage()
|
||||
{
|
||||
fImage->RemoveReference();
|
||||
}
|
||||
@@ -260,15 +260,12 @@ ThreadProfileResult::SetInterval(bigtime_t interval)
|
||||
|
||||
// #pragma mark - AbstractThreadProfileResult
|
||||
|
||||
|
||||
AbstractThreadProfileResult::AbstractThreadProfileResult()
|
||||
:
|
||||
fImages(),
|
||||
fNewImages(),
|
||||
fOldImages(),
|
||||
fTotalTicks(0),
|
||||
fUnkownTicks(0),
|
||||
fDroppedTicks(0),
|
||||
fTotalSampleCount(0)
|
||||
fOldImages()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -282,17 +279,10 @@ AbstractThreadProfileResult::~AbstractThreadProfileResult()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AbstractThreadProfileResult::Init(Thread* thread)
|
||||
{
|
||||
return ThreadProfileResult::Init(thread);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AbstractThreadProfileResult::AddImage(Image* image)
|
||||
{
|
||||
ThreadImage* threadImage = new(std::nothrow) ThreadImage(image);
|
||||
ThreadImage* threadImage = CreateThreadImage(image);
|
||||
if (threadImage == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@@ -347,70 +337,28 @@ AbstractThreadProfileResult::FindImage(addr_t address) const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AbstractThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
|
||||
// #pragma mark - BasicThreadProfileResult
|
||||
|
||||
|
||||
BasicThreadProfileResult::BasicThreadProfileResult()
|
||||
:
|
||||
fTotalTicks(0),
|
||||
fUnkownTicks(0),
|
||||
fDroppedTicks(0),
|
||||
fTotalSampleCount(0)
|
||||
{
|
||||
if (gOptions.analyze_full_stack) {
|
||||
// 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++;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AbstractThreadProfileResult::AddDroppedTicks(int32 dropped)
|
||||
BasicThreadProfileResult::AddDroppedTicks(int32 dropped)
|
||||
{
|
||||
fDroppedTicks += dropped;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AbstractThreadProfileResult::PrintResults()
|
||||
BasicThreadProfileResult::PrintResults()
|
||||
{
|
||||
// count images and symbols
|
||||
int32 imageCount = 0;
|
||||
@@ -523,3 +471,76 @@ AbstractThreadProfileResult::PrintResults()
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -80,17 +80,17 @@ public:
|
||||
AbstractThreadProfileResult();
|
||||
virtual ~AbstractThreadProfileResult();
|
||||
|
||||
virtual status_t Init(Thread* thread);
|
||||
|
||||
virtual status_t AddImage(Image* image);
|
||||
virtual void SynchronizeImages(int32 event);
|
||||
|
||||
ThreadImage* FindImage(addr_t address) const;
|
||||
|
||||
virtual void AddSamples(addr_t* samples,
|
||||
int32 sampleCount);
|
||||
virtual void AddDroppedTicks(int32 dropped);
|
||||
virtual void PrintResults();
|
||||
int32 sampleCount) = 0;
|
||||
virtual void AddDroppedTicks(int32 dropped) = 0;
|
||||
virtual void PrintResults() = 0;
|
||||
|
||||
virtual ThreadImage* CreateThreadImage(Image* image) = 0;
|
||||
|
||||
protected:
|
||||
typedef DoublyLinkedList<ThreadImage> ImageList;
|
||||
@@ -98,6 +98,19 @@ protected:
|
||||
ImageList fImages;
|
||||
ImageList fNewImages;
|
||||
ImageList fOldImages;
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
@@ -105,6 +118,20 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
||||
@@ -174,8 +174,12 @@ public:
|
||||
private:
|
||||
status_t _CreateThreadProfileResult(Thread* thread)
|
||||
{
|
||||
ThreadProfileResult* profileResult
|
||||
= new(std::nothrow) AbstractThreadProfileResult;
|
||||
ThreadProfileResult* profileResult;
|
||||
if (gOptions.analyze_full_stack)
|
||||
profileResult = new(std::nothrow) InclusiveThreadProfileResult;
|
||||
else
|
||||
profileResult = new(std::nothrow) ExclusiveThreadProfileResult;
|
||||
|
||||
if (profileResult == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user