Skip to content

Commit

Permalink
add mutex.Mutex
Browse files Browse the repository at this point in the history
R=r
DELTA=349  (348 added, 0 deleted, 1 changed)
OCL=20380
CL=20472
  • Loading branch information
rsc committed Dec 4, 2008
1 parent 3e8faa6 commit bf3dd3f
Show file tree
Hide file tree
Showing 10 changed files with 363 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/cmd/gc/sys.go
Expand Up @@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.


package SYS // rename to avoid redeclaration
package SYS // rename to avoid redeclaration errors

export func mal(int32) *any;
export func breakpoint();
Expand Down Expand Up @@ -92,3 +92,5 @@ export func exit(int);

export func symdat() (symtab *[]byte, pclntab *[]byte);

export func semacquire(sema *int32);
export func semrelease(sema *int32);
2 changes: 2 additions & 0 deletions src/cmd/gc/sysimport.c
Expand Up @@ -71,5 +71,7 @@ char *sysimport =
"export func sys.stringtorune (? string, ? int) (? int, ? int)\n"
"export func sys.exit (? int)\n"
"export func sys.symdat () (symtab *[]uint8, pclntab *[]uint8)\n"
"export func sys.semacquire (sema *int32)\n"
"export func sys.semrelease (sema *int32)\n"
"\n"
"$$\n";
2 changes: 2 additions & 0 deletions src/lib/Makefile
Expand Up @@ -18,6 +18,7 @@ DIRS=\
reflect\
regexp\
strconv\
sync\
tabwriter\
time\

Expand Down Expand Up @@ -95,4 +96,5 @@ reflect.dirinstall: strconv.dirinstall
strconv.dirinstall: os.dirinstall utf8.install
tabwriter.dirinstall: os.dirinstall io.dirinstall container/array.dirinstall
time.dirinstall: once.install os.dirinstall
sync.dirinstall:

56 changes: 56 additions & 0 deletions src/lib/sync/Makefile
@@ -0,0 +1,56 @@
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# DO NOT EDIT. Automatically generated by gobuild.
# gobuild -m >Makefile
O=6
GC=$(O)g
CC=$(O)c -w
AS=$(O)a
AR=$(O)ar

default: packages

clean:
rm -f *.$O *.a $O.out

test: packages
gotest

coverage: packages
gotest
6cov -g `pwd` | grep -v '_test\.go:'

%.$O: %.go
$(GC) $*.go

%.$O: %.c
$(CC) $*.c

%.$O: %.s
$(AS) $*.s

O1=\
asm_$(GOARCH).$O\
mutex.$O\

sync.a: a1

a1: $(O1)
$(AR) grc sync.a asm_$(GOARCH).$O mutex.$O
rm -f $(O1)

newpkg: clean
$(AR) grc sync.a

$(O1): newpkg

nuke: clean
rm -f $(GOROOT)/pkg/sync.a

packages: sync.a

install: packages
cp sync.a $(GOROOT)/pkg/sync.a

23 changes: 23 additions & 0 deletions src/lib/sync/asm_amd64.s
@@ -0,0 +1,23 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// func cas(val *int32, old, new int32) bool
// Atomically:
// if *val == old {
// *val = new;
// return true;
// }else
// return false;
TEXT sync·cas(SB), 7, $0
MOVQ 8(SP), BX
MOVL 16(SP), AX
MOVL 20(SP), CX
LOCK
CMPXCHGL CX, 0(BX)
JZ ok
MOVL $0, 24(SP)
RET
ok:
MOVL $1, 24(SP)
RET
39 changes: 39 additions & 0 deletions src/lib/sync/mutex.go
@@ -0,0 +1,39 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sync

package func cas(val *int32, old, new int32) bool

export type Mutex struct {
key int32;
sema int32;
}

func xadd(val *int32, delta int32) (new int32) {
for {
v := *val;
if cas(val, v, v+delta) {
return v+delta;
}
}
panic("unreached")
}

func (m *Mutex) Lock() {
if xadd(&m.key, 1) == 1 {
// changed from 0 to 1; we hold lock
return;
}
sys.semacquire(&m.sema);
}

func (m *Mutex) Unlock() {
if xadd(&m.key, -1) == 0 {
// changed from 1 to 0; no contention
return;
}
sys.semrelease(&m.sema);
}

53 changes: 53 additions & 0 deletions src/lib/sync/mutex_test.go
@@ -0,0 +1,53 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// GOMAXPROCS=10 gotest

package sync

import (
"sync";
"testing"
)

func HammerSemaphore(s *int32, cdone *chan bool) {
for i := 0; i < 1000; i++ {
sys.semacquire(s);
sys.semrelease(s);
}
cdone <- true;
}

export func TestSemaphore(t *testing.T) {
s := new(int32);
*s = 1;
c := new(chan bool);
for i := 0; i < 10; i++ {
go HammerSemaphore(s, c);
}
for i := 0; i < 10; i++ {
<-c;
}
}


func HammerMutex(m *Mutex, cdone *chan bool) {
for i := 0; i < 1000; i++ {
m.Lock();
m.Unlock();
}
cdone <- true;
}

export func TestMutex(t *testing.T) {
m := new(Mutex);
c := new(chan bool);
for i := 0; i < 10; i++ {
go HammerMutex(m, c);
}
for i := 0; i < 10; i++ {
<-c;
}
}

6 changes: 6 additions & 0 deletions src/run.bash
Expand Up @@ -34,6 +34,12 @@ maketest \

(xcd lib; make test) || exit $?

(xcd lib/sync;
make clean;
time make
GOMAXPROCS=10 make test
) || exit $?

(xcd ../usr/gri/pretty
make clean
time make
Expand Down
1 change: 1 addition & 0 deletions src/runtime/Makefile
Expand Up @@ -25,6 +25,7 @@ LIBOFILES=\
print.$O\
rune.$O\
proc.$O\
sema.$O\
stack.$O\
string.$O\
symtab.$O\
Expand Down

0 comments on commit bf3dd3f

Please sign in to comment.