aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/proc.c
blob: bbdf894f49d1a68a328db439d7cac07da79967c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"
#include "malloc.h"	/* so that acid generated from proc.c includes malloc data structures */

typedef struct Sched Sched;

M	m0;

#ifdef __rtems__
#define __thread
#endif

__thread M *m = &m0;

static struct {
	Lock;
	void (*fn)(uintptr*, int32);
	int32 hz;
	uintptr pcbuf[100];
} prof;

void
runtime_sigprof(uint8 *pc __attribute__ ((unused)),
		uint8 *sp __attribute__ ((unused)),
		uint8 *lr __attribute__ ((unused)))
{
	int32 n;
	
	if(prof.fn == nil || prof.hz == 0)
		return;
	
	runtime_lock(&prof);
	if(prof.fn == nil) {
		runtime_unlock(&prof);
		return;
	}
	n = 0;
	// n = runtime·gentraceback(pc, sp, lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf));
	if(n > 0)
		prof.fn(prof.pcbuf, n);
	runtime_unlock(&prof);
}

void
runtime_setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz)
{
	// Force sane arguments.
	if(hz < 0)
		hz = 0;
	if(hz == 0)
		fn = nil;
	if(fn == nil)
		hz = 0;

	// Stop profiler on this cpu so that it is safe to lock prof.
	// if a profiling signal came in while we had prof locked,
	// it would deadlock.
	runtime_resetcpuprofiler(0);

	runtime_lock(&prof);
	prof.fn = fn;
	prof.hz = hz;
	runtime_unlock(&prof);
	// runtime_lock(&runtime_sched);
	// runtime_sched.profilehz = hz;
	// runtime_unlock(&runtime_sched);
	
	if(hz != 0)
		runtime_resetcpuprofiler(hz);
}