LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // CPU profiling. | 5 // CPU profiling. |
6 // Based on algorithms and data structures used in | 6 // Based on algorithms and data structures used in |
7 // http://code.google.com/p/google-perftools/. | 7 // http://code.google.com/p/google-perftools/. |
8 // | 8 // |
9 // The main difference between this code and the google-perftools | 9 // The main difference between this code and the google-perftools |
10 // code is that this code is written to allow copying the profile data | 10 // code is that this code is written to allow copying the profile data |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 // Could not evict entry. Record lost stack. | 232 // Could not evict entry. Record lost stack. |
233 p.lost++ | 233 p.lost++ |
234 return | 234 return |
235 } | 235 } |
236 p.evicts++ | 236 p.evicts++ |
237 } | 237 } |
238 | 238 |
239 // Reuse the newly evicted entry. | 239 // Reuse the newly evicted entry. |
240 e.depth = uintptr(len(pc)) | 240 e.depth = uintptr(len(pc)) |
241 e.count = 1 | 241 e.count = 1 |
242 » for i := range pc { | 242 » copy(e.stack[:], pc) |
243 » » e.stack[i] = pc[i] | |
244 » } | |
245 } | 243 } |
246 | 244 |
247 // evict copies the given entry's data into the log, so that | 245 // evict copies the given entry's data into the log, so that |
248 // the entry can be reused. evict is called from add, which | 246 // the entry can be reused. evict is called from add, which |
249 // is called from the profiling signal handler, so it must not | 247 // is called from the profiling signal handler, so it must not |
250 // allocate memory or block. It is safe to call flushlog. | 248 // allocate memory or block. It is safe to call flushlog. |
251 // evict returns true if the entry was copied to the log, | 249 // evict returns true if the entry was copied to the log, |
252 // false if there was no room available. | 250 // false if there was no room available. |
253 func (p *cpuProfile) evict(e *cpuprofEntry) bool { | 251 func (p *cpuProfile) evict(e *cpuprofEntry) bool { |
254 d := e.depth | 252 d := e.depth |
255 nslot := d + 2 | 253 nslot := d + 2 |
256 log := &p.log[p.toggle] | 254 log := &p.log[p.toggle] |
257 if p.nlog+nslot > uintptr(len(p.log[0])) { | 255 if p.nlog+nslot > uintptr(len(p.log[0])) { |
258 if !p.flushlog() { | 256 if !p.flushlog() { |
259 return false | 257 return false |
260 } | 258 } |
261 log = &p.log[p.toggle] | 259 log = &p.log[p.toggle] |
262 } | 260 } |
263 | 261 |
264 q := p.nlog | 262 q := p.nlog |
265 log[q] = e.count | 263 log[q] = e.count |
266 q++ | 264 q++ |
267 log[q] = d | 265 log[q] = d |
268 q++ | 266 q++ |
269 » for i := uintptr(0); i < d; i++ { | 267 » copy(log[q:], e.stack[:d]) |
270 » » log[q] = e.stack[i] | 268 » q += d |
271 » » q++ | |
272 » } | |
273 p.nlog = q | 269 p.nlog = q |
274 e.count = 0 | 270 e.count = 0 |
275 return true | 271 return true |
276 } | 272 } |
277 | 273 |
278 // flushlog tries to flush the current log and switch to the other one. | 274 // flushlog tries to flush the current log and switch to the other one. |
279 // flushlog is called from evict, called from add, called from the signal handle
r, | 275 // flushlog is called from evict, called from add, called from the signal handle
r, |
280 // so it cannot allocate memory or block. It can try to swap logs with | 276 // so it cannot allocate memory or block. It can try to swap logs with |
281 // the writing goroutine, as explained in the comment at the top of this file. | 277 // the writing goroutine, as explained in the comment at the top of this file. |
282 func (p *cpuProfile) flushlog() bool { | 278 func (p *cpuProfile) flushlog() bool { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 // blocking until data is available. If profiling is turned off and all the pro
file | 410 // blocking until data is available. If profiling is turned off and all the pro
file |
415 // data accumulated while it was on has been returned, CPUProfile returns nil. | 411 // data accumulated while it was on has been returned, CPUProfile returns nil. |
416 // The caller must save the returned data before calling CPUProfile again. | 412 // The caller must save the returned data before calling CPUProfile again. |
417 // | 413 // |
418 // Most clients should use the runtime/pprof package or | 414 // Most clients should use the runtime/pprof package or |
419 // the testing package's -test.cpuprofile flag instead of calling | 415 // the testing package's -test.cpuprofile flag instead of calling |
420 // CPUProfile directly. | 416 // CPUProfile directly. |
421 func CPUProfile() []byte { | 417 func CPUProfile() []byte { |
422 return cpuprof.getprofile() | 418 return cpuprof.getprofile() |
423 } | 419 } |
LEFT | RIGHT |