[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haiku-commits
Subject:    [Haiku-commits] r27788 - haiku/trunk/src/bin/debug/profile
From:       bonefish at BerliOS <bonefish () mail ! berlios ! de>
Date:       2008-09-29 23:49:30
Message-ID: 200809292349.m8TNnU2n017930 () sheep ! berlios ! de
[Download RAW message or body]

Author: bonefish
Date: 2008-09-30 01:49:29 +0200 (Tue, 30 Sep 2008)
New Revision: 27788
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=27788&view=rev

Added:
   haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.cpp
   haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.h
Modified:
   haiku/trunk/src/bin/debug/profile/Jamfile
   haiku/trunk/src/bin/debug/profile/Thread.cpp
   haiku/trunk/src/bin/debug/profile/Thread.h
   haiku/trunk/src/bin/debug/profile/profile.cpp
Log:
More refactoring:
* Moved the BasicThreadProfileResult class, its subclasses and related
  code into separate files.
* Made ThreadImage an abstract base class. Pulled the meaty part into
  new subclass BasicThreadImage.
* Templatized AbstractThreadProfileResult over the ThreadImage type.


Added: haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.cpp
===================================================================
--- haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.cpp	2008-09-29 23:45:45 UTC (rev 27787)
+++ haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.cpp	2008-09-29 23:49:29 UTC (rev 27788)
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "BasicThreadProfileResult.h"
+
+#include <stdio.h>
+
+#include <algorithm>
+#include <new>
+
+#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;
+}

Added: haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.h
===================================================================
--- haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.h	2008-09-29 23:45:45 UTC (rev 27787)
+++ haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.h	2008-09-29 23:49:29 UTC (rev 27788)
@@ -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<BasicThreadImage> {
+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<BasicThreadImage> {
+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

Modified: haiku/trunk/src/bin/debug/profile/Jamfile
===================================================================
--- haiku/trunk/src/bin/debug/profile/Jamfile	2008-09-29 23:45:45 UTC (rev 27787)
+++ haiku/trunk/src/bin/debug/profile/Jamfile	2008-09-29 23:49:29 UTC (rev 27788)
@@ -10,6 +10,7 @@
 
 BinCommand profile
 	:
+	BasicThreadProfileResult.cpp
 	Image.cpp
 	Team.cpp
 	Thread.cpp

Modified: haiku/trunk/src/bin/debug/profile/Thread.cpp
===================================================================
--- haiku/trunk/src/bin/debug/profile/Thread.cpp	2008-09-29 23:45:45 UTC (rev 27787)
+++ haiku/trunk/src/bin/debug/profile/Thread.cpp	2008-09-29 23:49:29 UTC (rev 27788)
@@ -16,108 +16,34 @@
 #include "Team.h"
 
 
-struct HitSymbol {
-	int64	hits;
-	Symbol*	symbol;
+// #pragma mark - ThreadImage
 
-	inline bool operator<(const HitSymbol& other) const
-	{
-		return hits > other.hits;
-	}
-};
 
+ThreadImage::ThreadImage(Image* image)
+	:
+	fImage(image),
+	fTotalHits(0)
+{
+	fImage->AddReference();
+}
 
-class ThreadImage : public DoublyLinkedListLinkImpl<ThreadImage> {
-public:
-	ThreadImage(Image* image)
-		:
-		fImage(image),
-		fSymbolHits(NULL),
-		fTotalHits(0),
-		fUnknownHits(0)
-	{
-		fImage->AddReference();
-	}
 
-	virtual ~ThreadImage()
-	{
-		fImage->RemoveReference();
-	}
+ThreadImage::~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);
+status_t
+ThreadImage::Init()
+{
+	return B_OK;
+}
 
-		return B_OK;
-	}
 
-	image_id ID() const
-	{
-		return fImage->ID();
-	}
+// #pragma mark - Thread
 
-	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;
-};
-
-
-// #pragma mark -
-
-
 Thread::Thread(const thread_info& info, Team* team)
 	:
 	fInfo(info),
@@ -256,291 +182,3 @@
 {
 	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;
-}

Modified: haiku/trunk/src/bin/debug/profile/Thread.h
===================================================================
--- haiku/trunk/src/bin/debug/profile/Thread.h	2008-09-29 23:45:45 UTC (rev 27787)
+++ haiku/trunk/src/bin/debug/profile/Thread.h	2008-09-29 23:49:29 UTC (rev 27788)
@@ -15,6 +15,26 @@
 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<Thread> {
 public:
 								Thread(const thread_info& info, Team* team);
@@ -75,6 +95,7 @@
 };
 
 
+template<typename ThreadImageType>
 class AbstractThreadProfileResult : public ThreadProfileResult {
 public:
 								AbstractThreadProfileResult();
@@ -83,17 +104,17 @@
 	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<ThreadImage>	ImageList;
+	typedef DoublyLinkedList<ThreadImageType>	ImageList;
 
 			ImageList			fImages;
 			ImageList			fNewImages;
@@ -101,37 +122,37 @@
 };
 
 
-class BasicThreadProfileResult : public AbstractThreadProfileResult {
-public:
-								BasicThreadProfileResult();
+// #pragma mark -
 
-	virtual	void				AddDroppedTicks(int32 dropped);
-	virtual	void				PrintResults();
 
-	virtual ThreadImage*		CreateThreadImage(Image* image);
+image_id
+ThreadImage::ID() const
+{
+	return fImage->ID();
+}
 
-protected:
-			int64				fTotalTicks;
-			int64				fUnkownTicks;
-			int64				fDroppedTicks;
-			int64				fTotalSampleCount;
-};
 
+bool
+ThreadImage::ContainsAddress(addr_t address) const
+{
+	return fImage->ContainsAddress(address);
+}
 
-class InclusiveThreadProfileResult : public BasicThreadProfileResult {
-public:
-	virtual	void				AddSamples(addr_t* samples,
-									int32 sampleCount);
-};
 
+Image*
+ThreadImage::GetImage() const
+{
+	return fImage;
+}
 
-class ExclusiveThreadProfileResult : public BasicThreadProfileResult {
-public:
-	virtual	void				AddSamples(addr_t* samples,
-									int32 sampleCount);
-};
 
+int64
+ThreadImage::TotalHits() const
+{
+	return fTotalHits;
+}
 
+
 // #pragma mark -
 
 
@@ -170,4 +191,88 @@
 }
 
 
+// #pragma mark - AbstractThreadProfileResult
+
+
+template<typename ThreadImageType>
+AbstractThreadProfileResult<ThreadImageType>::AbstractThreadProfileResult()
+	:
+	fImages(),
+	fNewImages(),
+	fOldImages()
+{
+}
+
+
+template<typename ThreadImageType>
+AbstractThreadProfileResult<ThreadImageType>::~AbstractThreadProfileResult()
+{
+	while (ThreadImageType* image = fImages.RemoveHead())
+		delete image;
+	while (ThreadImageType* image = fOldImages.RemoveHead())
+		delete image;
+}
+
+
+template<typename ThreadImageType>
+status_t
+AbstractThreadProfileResult<ThreadImageType>::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<typename ThreadImageType>
+void
+AbstractThreadProfileResult<ThreadImageType>::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;
+		}

[... truncated: 41 lines follow ...]
_______________________________________________
Haiku-commits mailing list
Haiku-commits@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/haiku-commits
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic