Permalink
Browse files

Move cdata logic to assembly in Go 1.4+.

Fixes #106.
  • Loading branch information...
1 parent f0a005b commit b94596a6ddac9305f52c756f78cab8cb28de29af @niemeyer niemeyer committed Oct 6, 2014
Showing with 73 additions and 12 deletions.
  1. +1 −2 cdata/cdata.go
  2. +2 −0 cdata/{cdata.c → cdata12.c}
  3. +17 −0 cdata/cdata14_386.s
  4. +17 −0 cdata/cdata14_amd64.s
  5. +18 −0 cdata/cdata14_arm.s
  6. +18 −10 cdata/cdata_test.go
View
@@ -1,5 +1,4 @@
-// This package supports the implementation of the qml package,
-// and must not be used by itself.
+// Package cdata supports the implementation of the qml package.
package cdata
func Ref() uintptr
@@ -1,3 +1,5 @@
+// +build !go1.4
+
#include "runtime.h"
void ·Ref(uintptr ref) {
View
@@ -0,0 +1,17 @@
+// +build go1.4
+
+#include "textflag.h"
+
+TEXT ·Ref(SB),NOSPLIT,$4-4
+ CALL runtime·acquirem(SB)
+ MOVL 0(SP), AX
+ MOVL AX, ret+0(FP)
+ CALL runtime·releasem(SB)
+ RET
+
+TEXT ·Addrs(SB),NOSPLIT,$0-8
+ MOVL $runtime·main(SB), AX
+ MOVL AX, ret+0(FP)
+ MOVL $runtime·main_main(SB), AX
+ MOVL AX, ret+8(FP)
+ RET
View
@@ -0,0 +1,17 @@
+// +build go1.4
+
+#include "textflag.h"
+
+TEXT ·Ref(SB),NOSPLIT,$8-8
+ CALL runtime·acquirem(SB)
+ MOVQ 0(SP), AX
+ MOVQ AX, ret+0(FP)
+ CALL runtime·releasem(SB)
+ RET
+
+TEXT ·Addrs(SB),NOSPLIT,$0-16
+ MOVQ $runtime·main(SB), AX
+ MOVQ AX, ret+0(FP)
+ MOVQ $runtime·main_main(SB), AX
+ MOVQ AX, ret+8(FP)
+ RET
View
@@ -0,0 +1,18 @@
+// +build go1.4
+
+#include "textflag.h"
+
+TEXT ·Ref(SB),NOSPLIT,$4-4
+ BL runtime·acquirem(SB)
+ MOVW 4(R13), R0
+ MOVW R0, ret+0(FP)
+ MOVW R0, 4(R13)
+ BL runtime·releasem(SB)
+ RET
+
+TEXT ·Addrs(SB),NOSPLIT,$0-8
+ MOVW $runtime·main(SB), R0
+ MOVW R0, ret+0(FP)
+ MOVW $runtime·main_main(SB), R0
+ MOVW R0, ret+4(FP)
+ RET
View
@@ -6,29 +6,37 @@ import (
"testing"
)
+type refPair struct {
+ ref1, ref2 uintptr
+}
+
func TestRef(t *testing.T) {
const N = 10
runtime.LockOSThread()
+ exit := sync.WaitGroup{}
+ exit.Add(1)
+ defer exit.Done()
wg := sync.WaitGroup{}
wg.Add(N)
- ch := make(chan uintptr)
+ ch := make(chan refPair)
for i := 0; i < N; i++ {
go func() {
runtime.LockOSThread()
wg.Done()
- ch <- Ref()
- wg.Wait()
+ ch <- refPair{Ref(), Ref()}
+ exit.Wait()
}()
}
wg.Wait()
- refs := []uintptr{Ref()}
+ refs := make(map[uintptr]bool)
for i := 0; i < N; i++ {
- chref := <-ch
- for _, ref := range refs {
- if chref == ref {
- t.Fatalf("found duplicated ref: %d == %d", chref, ref)
- }
+ pair := <-ch
+ if pair.ref1 != pair.ref2 {
+ t.Fatalf("found inconsistent ref: %d != %d", pair.ref1, pair.ref2)
+ }
+ if refs[pair.ref1] {
+ t.Fatalf("found duplicated ref: %d", pair.ref1)
}
- refs = append(refs, chref)
+ refs[pair.ref1] = true
}
}

0 comments on commit b94596a

Please sign in to comment.