[haiku-commits] r35546 - haiku/trunk/src/bin/debug/profile

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 20 Feb 2010 21:31:04 +0100 (CET)

Author: bonefish
Date: 2010-02-20 21:31:04 +0100 (Sat, 20 Feb 2010)
New Revision: 35546
Changeset: http://dev.haiku-os.org/changeset/35546/haiku

Added:
   haiku/trunk/src/bin/debug/profile/BasicProfileResult.cpp
   haiku/trunk/src/bin/debug/profile/BasicProfileResult.h
   haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.cpp
   haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.h
   haiku/trunk/src/bin/debug/profile/ProfileResult.cpp
   haiku/trunk/src/bin/debug/profile/ProfileResult.h
   haiku/trunk/src/bin/debug/profile/ProfiledEntity.cpp
   haiku/trunk/src/bin/debug/profile/ProfiledEntity.h
Removed:
   haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.cpp
   haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.h
   haiku/trunk/src/bin/debug/profile/CallgrindThreadProfileResult.cpp
   haiku/trunk/src/bin/debug/profile/CallgrindThreadProfileResult.h
Modified:
   haiku/trunk/src/bin/debug/profile/Jamfile
   haiku/trunk/src/bin/debug/profile/Team.cpp
   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:
Some refactoring:
* Added new class ProfiledEntity which Thread derives from and which is the
  new dependency for the profile result classes (instead of Thread).
* Renamed *ThreadProfileResult to *ProfileResult and *ThreadImage to
  *ProfileResultImage and move ProfileResult[Image] into a new header/source
  file.


Copied: haiku/trunk/src/bin/debug/profile/BasicProfileResult.cpp (from rev 
35519, haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.cpp)
===================================================================
--- haiku/trunk/src/bin/debug/profile/BasicProfileResult.cpp                    
        (rev 0)
