]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: change Note from union to struct
authorDmitriy Vyukov <dvyukov@google.com>
Sun, 7 Apr 2013 03:09:02 +0000 (20:09 -0700)
committerDmitriy Vyukov <dvyukov@google.com>
Sun, 7 Apr 2013 03:09:02 +0000 (20:09 -0700)
Unions can break precise GC.
Update #5193.

R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/8362046

src/pkg/runtime/lock_futex.c
src/pkg/runtime/lock_sema.c
src/pkg/runtime/runtime.h

index 07aab2d7be34220c948b39b53e4166477b22a0af..3c2ef4ede079a05d805bbbf75942a1daaa179ded 100644 (file)
@@ -111,9 +111,9 @@ runtime·noteclear(Note *n)
 void
 runtime·notewakeup(Note *n)
 {
-       if(runtime·xchg(&n->key, 1))
+       if(runtime·xchg((uint32*)&n->key, 1))
                runtime·throw("notewakeup - double wakeup");
-       runtime·futexwakeup(&n->key, 1);
+       runtime·futexwakeup((uint32*)&n->key, 1);
 }
 
 void
@@ -121,8 +121,8 @@ runtime·notesleep(Note *n)
 {
        if(m->profilehz > 0)
                runtime·setprof(false);
-       while(runtime·atomicload(&n->key) == 0)
-               runtime·futexsleep(&n->key, 0, -1);
+       while(runtime·atomicload((uint32*)&n->key) == 0)
+               runtime·futexsleep((uint32*)&n->key, 0, -1);
        if(m->profilehz > 0)
                runtime·setprof(true);
 }
@@ -137,15 +137,15 @@ runtime·notetsleep(Note *n, int64 ns)
                return;
        }
 
-       if(runtime·atomicload(&n->key) != 0)
+       if(runtime·atomicload((uint32*)&n->key) != 0)
                return;
 
        if(m->profilehz > 0)
                runtime·setprof(false);
        deadline = runtime·nanotime() + ns;
        for(;;) {
-               runtime·futexsleep(&n->key, 0, ns);
-               if(runtime·atomicload(&n->key) != 0)
+               runtime·futexsleep((uint32*)&n->key, 0, ns);
+               if(runtime·atomicload((uint32*)&n->key) != 0)
                        break;
                now = runtime·nanotime();
                if(now >= deadline)
index 210460f33dd3df0b1c8d83110dffdbd9173e1a40..ec4b15a98a1c7aca7bda3e656a2a977f25f223f5 100644 (file)
@@ -118,7 +118,7 @@ runtime·unlock(Lock *l)
 void
 runtime·noteclear(Note *n)
 {
-       n->waitm = nil;
+       n->key = 0;
 }
 
 void
@@ -127,8 +127,8 @@ runtime·notewakeup(Note *n)
        M *mp;
 
        do
-               mp = runtime·atomicloadp(&n->waitm);
-       while(!runtime·casp(&n->waitm, mp, (void*)LOCKED));
+               mp = runtime·atomicloadp((void**)&n->key);
+       while(!runtime·casp((void**)&n->key, mp, (void*)LOCKED));
 
        // Successfully set waitm to LOCKED.
        // What was it before?
@@ -148,8 +148,8 @@ runtime·notesleep(Note *n)
 {
        if(m->waitsema == 0)
                m->waitsema = runtime·semacreate();
-       if(!runtime·casp(&n->waitm, nil, m)) {  // must be LOCKED (got wakeup)
-               if(n->waitm != (void*)LOCKED)
+       if(!runtime·casp((void**)&n->key, nil, m)) {  // must be LOCKED (got wakeup)
+               if(n->key != LOCKED)
                        runtime·throw("notesleep - waitm out of sync");
                return;
        }
@@ -176,8 +176,8 @@ runtime·notetsleep(Note *n, int64 ns)
                m->waitsema = runtime·semacreate();
 
        // Register for wakeup on n->waitm.
-       if(!runtime·casp(&n->waitm, nil, m)) {  // must be LOCKED (got wakeup already)
-               if(n->waitm != (void*)LOCKED)
+       if(!runtime·casp((void**)&n->key, nil, m)) {  // must be LOCKED (got wakeup already)
+               if(n->key != LOCKED)
                        runtime·throw("notetsleep - waitm out of sync");
                return;
        }
@@ -212,10 +212,10 @@ runtime·notetsleep(Note *n, int64 ns)
        // so that any notewakeup racing with the return does not
        // try to grant us the semaphore when we don't expect it.
        for(;;) {
-               mp = runtime·atomicloadp(&n->waitm);
+               mp = runtime·atomicloadp((void**)&n->key);
                if(mp == m) {
                        // No wakeup yet; unregister if possible.
-                       if(runtime·casp(&n->waitm, mp, nil))
+                       if(runtime·casp((void**)&n->key, mp, nil))
                                return;
                } else if(mp == (M*)LOCKED) {
                        // Wakeup happened so semaphore is available.
index 8e604221b13e4d809b04e9820e2f93dee92b1b29..ee82bedb7b4ee49b12387770ca493b2bf432b659 100644 (file)
@@ -54,7 +54,7 @@ typedef       struct  Lock            Lock;
 typedef        struct  M               M;
 typedef        struct  P               P;
 typedef        struct  Mem             Mem;
-typedef        union   Note            Note;
+typedef        struct  Note            Note;
 typedef        struct  Slice           Slice;
 typedef        struct  Stktop          Stktop;
 typedef        struct  String          String;
@@ -163,10 +163,12 @@ struct    Lock
        // Used to be a union, but unions break precise GC.
        uintptr key;
 };
-union  Note
+struct Note
 {
-       uint32  key;    // futex-based impl
-       M*      waitm;  // waiting M (sema-based impl)
+       // Futex-based impl treats it as uint32 key,
+       // while sema-based impl as M* waitm.
+       // Used to be a union, but unions break precise GC.
+       uintptr key;
 };
 struct String
 {