Skip to content

Commit 841bb62

Browse files
rhyshgopherbot
authored andcommitted
internal/runtime/atomic: add Xchg8 for amd64
For #68578 Change-Id: Idecfdbb793f46560dd69287af9170c07cf4ee973 Reviewed-on: https://go-review.googlesource.com/c/go/+/606900 Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Mauri de Souza Meneguzzo <[email protected]> Auto-Submit: Rhys Hiltner <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Michael Knyszek <[email protected]>
1 parent 03103a5 commit 841bb62

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

src/internal/runtime/atomic/atomic_amd64.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ func Xadd64(ptr *uint64, delta int64) uint64
5757
//go:noescape
5858
func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
5959

60+
//go:noescape
61+
func Xchg8(ptr *uint8, new uint8) uint8
62+
6063
//go:noescape
6164
func Xchg(ptr *uint32, new uint32) uint32
6265

src/internal/runtime/atomic/atomic_amd64.s

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ TEXT ·Xaddint64(SB), NOSPLIT, $0-24
117117
TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
118118
JMP ·Xadd64(SB)
119119

120+
// uint8 Xchg(ptr *uint8, new uint8)
121+
// Atomically:
122+
// old := *ptr;
123+
// *ptr = new;
124+
// return old;
125+
TEXT ·Xchg8(SB), NOSPLIT, $0-17
126+
MOVQ ptr+0(FP), BX
127+
MOVB new+8(FP), AX
128+
XCHGB AX, 0(BX)
129+
MOVB AX, ret+16(FP)
130+
RET
131+
120132
// uint32 Xchg(ptr *uint32, new uint32)
121133
// Atomically:
122134
// old := *ptr;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build amd64
6+
7+
package atomic_test
8+
9+
import (
10+
"internal/runtime/atomic"
11+
"testing"
12+
)
13+
14+
func TestXchg8(t *testing.T) {
15+
var a [16]uint8
16+
for i := range a {
17+
next := uint8(i + 50)
18+
a[i] = next
19+
}
20+
b := a
21+
22+
// Compare behavior against non-atomic implementation. Expect the operation
23+
// to work at any byte offset and to not clobber neighboring values.
24+
for i := range a {
25+
next := uint8(i + 100)
26+
pa := atomic.Xchg8(&a[i], next)
27+
pb := b[i]
28+
b[i] = next
29+
if pa != pb {
30+
t.Errorf("atomic.Xchg8(a[%d]); %d != %d", i, pa, pb)
31+
}
32+
if a != b {
33+
t.Errorf("after atomic.Xchg8(a[%d]); %d != %d", i, a, b)
34+
}
35+
if t.Failed() {
36+
break
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)