+++ haiku/trunk/src/bin/debug/profile/BasicProfileResult.cpp    2010-02-20 
20:31:04 UTC (rev 35546)
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "BasicProfileResult.h"
+
+#include <stdio.h>
+
+#include <algorithm>
+#include <new>
+
+#include "Options.h"
+#include "ProfiledEntity.h"
+
+
+struct HitSymbol {
+       int64           hits;
+       Symbol*         symbol;
+       image_id        imageID;
+
+       inline bool operator<(const HitSymbol& other) const
+       {
+               return hits > other.hits;
+       }
+};
+
+
+// #pragma mark - BasicProfileResultImage
+
+
+BasicProfileResultImage::BasicProfileResultImage(Image* image)
+       :
+       ProfileResultImage(image),
+       fSymbolHits(NULL),
+       fUnknownHits(0)
+{
+}
+
+
+BasicProfileResultImage::~BasicProfileResultImage()
+{
+}
+
+
+status_t
+BasicProfileResultImage::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;
+}
+
+
+bool
+BasicProfileResultImage::AddHit(addr_t address)
+{
+       int32 symbolIndex = fImage->FindSymbol(address);
+       if (symbolIndex < 0)
+               return false;
+
+       fSymbolHits[symbolIndex]++;
+       fTotalHits++;
+
+       return true;
+}
+
+
+void
+BasicProfileResultImage::AddUnknownHit()
+{
+       fUnknownHits++;
+       fTotalHits++;
+}
+
+
+void
+BasicProfileResultImage::AddSymbolHit(int32 symbolIndex)
+{
+       fSymbolHits[symbolIndex]++;
+}
+
+
+void
+BasicProfileResultImage::AddImageHit()
+{
+       fTotalHits++;
+}
+
+
+const int64*
+BasicProfileResultImage::SymbolHits() const
+{
+       return fSymbolHits;
+}
+
+
+int64
+BasicProfileResultImage::UnknownHits() const
+{
+       return fUnknownHits;
+}
+
+
+// #pragma mark - BasicProfileResult
+
+
+BasicProfileResult::BasicProfileResult()
+       :
+       fTotalTicks(0),
+       fUnkownTicks(0),
+       fDroppedTicks(0),
+       fTotalSampleCount(0)
+{
+}
+
+
+void
+BasicProfileResult::AddDroppedTicks(int32 dropped)
+{
+       fDroppedTicks += dropped;
+}
+
+
+void
+BasicProfileResult::PrintResults()
+{
+       // get hit images
+       BasicProfileResultImage* images[fOldImages.Count() + fImages.Count()];
+       int32 imageCount = GetHitImages(images);
+
+       // count symbols
+       int32 symbolCount = 0;
+       for (int32 k = 0; k < imageCount; k++) {
+               BasicProfileResultImage* image = images[k];
+               if (image->TotalHits() > image->UnknownHits())
+                       symbolCount += image->GetImage()->SymbolCount();
+       }
+
+       // find and sort the hit symbols
+       HitSymbol hitSymbols[symbolCount];
+       int32 hitSymbolCount = 0;
+
+       for (int32 k = 0; k < imageCount; k++) {
+               BasicProfileResultImage* 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];
+                                       hitSymbol.imageID = image->ID();
+                               }
+                       }
+               }
+       }
+
+       if (hitSymbolCount > 1)
+               std::sort(hitSymbols, hitSymbols + hitSymbolCount);
+
+       int64 totalTicks = fTotalTicks;
+       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);
+       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++) {
+                       BasicProfileResultImage* image = images[k];
+                       fprintf(gOptions.output, "  %10lld  %10lld  %7ld %s\n",
+                               image->TotalHits(), image->UnknownHits(),
+                               image->GetImage()->ID(), 
image->GetImage()->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, 
hitSymbol.imageID,
+                               symbol->Name());
+               }
+       } else
+               fprintf(gOptions.output, "  no functions were hit\n");
+}
+
+
+BasicProfileResultImage*
+BasicProfileResult::CreateProfileResultImage(Image* image)
+{
+       return new(std::nothrow) BasicProfileResultImage(image);
+}
+
+
+// #pragma mark - InclusiveProfileResult
+
+
+void
+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
+       // same symbol twice. Same for images.
+       std::sort(samples, samples + sampleCount);
+
+       int32 unknownSamples = 0;
+       BasicProfileResultImage* previousImage = NULL;
+       int32 previousSymbol = -1;
+
+       for (int32 i = 0; i < sampleCount; i++) {
+               addr_t address = samples[i];
+               BasicProfileResultImage* image = FindImage(address);
+               int32 symbol = -1;
+               if (image != NULL) {
+                       symbol = image->GetImage()->FindSymbol(address);
+                       if (symbol < 0) {
+                               // TODO: Count unknown image hits?
+                       } else if (image != previousImage || 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 - ExclusiveProfileResult
+
+
+void
+ExclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
+{
+       BasicProfileResultImage* image = NULL;
+               // the image in which we hit a symbol
+       BasicProfileResultImage* firstImage = NULL;
+               // the first image we hit, != image if no symbol was hit
+
+       for (int32 k = 0; k < sampleCount; k++) {
+               addr_t address = samples[k];
+               image = FindImage(address);
+               if (image != NULL) {
+                       if (image->AddHit(address))
+                               break;
+                       if (firstImage == NULL)
+                               firstImage = image;
+               }
+       }
+
+       if (image == NULL) {
+               if (firstImage != NULL)
+                       firstImage->AddUnknownHit();
+               else
+                       fUnkownTicks++;
+       }
+
+       fTotalTicks++;
+       fTotalSampleCount += sampleCount;
+}

Copied: haiku/trunk/src/bin/debug/profile/BasicProfileResult.h (from rev 35519, 
haiku/trunk/src/bin/debug/profile/BasicThreadProfileResult.h)
===================================================================
--- haiku/trunk/src/bin/debug/profile/BasicProfileResult.h                      
        (rev 0)
+++ haiku/trunk/src/bin/debug/profile/BasicProfileResult.h      2010-02-20 
20:31:04 UTC (rev 35546)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef BASIC_PROFILE_RESULT_H
+#define BASIC_PROFILE_RESULT_H
+
+
+#include "ProfileResult.h"
+
+
+class BasicProfileResultImage : public ProfileResultImage,
+       public DoublyLinkedListLinkImpl<BasicProfileResultImage> {
+public:
+                                                               
BasicProfileResultImage(Image* image);
+       virtual                                         
~BasicProfileResultImage();
+
+       virtual status_t                        Init();
+
+       inline  bool                            AddHit(addr_t address);
+       inline  void                            AddUnknownHit();
+       inline  void                            AddSymbolHit(int32 symbolIndex);
+       inline  void                            AddImageHit();
+
+       inline  const int64*            SymbolHits() const;
+       inline  int64                           UnknownHits() const;
+
+private:
+                       int64*                          fSymbolHits;
+                       int64                           fUnknownHits;
+};
+
+
+class BasicProfileResult
+       : public AbstractProfileResult<BasicProfileResultImage> {
+public:
+                                                               
BasicProfileResult();
+
+       virtual void                            AddDroppedTicks(int32 dropped);
+       virtual void                            PrintResults();
+
+       virtual BasicProfileResultImage* CreateProfileResultImage(Image* image);
+
+protected:
+                       int64                           fTotalTicks;
+                       int64                           fUnkownTicks;
+                       int64                           fDroppedTicks;
+                       int64                           fTotalSampleCount;
+};
+
+
+class InclusiveProfileResult : public BasicProfileResult {
+public:
+       virtual void                            AddSamples(addr_t* samples,
+                                                                       int32 
sampleCount);
+};
+
+
+class ExclusiveProfileResult : public BasicProfileResult {
+public:
+       virtual void                            AddSamples(addr_t* samples,
+                                                                       int32 
sampleCount);
+};
+
+
+#endif // BASIC_PROFILE_RESULT_H

Copied: haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.cpp (from rev 
35519, haiku/trunk/src/bin/debug/profile/CallgrindThreadProfileResult.cpp)
===================================================================
--- haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.cpp                
                (rev 0)
+++ haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.cpp        
2010-02-20 20:31:04 UTC (rev 35546)
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "CallgrindProfileResult.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <algorithm>
+#include <new>
+
+#include "Options.h"
+#include "ProfiledEntity.h"
+
+
+// #pragma mark - CallgrindProfileResultImage
+
+
+CallgrindProfileResultImage::CallgrindProfileResultImage(Image* image)
+       :
+       ProfileResultImage(image),
+       fFunctions(NULL),
+       fOutputIndex(0)
+{
+}
+
+
+CallgrindProfileResultImage::~CallgrindProfileResultImage()
+{
+       int32 symbolCount = fImage->SymbolCount();
+       for (int32 i = 0; i < symbolCount; i++) {
+               while (CallgrindCalledFunction* calledFunction
+                               = fFunctions[i].calledFunctions) {
+                       fFunctions[i].calledFunctions = calledFunction->next;
+                       delete calledFunction;
+               }
+       }
+
+       delete[] fFunctions;
+}
+
+
+status_t
+CallgrindProfileResultImage::Init()
+{
+       int32 symbolCount = fImage->SymbolCount();
+       fFunctions = new(std::nothrow) CallgrindFunction[symbolCount];
+       if (fFunctions == NULL)
+               return B_NO_MEMORY;
+
+       memset(fFunctions, 0, sizeof(CallgrindFunction) * symbolCount);
+
+       return B_OK;
+}
+
+
+void
+CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex,
+       CallgrindProfileResultImage* calledImage, int32 calledSymbol)
+
+{
+       fTotalHits++;
+
+       CallgrindFunction& function = fFunctions[symbolIndex];
+       if (calledImage != NULL) {
+               // check whether the called function is known already
+               CallgrindCalledFunction* calledFunction = 
function.calledFunctions;
+               while (calledFunction != NULL) {
+                       if (calledFunction->image == calledImage
+                               && calledFunction->function == calledSymbol) {
+                               break;
+                       }
+                       calledFunction = calledFunction->next;
+               }
+
+               // create a new CallgrindCalledFunction object, if not known
+               if (calledFunction == NULL) {
+                       calledFunction = new(std::nothrow) 
CallgrindCalledFunction(
+                               calledImage, calledSymbol);
+                       if (calledFunction == NULL)
+                               return;
+
+                       calledFunction->next = function.calledFunctions;
+                       function.calledFunctions = calledFunction;
+               }
+
+               calledFunction->hits++;
+       } else
+               function.hits++;
+}
+
+
+CallgrindFunction*
+CallgrindProfileResultImage::Functions() const
+{
+       return fFunctions;
+}
+
+
+int32
+CallgrindProfileResultImage::OutputIndex() const
+{
+       return fOutputIndex;
+}
+
+
+void
+CallgrindProfileResultImage::SetOutputIndex(int32 index)
+{
+       fOutputIndex = index;
+}
+
+
+// #pragma mark - CallgrindProfileResult
+
+
+CallgrindProfileResult::CallgrindProfileResult()
+       :
+       fTotalTicks(0),
+       fUnkownTicks(0),
+       fDroppedTicks(0),
+       fNextImageOutputIndex(1),
+       fNextFunctionOutputIndex(1)
+{
+}
+
+
+void
+CallgrindProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
+{
+       int32 unknownSamples = 0;
+       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];
+               CallgrindProfileResultImage* image = FindImage(address);
+               int32 symbol = -1;
+               if (image != NULL) {
+                       symbol = image->GetImage()->FindSymbol(address);
+                       if (symbol >= 0) {
+                               image->AddSymbolHit(symbol, previousImage, 
previousSymbol);
+                               previousImage = image;
+                               previousSymbol = symbol;
+                       }
+               } else
+                       unknownSamples++;
+       }
+
+       if (unknownSamples == sampleCount)
+               fUnkownTicks++;
+
+       fTotalTicks++;
+}
+
+
+void
+CallgrindProfileResult::AddDroppedTicks(int32 dropped)
+{
+       fDroppedTicks += dropped;
+}
+
+
+void
+CallgrindProfileResult::PrintResults()
+{
+       // create output file
+
+       // create output dir
+       mkdir(gOptions.callgrind_directory, S_IRWXU | S_IRWXG | S_IROTH | 
S_IXOTH);
+
+       // 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, fEntity->EntityID(), entityName,
+               fTotalTicks * fInterval);
+
+       // create the file
+       FILE* out = fopen(fileName, "w+");
+       if (out == NULL) {
+               fprintf(stderr, "%s: Failed to open output file \"%s\": %s\n",
+                       kCommandName, fileName, strerror(errno));
+               return;
+       }
+
+       // write the header
+       fprintf(out, "version: 1\n");
+       fprintf(out, "creator: Haiku profile\n");
+       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");
+       fprintf(out, "events: Ticks Time\n");
+       fprintf(out, "summary: %lld %lld\n", fTotalTicks, fTotalTicks * 
fInterval);
+
+       // get hit images
+       CallgrindProfileResultImage* images[fOldImages.Count() + 
fImages.Count()];
+       int32 imageCount = GetHitImages(images);
+
+       for (int32 i = 0; i < imageCount; i++) {
+               CallgrindProfileResultImage* image = images[i];
+
+               CallgrindFunction* functions = image->Functions();
+               int32 imageSymbolCount = image->GetImage()->SymbolCount();
+               for (int32 k = 0; k < imageSymbolCount; k++) {
+                       CallgrindFunction& function = functions[k];
+                       if (function.hits == 0 && function.calledFunctions == 
NULL)
+                               continue;
+
+                       fprintf(out, "\n");
+                       _PrintFunction(out, image, k, false);
+                       fprintf(out, "0 %lld %lld\n", function.hits,
+                               function.hits * fInterval);
+
+                       CallgrindCalledFunction* calledFunction = 
function.calledFunctions;
+                       while (calledFunction != NULL) {
+                               _PrintFunction(out, calledFunction->image,
+                                       calledFunction->function, true);
+                               fprintf(out, "calls=%lld 0\n", 
calledFunction->hits);
+                               fprintf(out, "0 %lld %lld\n", 
calledFunction->hits,
+                                       calledFunction->hits * fInterval);
+                               calledFunction = calledFunction->next;
+                       }
+               }
+       }
+
+       // print pseudo-functions for unknown and dropped ticks
+       if (fUnkownTicks + fDroppedTicks > 0) {
+               fprintf(out, "\nob=<pseudo>\n");
+
+               if (fUnkownTicks > 0) {
+                       fprintf(out, "\nfn=unknown\n");
+                       fprintf(out, "0 %lld\n", fUnkownTicks);
+               }
+
+               if (fDroppedTicks > 0) {
+                       fprintf(out, "\nfn=dropped\n");
+                       fprintf(out, "0 %lld\n", fDroppedTicks);
+               }
+       }
+
+       fprintf(out, "\ntotals: %lld %lld\n", fTotalTicks, fTotalTicks * 
fInterval);
+
+       fclose(out);
+}
+
+
+CallgrindProfileResultImage*
+CallgrindProfileResult::CreateProfileResultImage(Image* image)
+{
+       return new(std::nothrow) CallgrindProfileResultImage(image);
+}
+
+
+void
+CallgrindProfileResult::_PrintFunction(FILE* out,
+       CallgrindProfileResultImage* image, int32 functionIndex, bool called)
+{
+       if (image->OutputIndex() == 0) {
+               // need to print the image name
+               int32 index = fNextImageOutputIndex++;
+               image->SetOutputIndex(index);
+               fprintf(out, "%sob=(%ld) %s:%ld\n", called ? "c" : "", index,
+                       image->GetImage()->Name(), image->ID());
+       } else {
+               // image is already known
+               // TODO: We may not need to print it at all!
+               fprintf(out, "%sob=(%ld)\n", called ? "c" : "", 
image->OutputIndex());
+       }
+
+       CallgrindFunction& function = image->Functions()[functionIndex];
+       if (function.outputIndex == 0) {
+               // need to print the function name
+               function.outputIndex = fNextFunctionOutputIndex++;
+               fprintf(out, "%sfn=(%ld) %s\n", called ? "c" : "", 
function.outputIndex,
+                       image->GetImage()->Symbols()[functionIndex]->Name());
+       } else {
+               // function is already known
+               fprintf(out, "%sfn=(%ld)\n", called ? "c" : "", 
function.outputIndex);
+       }
+}

