Update contrib.
1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "distribution.h"
23 #else //!__MSVCDOTNET__
26 #endif //__MSVCDOTNET__
34 int* BucketBox(int aSize)
36 int* buckets = new int[aSize];
37 memset(buckets, 0, sizeof(int) * aSize);
50 inline int operator()()
58 inline Sorter(const int* aTotals)
61 inline bool operator()(int aLhs, int aRhs) const
62 {return (iTotals[aLhs] > iTotals[aRhs]);}
67 BucketTotals(Distribution::Data& aData, int aSize);
71 inline int Total() const;
72 inline int Map(int aBucket) const;
73 inline int operator[](int aBucket) const;
74 inline Result Sample(int aSample) const;
76 void Total(Distribution::Data& aData);
84 BucketTotals::BucketTotals(Distribution::Data& aData, int aSize)
85 :iSize(aSize), iTotals(BucketBox(aSize)), iOrdering(BucketBox(aSize))
88 std::generate_n(iOrdering, iSize, Generator());
91 BucketTotals::~BucketTotals()
97 void BucketTotals::Total(Distribution::Data& aData)
100 for (Distribution::Data::iterator p = aData.begin(), e = aData.end(); p != e; ++p)
102 const int* box = p->iBuckets;
104 for (int j = p->iBucketsLength; --j >=0;)
106 threadTotal += box[j];
107 iTotals[j] += box[j];
109 p->iTotal = threadTotal;
110 total += threadTotal;
115 void BucketTotals::Sort()
117 std::sort(iOrdering, iOrdering + iSize, Sorter(iTotals));
120 inline int BucketTotals::Total() const
123 inline int BucketTotals::Map(int aBucket) const
124 {return iOrdering[aBucket];}
126 inline int BucketTotals::operator[](int aBucket) const
127 {return iTotals[iOrdering[aBucket]];}
129 inline Result BucketTotals::Sample(int aSample) const
130 {return Result(aSample, iTotal);}
134 inline Distribution::ThreadData::ThreadData(const Thread& aThread, int aSize)
135 :iThread(&aThread), iBuckets(BucketBox(aSize)), iTotal(0), iBucketsLength(aSize)
138 inline Distribution::ThreadData::ThreadData(int aCutoff)
142 inline bool Distribution::ThreadData::operator<(const Distribution::ThreadData& aRhs) const
143 {return (iTotal > aRhs.iTotal);}
145 Distribution::Distribution(CodeSpace& aCodeSpace, double aCutOff)
146 :iCodeSpace(aCodeSpace), iCutOff(aCutOff)
148 cout << "Profile distribution\n\n";
151 void Distribution::Sample(unsigned , const Thread& aThread, PC aPc)
153 // Collect the sample in the bucket as allocated by the code space
156 if (aThread.iIndex == iData.size())
157 iData.push_back(ThreadData(aThread,iCodeSpace.Size()));
160 int bucket = iCodeSpace.Bucket(aPc);
161 if (bucket >= iData[aThread.iIndex].iBucketsLength)
163 int* new_buckets = new int[bucket+1];
164 memset(new_buckets, 0, sizeof(int) * (bucket+1));
165 memcpy(new_buckets, iData[aThread.iIndex].iBuckets, sizeof(int) * iData[aThread.iIndex].iBucketsLength);
166 delete [] iData[aThread.iIndex].iBuckets;
167 iData[aThread.iIndex].iBuckets = new_buckets;
168 iData[aThread.iIndex].iBucketsLength = bucket+1;
171 ++iData[aThread.iIndex].iBuckets[bucket];
174 void Distribution::Complete(unsigned aTotal, unsigned aActive)
176 // accumulate thread and bucket totals
177 const int nbuckets = iCodeSpace.Size();
178 BucketTotals totals(iData, nbuckets);
179 if (iCodeSpace.Ordering() == CodeSpace::ERandom)
182 int cutoff = int(iCutOff * totals.Total() * 0.01);
183 std::sort(iData.begin(), iData.end());
184 iData.erase(std::upper_bound(iData.begin(), iData.end(), ThreadData(cutoff)), iData.end());
186 cout.setf(ios::fixed, ios::floatfield);
189 cout << "Samples: " << aTotal << '\n';
190 cout << " Active: " << aActive << " (" << double(aActive*100)/aTotal << "%)\n";
191 cout << "Counted: " << totals.Total() << " (" << double(totals.Total()*100)/aTotal << "%)\n\n";
192 cout << setfill(' ');
195 if (!Analyse::Option(Analyse::ETotalOnly))
197 if (Analyse::Format() != Analyse::EExcel)
199 cout << "ID Thread name\n";
201 for (p = iData.begin(), e = iData.end(); p != e; ++p)
202 cout << id++ << " " << *p->iThread << '\n';
206 for (p = iData.begin(), e = iData.end(); p != e; ++p)
207 cout << setw(4) << id++ << " ";
208 cout << " total\n\n";
210 for (p = iData.begin(), e = iData.end(); p != e; ++p)
211 cout << totals.Sample(p->iTotal) << " ";
212 cout << " " << totals.Sample(totals.Total()) << " total\n\n";
217 for (p = iData.begin(), e = iData.end(); p != e; ++p)
218 cout << '\t' << *p->iThread;
223 if (cutoff == 0 && iCodeSpace.Ordering() != CodeSpace::ELinear)
226 for (int ix = 0; ix< nbuckets; ++ix)
228 int total = totals[ix];
231 int jx = totals.Map(ix);
232 if (jx == CodeSpace::KOtherBucket && Analyse::Option(Analyse::ENoOther))
234 if (Analyse::Format() == Analyse::EExcel)
236 cout << iCodeSpace.Name(jx);
237 if (!Analyse::Option(Analyse::ETotalOnly))
239 for (p = iData.begin(), e = iData.end(); p != e; ++p)
240 cout << '\t' << totals.Sample(jx>=p->iBucketsLength ? 0 : p->iBuckets[jx]);
242 cout << '\t' << totals.Sample(total) << '\n';
246 if (!Analyse::Option(Analyse::ETotalOnly))
248 for (p = iData.begin(), e = iData.end(); p != e; ++p)
249 cout << totals.Sample(jx>=p->iBucketsLength ? 0 : p->iBuckets[jx]) << " ";
252 cout << totals.Sample(total) << " " << iCodeSpace.Name(jx) << '\n';
257 if (!Analyse::Option(Analyse::ETotalOnly))
259 if (Analyse::Format() == Analyse::EExcel)
262 for (p = iData.begin(), e = iData.end(); p != e; ++p)
263 cout << '\t' << totals.Sample(p->iTotal);
264 cout << '\t' << totals.Sample(totals.Total()) << '\n';