summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/cpuprof.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/cpuprof.c')
-rw-r--r--src/pkg/runtime/cpuprof.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/pkg/runtime/cpuprof.c b/src/pkg/runtime/cpuprof.c
index 05fa0cf61..9a0606a22 100644
--- a/src/pkg/runtime/cpuprof.c
+++ b/src/pkg/runtime/cpuprof.c
@@ -99,6 +99,7 @@ struct Profile {
uint32 wtoggle;
bool wholding; // holding & need to release a log half
bool flushing; // flushing hash table - profile is over
+ bool eod_sent; // special end-of-data record sent; => flushing
};
static Lock lk;
@@ -109,16 +110,20 @@ static void add(Profile*, uintptr*, int32);
static bool evict(Profile*, Entry*);
static bool flushlog(Profile*);
+static uintptr eod[3] = {0, 1, 0};
+
// LostProfileData is a no-op function used in profiles
// to mark the number of profiling stack traces that were
// discarded due to slow data writers.
-static void LostProfileData(void) {
+static void
+LostProfileData(void)
+{
}
// SetCPUProfileRate sets the CPU profiling rate.
// The user documentation is in debug.go.
void
-runtime·SetCPUProfileRate(int32 hz)
+runtime·SetCPUProfileRate(intgo hz)
{
uintptr *p;
uintptr n;
@@ -163,6 +168,7 @@ runtime·SetCPUProfileRate(int32 hz)
prof->wholding = false;
prof->wtoggle = 0;
prof->flushing = false;
+ prof->eod_sent = false;
runtime·noteclear(&prof->wait);
runtime·setcpuprofilerate(tick, hz);
@@ -356,7 +362,7 @@ getprofile(Profile *p)
return ret;
// Wait for new log.
- runtime·entersyscall();
+ runtime·entersyscallblock();
runtime·notesleep(&p->wait);
runtime·exitsyscall();
runtime·noteclear(&p->wait);
@@ -409,6 +415,16 @@ breakflush:
}
// Made it through the table without finding anything to log.
+ if(!p->eod_sent) {
+ // We may not have space to append this to the partial log buf,
+ // so we always return a new slice for the end-of-data marker.
+ p->eod_sent = true;
+ ret.array = (byte*)eod;
+ ret.len = sizeof eod;
+ ret.cap = ret.len;
+ return ret;
+ }
+
// Finally done. Clean up and return nil.
p->flushing = false;
if(!runtime·cas(&p->handoff, p->handoff, 0))