Copied: haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.h (from rev 
35519, haiku/trunk/src/bin/debug/profile/CallgrindThreadProfileResult.h)
===================================================================
--- haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.h                  
        (rev 0)
+++ haiku/trunk/src/bin/debug/profile/CallgrindProfileResult.h  2010-02-20 
20:31:04 UTC (rev 35546)
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef CALLGRIND_PROFILE_RESULT_H
+#define CALLGRIND_PROFILE_RESULT_H
+
+
+#include <stdio.h>
+
+#include "ProfileResult.h"
+
+
+class CallgrindProfileResultImage;
+
+
+struct CallgrindCalledFunction {
+       CallgrindCalledFunction*                next;
+       CallgrindProfileResultImage*    image;
+       int32                                                   function;
+       int64                                                   hits;
+
+       CallgrindCalledFunction(CallgrindProfileResultImage* image, int32 
function)
+               :
+               next(NULL),
+               image(image),
+               function(function),
+               hits(0)
+       {
+       }
+};
+
+
+struct CallgrindFunction {
+       int64                                           hits;
+       CallgrindCalledFunction*        calledFunctions;
+       int32                                           outputIndex;
+                                                                       // 
index when generating the output file
+};
+
+
+class CallgrindProfileResultImage : public ProfileResultImage,
+       public DoublyLinkedListLinkImpl<CallgrindProfileResultImage> {
+public:
+                                                               
CallgrindProfileResultImage(Image* image);
+       virtual                                         
~CallgrindProfileResultImage();
+
+       virtual status_t                        Init();
+
+       inline  void                            AddSymbolHit(int32 symbolIndex,
+                                                                       
CallgrindProfileResultImage* calledImage,
+                                                                       int32 
calledSymbol);
+
+       inline  CallgrindFunction*      Functions() const;
+
+       inline  int32                           OutputIndex() const;
+       inline  void                            SetOutputIndex(int32 index);
+
+private:
+                       CallgrindFunction*      fFunctions;
+                       int32                           fOutputIndex;
+};
+
+
+class CallgrindProfileResult
+       : public AbstractProfileResult<CallgrindProfileResultImage> {
+public:
+                                                               
CallgrindProfileResult();
+
+       virtual void                            AddSamples(addr_t* samples,
+                                                                       int32 
sampleCount);
+       virtual void                            AddDroppedTicks(int32 dropped);
+       virtual void                            PrintResults();
+
+       virtual CallgrindProfileResultImage* CreateProfileResultImage(Image* 
image);
+
+private:
+                       void                            _PrintFunction(FILE* 
out,
+                                                                       
CallgrindProfileResultImage* image,
+                                                                       int32 
functionIndex, bool called);
+private:
+                       int64                           fTotalTicks;
+                       int64                           fUnkownTicks;
+                       int64                           fDroppedTicks;
+                       int32                           fNextImageOutputIndex;
+                       int32                           
fNextFunctionOutputIndex;
+};
+
+
+#endif // CALLGRIND_PROFILE_RESULT_H

