xref: /haiku/src/bin/debug/profile/Thread.cpp (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
1 /*
2  * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "Thread.h"
7 
8 #include <algorithm>
9 #include <new>
10 
11 #include <debug_support.h>
12 
13 #include "debug_utils.h"
14 
15 #include "Options.h"
16 #include "Team.h"
17 
18 
19 // #pragma mark - ThreadImage
20 
21 
22 ThreadImage::ThreadImage(Image* image)
23 	:
24 	fImage(image),
25 	fTotalHits(0)
26 {
27 	fImage->AddReference();
28 }
29 
30 
31 ThreadImage::~ThreadImage()
32 {
33 	fImage->RemoveReference();
34 }
35 
36 
37 status_t
38 ThreadImage::Init()
39 {
40 	return B_OK;
41 }
42 
43 
44 // #pragma mark - Thread
45 
46 
47 Thread::Thread(thread_id threadID, const char* name, Team* team)
48 	:
49 	fID(threadID),
50 	fName(name),
51 	fTeam(team),
52 	fSampleArea(-1),
53 	fSamples(NULL),
54 	fProfileResult(NULL)
55 {
56 }
57 
58 
59 Thread::~Thread()
60 {
61 	if (fSampleArea >= 0)
62 		delete_area(fSampleArea);
63 
64 	delete fProfileResult;
65 }
66 
67 
68 void
69 Thread::SetProfileResult(ThreadProfileResult* result)
70 {
71 	delete fProfileResult;
72 	fProfileResult = result;
73 }
74 
75 
76 void
77 Thread::UpdateInfo(const char* name)
78 {
79 	fName = name;
80 }
81 
82 
83 void
84 Thread::SetSampleArea(area_id area, addr_t* samples)
85 {
86 	fSampleArea = area;
87 	fSamples = samples;
88 }
89 
90 
91 void
92 Thread::SetInterval(bigtime_t interval)
93 {
94 	fProfileResult->SetInterval(interval);
95 }
96 
97 
98 void
99 Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
100 	bool variableStackDepth, int32 event)
101 {
102 	fProfileResult->SynchronizeImages(event);
103 
104 	if (variableStackDepth) {
105 		addr_t* samples = fSamples;
106 
107 		while (count > 0) {
108 			addr_t sampleCount = *(samples++);
109 
110 			if (sampleCount >= B_DEBUG_PROFILE_EVENT_BASE) {
111 				int32 eventParameterCount
112 					= sampleCount & B_DEBUG_PROFILE_EVENT_PARAMETER_MASK;
113 				if (sampleCount == B_DEBUG_PROFILE_IMAGE_EVENT) {
114 					fProfileResult->SynchronizeImages((int32)samples[0]);
115 				} else {
116 					fprintf(stderr, "unknown profile event: %#lx\n",
117 						sampleCount);
118 				}
119 
120 				samples += eventParameterCount;
121 				count -= eventParameterCount + 1;
122 				continue;
123 			}
124 
125 			fProfileResult->AddSamples(samples, sampleCount);
126 
127 			samples += sampleCount;
128 			count -= sampleCount + 1;
129 		}
130 	} else {
131 		count = count / stackDepth * stackDepth;
132 
133 		for (int32 i = 0; i < count; i += stackDepth)
134 			fProfileResult->AddSamples(fSamples + i, stackDepth);
135 	}
136 
137 	fProfileResult->AddDroppedTicks(dropped);
138 }
139 
140 
141 void
142 Thread::AddSamples(addr_t* samples, int32 sampleCount)
143 {
144 	fProfileResult->AddSamples(samples, sampleCount);
145 }
146 
147 
148 void
149 Thread::PrintResults() const
150 {
151 	fProfileResult->PrintResults();
152 }
153 
154 
155 // #pragma mark - ThreadProfileResult
156 
157 
158 ThreadProfileResult::ThreadProfileResult()
159 	:
160 	fThread(NULL),
161 	fInterval(1)
162 {
163 }
164 
165 
166 ThreadProfileResult::~ThreadProfileResult()
167 {
168 }
169 
170 
171 status_t
172 ThreadProfileResult::Init(Thread* thread)
173 {
174 	fThread = thread;
175 	return B_OK;
176 }
177 
178 
179 void
180 ThreadProfileResult::SetInterval(bigtime_t interval)
181 {
182 	fInterval = interval;
183 }
184