runtime: introduce notetsleepg function
notetsleepg is the same as notetsleep, but is called on user g.
It includes entersyscall/exitsyscall and will help to avoid
split stack functions in syscall status.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/11681043
diff --git a/src/pkg/runtime/cpuprof.c b/src/pkg/runtime/cpuprof.c
index 6793e5d3..ef30773 100644
--- a/src/pkg/runtime/cpuprof.c
+++ b/src/pkg/runtime/cpuprof.c
@@ -358,9 +358,7 @@
 		return ret;
 
 	// Wait for new log.
-	runtime·entersyscallblock();
-	runtime·notesleep(&p->wait);
-	runtime·exitsyscall();
+	runtime·notetsleepg(&p->wait, -1);
 	runtime·noteclear(&p->wait);
 
 	n = p->handoff;
diff --git a/src/pkg/runtime/lock_futex.c b/src/pkg/runtime/lock_futex.c
index 95d590b..2265607 100644
--- a/src/pkg/runtime/lock_futex.c
+++ b/src/pkg/runtime/lock_futex.c
@@ -159,3 +159,16 @@
 		runtime·setprof(true);
 	return runtime·atomicload((uint32*)&n->key) != 0;
 }
+
+bool
+runtime·notetsleepg(Note *n, int64 ns)
+{
+	bool res;
+
+	if(g == m->g0)
+		runtime·throw("notetsleepg on g0");
+	runtime·entersyscallblock();
+	res = runtime·notetsleep(n, ns);
+	runtime·exitsyscall();
+	return res;
+}
diff --git a/src/pkg/runtime/lock_sema.c b/src/pkg/runtime/lock_sema.c
index 069b8c1..da5d24a 100644
--- a/src/pkg/runtime/lock_sema.c
+++ b/src/pkg/runtime/lock_sema.c
@@ -231,3 +231,16 @@
 		}
 	}
 }
+
+bool
+runtime·notetsleepg(Note *n, int64 ns)
+{
+	bool res;
+
+	if(g == m->g0)
+		runtime·throw("notetsleepg on g0");
+	runtime·entersyscallblock();
+	res = runtime·notetsleep(n, ns);
+	runtime·exitsyscall();
+	return res;
+}
diff --git a/src/pkg/runtime/mheap.c b/src/pkg/runtime/mheap.c
index e076d89f..6dd5fa9 100644
--- a/src/pkg/runtime/mheap.c
+++ b/src/pkg/runtime/mheap.c
@@ -460,9 +460,7 @@
 	h = &runtime·mheap;
 	for(k=0;; k++) {
 		runtime·noteclear(&note);
-		runtime·entersyscallblock();
-		runtime·notetsleep(&note, tick);
-		runtime·exitsyscall();
+		runtime·notetsleepg(&note, tick);
 
 		runtime·lock(h);
 		now = runtime·nanotime();
@@ -474,9 +472,7 @@
 			runtime·noteclear(&note);
 			notep = &note;
 			runtime·newproc1(&forcegchelperv, (byte*)&notep, sizeof(notep), 0, runtime·MHeap_Scavenger);
-			runtime·entersyscallblock();
-			runtime·notesleep(&note);
-			runtime·exitsyscall();
+			runtime·notetsleepg(&note, -1);
 			if(runtime·debug.gctrace > 0)
 				runtime·printf("scvg%d: GC forced\n", k);
 			runtime·lock(h);
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index f8d45ba..244b548 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -905,11 +905,15 @@
  * wake up early, it must wait to call noteclear until it
  * can be sure that no other goroutine is calling
  * notewakeup.
+ *
+ * notesleep/notetsleep are generally called on g0,
+ * notetsleepg is similar to notetsleep but is called on user g.
  */
 void	runtime·noteclear(Note*);
 void	runtime·notesleep(Note*);
 void	runtime·notewakeup(Note*);
 bool	runtime·notetsleep(Note*, int64);  // false - timeout
+bool	runtime·notetsleepg(Note*, int64);  // false - timeout
 
 /*
  * low-level synchronization for implementing the above
diff --git a/src/pkg/runtime/sigqueue.goc b/src/pkg/runtime/sigqueue.goc
index 9bfab3b..e430e21 100644
--- a/src/pkg/runtime/sigqueue.goc
+++ b/src/pkg/runtime/sigqueue.goc
@@ -106,9 +106,7 @@
 				new = HASWAITER;
 			if(runtime·cas(&sig.state, old, new)) {
 				if (new == HASWAITER) {
-					runtime·entersyscallblock();
-					runtime·notesleep(&sig);
-					runtime·exitsyscall();
+					runtime·notetsleepg(&sig, -1);
 					runtime·noteclear(&sig);
 				}
 				break;
diff --git a/src/pkg/runtime/time.goc b/src/pkg/runtime/time.goc
index be0c1f8..4f20300 100644
--- a/src/pkg/runtime/time.goc
+++ b/src/pkg/runtime/time.goc
@@ -214,9 +214,7 @@
 		timers.sleeping = true;
 		runtime·noteclear(&timers.waitnote);
 		runtime·unlock(&timers);
-		runtime·entersyscallblock();
-		runtime·notetsleep(&timers.waitnote, delta);
-		runtime·exitsyscall();
+		runtime·notetsleepg(&timers.waitnote, delta);
 	}
 }