]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add atomic xchg64
authorDmitriy Vyukov <dvyukov@google.com>
Tue, 5 Mar 2013 07:46:52 +0000 (09:46 +0200)
committerDmitriy Vyukov <dvyukov@google.com>
Tue, 5 Mar 2013 07:46:52 +0000 (09:46 +0200)
It will be handy for network poller.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7429048

src/pkg/runtime/asm_amd64.s
src/pkg/runtime/atomic_386.c
src/pkg/runtime/atomic_arm.c
src/pkg/runtime/runtime.c
src/pkg/runtime/runtime.h

index 987958498eab7d4b01c23d5ac02bfa631577eed2..696befd6e4dc93995621deb54f1bd30a9d0dc3e9 100644 (file)
@@ -442,6 +442,12 @@ TEXT runtime·xchg(SB), 7, $0
        XCHGL   AX, 0(BX)
        RET
 
+TEXT runtime·xchg64(SB), 7, $0
+       MOVQ    8(SP), BX
+       MOVQ    16(SP), AX
+       XCHGQ   AX, 0(BX)
+       RET
+
 TEXT runtime·procyield(SB),7,$0
        MOVL    8(SP), AX
 again:
index 79b7cbf96dcc20b7a847d31524a1cb7339171b46..1046eb81e3f196d00714b40edd9cea82ec51f1ac 100644 (file)
@@ -30,3 +30,16 @@ runtime·xadd64(uint64 volatile* addr, int64 v)
        }
        return old+v;
 }
+
+#pragma textflag 7
+uint64
+runtime·xchg64(uint64 volatile* addr, uint64 v)
+{
+       uint64 old;
+
+       old = *addr;
+       while(!runtime·cas64(addr, &old, v)) {
+               // nothing
+       }
+       return old;
+}
index 0b54840cc9fab743552020fe0cc2f04b713eb971..9193d599d36fb047684dc25f4941d0b793b878ae 100644 (file)
@@ -121,6 +121,19 @@ runtime·xadd64(uint64 volatile *addr, int64 delta)
        return res;
 }
 
+#pragma textflag 7
+uint64
+runtime·xchg64(uint64 volatile *addr, uint64 v)
+{
+       uint64 res;
+
+       runtime·lock(LOCK(addr));
+       res = *addr;
+       *addr = v;
+       runtime·unlock(LOCK(addr));
+       return res;
+}
+
 #pragma textflag 7
 uint64
 runtime·atomicload64(uint64 volatile *addr)
index 4d57cbafdff1af4050729a621c610d5d8c39fa93..d3ee2a0ec9f5d986d966988408ff5f875ebd6339 100644 (file)
@@ -156,6 +156,10 @@ TestAtomic64(void)
                runtime·throw("xadd64 failed");
        if(runtime·atomicload64(&z64) != (2ull<<40)+2)
                runtime·throw("xadd64 failed");
+       if(runtime·xchg64(&z64, (3ull<<40)+3) != (2ull<<40)+2)
+               runtime·throw("xchg64 failed");
+       if(runtime·atomicload64(&z64) != (3ull<<40)+3)
+               runtime·throw("xchg64 failed");
 }
 
 void
index 585d6a536e0cc5720ceacf0cb65f93f7173ddaac..8ed18432d8478f741bdfe400a22c9ce28ee11a93 100644 (file)
@@ -691,6 +691,7 @@ bool        runtime·casp(void**, void*, void*);
 uint32 runtime·xadd(uint32 volatile*, int32);
 uint64 runtime·xadd64(uint64 volatile*, int64);
 uint32 runtime·xchg(uint32 volatile*, uint32);
+uint64 runtime·xchg64(uint64 volatile*, uint64);
 uint32 runtime·atomicload(uint32 volatile*);
 void   runtime·atomicstore(uint32 volatile*, uint32);
 void   runtime·atomicstore64(uint64 volatile*, uint64);