Modified: haiku/trunk/src/bin/debug/profile/Jamfile
===================================================================
--- haiku/trunk/src/bin/debug/profile/Jamfile   2010-02-20 19:53:48 UTC (rev 
35545)
+++ haiku/trunk/src/bin/debug/profile/Jamfile   2010-02-20 20:31:04 UTC (rev 
35546)
@@ -10,9 +10,11 @@
 
 BinCommand profile
        :
-       BasicThreadProfileResult.cpp
-       CallgrindThreadProfileResult.cpp
+       BasicProfileResult.cpp
+       CallgrindProfileResult.cpp
        Image.cpp
+       ProfiledEntity.cpp
+       ProfileResult.cpp
        SharedImage.cpp
        Team.cpp
        Thread.cpp

Added: haiku/trunk/src/bin/debug/profile/ProfileResult.cpp
===================================================================
--- haiku/trunk/src/bin/debug/profile/ProfileResult.cpp                         
(rev 0)
+++ haiku/trunk/src/bin/debug/profile/ProfileResult.cpp 2010-02-20 20:31:04 UTC 
(rev 35546)
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * 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;
+}

Added: haiku/trunk/src/bin/debug/profile/ProfileResult.h
===================================================================
--- haiku/trunk/src/bin/debug/profile/ProfileResult.h                           
(rev 0)
+++ haiku/trunk/src/bin/debug/profile/ProfileResult.h   2010-02-20 20:31:04 UTC 
(rev 35546)
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef PROFILE_RESULT_H
+#define PROFILE_RESULT_H
+
+
+#include <util/DoublyLinkedList.h>
+
+#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<typename ProfileResultImageType>
+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
+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<typename ProfileResultImageType>
+AbstractProfileResult<ProfileResultImageType>::AbstractProfileResult()
+       :
+       fImages(),
+       fNewImages(),
+       fOldImages(),

[... truncated: 701 lines follow ...]

Other related posts:

  • » [haiku-commits] r35546 - haiku/trunk/src/bin/debug/profile - ingo_weinhold