]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: convert note to Go
authorDmitriy Vyukov <dvyukov@google.com>
Fri, 22 Aug 2014 18:13:01 +0000 (22:13 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Fri, 22 Aug 2014 18:13:01 +0000 (22:13 +0400)
Note is required for timers and heap scavenger.

LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews, khr, rlh
https://golang.org/cl/128620043

src/cmd/api/goapi.go
src/pkg/runtime/export_test.go
src/pkg/runtime/lock_futex.c
src/pkg/runtime/lock_sema.c
src/pkg/runtime/proc.c
src/pkg/runtime/runtime.h
src/pkg/runtime/stubs.go

index 07f007fdfb182184a9dc96e5d80a63e63c473536..7117254e5343fc38e09248093e7008fed7400bbc 100644 (file)
@@ -383,6 +383,7 @@ func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
                        " mspan struct{}; m struct{}; lock struct{}; slicetype struct{};" +
                        " iface struct{}; eface struct{}; interfacetype struct{}; itab struct{};" +
                        " mcache struct{}; bucket struct{}; sudog struct{}; g struct{};" +
+                       " note struct{};" +
                        ")"
                f, err = parser.ParseFile(fset, filename, src, 0)
                if err != nil {
index 4ca5a7354f191ac761a34f14a2ec4371af0f4d95..9d25cafebb823198735d8b14e64e9e570c5eed5e 100644 (file)
@@ -19,7 +19,6 @@ var Fintto64 = fintto64
 var F64toint = f64toint
 
 func entersyscall()
-func exitsyscall()
 func golockedOSThread() bool
 func stackguard() (sp, limit uintptr)
 
index 7fc2d5547d6746ba4a7884a2100a4f8352d051d0..2f4de0310493140353e6d77b72590449c9092488 100644 (file)
@@ -125,6 +125,16 @@ runtime·notewakeup(Note *n)
        runtime·futexwakeup((uint32*)&n->key, 1);
 }
 
+void
+runtime·notewakeup_m(void)
+{
+       Note *n;
+
+       n = g->m->ptrarg[0];
+       g->m->ptrarg[0] = nil;
+       runtime·notewakeup(n);
+}
+
 void
 runtime·notesleep(Note *n)
 {
@@ -199,3 +209,19 @@ runtime·notetsleepg(Note *n, int64 ns)
        runtime·exitsyscall();
        return res;
 }
+
+void
+runtime·notetsleepg_m(void)
+{
+       Note *n;
+       int64 ns;
+
+       n = g->m->ptrarg[0];
+       g->m->ptrarg[0] = nil;
+       ns = g->m->scalararg[0] + ((int64)g->m->scalararg[1] << 32);
+
+       runtime·entersyscallblock_m(pc, sp);
+       notetsleep(n, ns, 0, 0);
+       // caller will call exitsyscall on g stack
+       runtime·gogo(&g->m->curg->sched);
+}
index a4274e6555f693936e2863ee99553fe96d57bef1..98eea91d5f0c366df7c3dc847c3956cbfac04a58 100644 (file)
@@ -147,6 +147,16 @@ runtime·notewakeup(Note *n)
        }
 }
 
+void
+runtime·notewakeup_m(void)
+{
+       Note *n;
+
+       n = g->m->ptrarg[0];
+       g->m->ptrarg[0] = nil;
+       runtime·notewakeup(n);
+}
+
 void
 runtime·notesleep(Note *n)
 {
@@ -264,3 +274,22 @@ runtime·notetsleepg(Note *n, int64 ns)
        runtime·exitsyscall();
        return res;
 }
+
+void
+runtime·notetsleepg_m(void)
+{
+       Note *n;
+       int64 ns;
+
+       n = g->m->ptrarg[0];
+       g->m->ptrarg[0] = nil;
+       ns = g->m->scalararg[0] + ((int64)g->m->scalararg[1] << 32);
+
+       if(g->m->waitsema == 0)
+               g->m->waitsema = runtime·semacreate();
+
+       runtime·entersyscallblock_m();
+       notetsleep(n, ns, 0, nil);
+       // caller will call exitsyscall on g stack
+       runtime·gogo(&g->m->curg->sched);
+}
index 5ff38fb692265130da196964f22ac85a266db114..df85042340c3fe51a2a0727e33b0092c549b0f6a 100644 (file)
@@ -1630,6 +1630,31 @@ void
        g->m->locks--;
 }
 
+// The same as runtime·entersyscallblock(), but called on g0 stack.
+void
+runtime·entersyscallblock_m(void)
+{
+       G *gp;
+
+       gp = g->m->curg;
+       // sched.{g,pc,sp,lr} are already set by mcall.
+       gp->stackguard0 = StackPreempt;  // we are on g0, the goroutine must not touch its stack until exitsyscall
+       gp->sched.ret = 0;
+       gp->sched.ctxt = 0;
+       gp->syscallsp = gp->sched.sp;
+       gp->syscallpc = gp->sched.pc;
+       gp->syscallstack = gp->stackbase;
+       gp->syscallguard = gp->stackguard;
+       gp->status = Gsyscall;
+       if(gp->syscallsp < gp->syscallguard-StackGuard || gp->syscallstack < gp->syscallsp) {
+               // runtime·printf("entersyscall inconsistent %p [%p,%p]\n",
+               //      gp->syscallsp, gp->syscallguard-StackGuard, gp->syscallstack);
+               runtime·throw("entersyscall_m");
+       }
+
+       handoffp(releasep());
+}
+
 // The goroutine g exited its system call.
 // Arrange for it to run on a cpu again.
 // This is called only from the go syscall library, not
index d38eb454b771343cfebb052c57826f6bb88cbb4a..35574f4cd66fe3810fcc8401b20eb8dc26b20930 100644 (file)
@@ -931,6 +931,7 @@ void        runtime·asmcgocall(void (*fn)(void*), void*);
 void   runtime·entersyscall(void);
 void   runtime·entersyscallblock(void);
 void   runtime·exitsyscall(void);
+void   runtime·entersyscallblock_m(void);
 G*     runtime·newproc1(FuncVal*, byte*, int32, int32, void*);
 bool   runtime·sigsend(int32 sig);
 int32  runtime·callers(int32, uintptr*, int32);
index f3ac783aca54bdb99a6f49d796a9cfc758df05ec..a31589ca86cfbe44b5bbfd17e81404656d2501ba 100644 (file)
@@ -73,7 +73,9 @@ var (
        gosched_m,
        ready_m,
        park_m,
-       blockevent_m mFunction
+       blockevent_m,
+       notewakeup_m,
+       notetsleepg_m mFunction
 )
 
 // memclr clears n bytes starting at ptr.
@@ -169,3 +171,26 @@ func noescape(p unsafe.Pointer) unsafe.Pointer {
 func gopersistentalloc(n uintptr) unsafe.Pointer
 
 func gocputicks() int64
+
+func gonoteclear(n *note) {
+       n.key = 0
+}
+
+func gonotewakeup(n *note) {
+       mp := acquirem()
+       mp.ptrarg[0] = unsafe.Pointer(n)
+       onM(&notewakeup_m)
+       releasem(mp)
+}
+
+func gonotetsleepg(n *note, t int64) {
+       mp := acquirem()
+       mp.ptrarg[0] = unsafe.Pointer(n)
+       mp.scalararg[0] = uint(uint32(t)) // low 32 bits
+       mp.scalararg[1] = uint(t >> 32)   // high 32 bits
+       releasem(mp)
+       mcall(&notetsleepg_m)
+       exitsyscall()
+}
+
+func exitsyscall()