Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
2a4dcfff
Commit
2a4dcfff
authored
May 22, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
simplifying grammar: delete LBASETYPE and LACONST
R=ken OCL=29300 CL=29302
parent
b112d42a
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
251 additions
and
109 deletions
+251
-109
src/cmd/gc/align.c
src/cmd/gc/align.c
+1
-1
src/cmd/gc/dcl.c
src/cmd/gc/dcl.c
+12
-4
src/cmd/gc/export.c
src/cmd/gc/export.c
+5
-6
src/cmd/gc/go.y
src/cmd/gc/go.y
+3
-32
src/cmd/gc/lex.c
src/cmd/gc/lex.c
+18
-23
src/lib/Make.deps
src/lib/Make.deps
+2
-2
src/lib/bufio/bufio.go
src/lib/bufio/bufio.go
+4
-4
src/lib/io/io.go
src/lib/io/io.go
+13
-1
src/lib/io/pipe.go
src/lib/io/pipe.go
+60
-26
src/lib/runtime/types.go
src/lib/runtime/types.go
+121
-0
src/lib/sync/mutex.go
src/lib/sync/mutex.go
+12
-10
No files found.
src/cmd/gc/align.c
View file @
2a4dcfff
...
...
@@ -213,7 +213,7 @@ typeinit(int lex)
int
i
,
etype
,
sameas
;
Type
*
t
;
Sym
*
s
;
if
(
widthptr
==
0
)
fatal
(
"typeinit before betypeinit"
);
...
...
src/cmd/gc/dcl.c
View file @
2a4dcfff
...
...
@@ -1056,7 +1056,7 @@ addconst(Node *n, Node *e, int ctxt)
redeclare
(
"constant"
,
s
);
s
->
oconst
=
e
;
s
->
lexical
=
L
ACONST
;
s
->
lexical
=
L
NAME
;
d
=
dcl
();
d
->
dsym
=
s
;
...
...
@@ -1136,6 +1136,14 @@ oldname(Sym *s)
Node
*
n
;
Node
*
c
;
if
(
s
->
oconst
)
{
n
=
nod
(
OLITERAL
,
N
,
N
);
n
->
sym
=
s
;
n
->
val
=
s
->
oconst
->
val
;
n
->
type
=
s
->
oconst
->
type
;
return
n
;
}
n
=
s
->
oname
;
if
(
n
==
N
)
{
n
=
nod
(
ONONAME
,
N
,
N
);
...
...
@@ -1205,11 +1213,11 @@ nametoanondcl(Node *na)
for
(
l
=&
na
;
(
n
=*
l
)
->
op
==
OLIST
;
l
=&
n
->
left
)
n
->
right
=
nametoanondcl
(
n
->
right
);
if
(
n
->
sym
->
lexical
!=
LATYPE
&&
n
->
sym
->
lexical
!=
LBASETYPE
)
{
t
=
n
->
sym
->
otype
;
if
(
t
==
T
)
{
yyerror
(
"%s is not a type"
,
n
->
sym
->
name
);
t
=
typ
(
TINT32
);
}
else
t
=
oldtype
(
n
->
sym
);
}
n
=
nod
(
ODCLFIELD
,
N
,
N
);
n
->
type
=
t
;
*
l
=
n
;
...
...
src/cmd/gc/export.c
View file @
2a4dcfff
...
...
@@ -190,7 +190,6 @@ dumpsym(Sym *s)
yyerror
(
"package export symbol: %S"
,
s
);
break
;
case
LATYPE
:
case
LBASETYPE
:
// TODO(rsc): sort methods by name
for
(
f
=
s
->
otype
->
method
;
f
!=
T
;
f
=
f
->
down
)
dumpprereq
(
f
);
...
...
@@ -201,10 +200,10 @@ dumpsym(Sym *s)
f
->
type
->
type
->
type
,
f
->
sym
,
f
->
type
);
break
;
case
LNAME
:
dumpexportvar
(
s
);
break
;
case
LACONST
:
dumpexportconst
(
s
);
if
(
s
->
oconst
)
dumpexportconst
(
s
)
;
else
dumpexportvar
(
s
);
break
;
}
}
...
...
@@ -344,7 +343,7 @@ importconst(Node *ss, Type *t, Node *n)
return
;
convlit
(
n
,
t
);
s
=
importsym
(
ss
,
L
ACONST
);
s
=
importsym
(
ss
,
L
NAME
);
if
(
s
->
oconst
!=
N
)
{
// TODO: check if already the same.
return
;
...
...
src/cmd/gc/go.y
View file @
2a4dcfff
...
...
@@ -14,7 +14,7 @@
}
%
token
<
val
>
LLITERAL
%
token
<
lint
>
LASOP
%
token
<
sym
>
LNAME
L
BASETYPE
LATYPE
LPACK
LACONST
%
token
<
sym
>
LNAME
L
ATYPE
LPACK
%
token
<
sym
>
LPACKAGE
LIMPORT
LDEFER
LCLOSE
LCLOSED
%
token
<
sym
>
LMAP
LCHAN
LINTERFACE
LFUNC
LSTRUCT
%
token
<
sym
>
LCOLAS
LFALL
LRETURN
LDDD
...
...
@@ -42,7 +42,7 @@
* names like Bstmt, Bvardcl, etc. can'
t
.
*/
%
type
<
sym
>
sym
sym1
sym2
sym3
keyword
l
aconst
l
name
latype
lpackatype
%
type
<
sym
>
sym
sym1
sym2
sym3
keyword
lname
latype
lpackatype
%
type
<
node
>
xdcl
xdcl_list_r
oxdcl_list
%
type
<
node
>
common_dcl
Acommon_dcl
Bcommon_dcl
%
type
<
node
>
oarg_type_list
arg_type_list_r
arg_chunk
arg_chunk_list_r
arg_type_list
...
...
@@ -913,13 +913,6 @@ pexpr:
{
$$
=
nodbool
(
0
);
}
|
laconst
{
$$
=
nod
(
OLITERAL
,
N
,
N
);
$$->
sym
=
$
1
;
$$->
val
=
$
1
->
oconst
->
val
;
$$->
type
=
$
1
->
oconst
->
type
;
}
|
LIOTA
{
$$
=
nodintconst
(
iota
);
...
...
@@ -1023,14 +1016,6 @@ lpack:
}
*/
laconst:
LACONST
| lpack '
.
' LACONST
{
$$ = $3;
context = nil;
}
lname:
LNAME
| lpack '
.
' LNAME
...
...
@@ -1082,7 +1067,6 @@ onew_name:
sym:
LATYPE
| LNAME
| LACONST
| LPACK
sym1:
...
...
@@ -1112,7 +1096,6 @@ sym3:
| LPRINTN
| LNEW
| LMAKE
| LBASETYPE
/*
* keywords that we can
...
...
@@ -2129,20 +2112,8 @@ lpack:
YYERROR;
}
laconst:
LATYPE
{
yyerror("%s is type, not var", $1->name);
YYERROR;
}
latype:
LACONST
{
yyerror("%s is const, not type", $1->name);
YYERROR;
}
| LPACK
LPACK
{
yyerror("%s is package, not type", $1->name);
YYERROR;
...
...
src/cmd/gc/lex.c
View file @
2a4dcfff
...
...
@@ -64,7 +64,7 @@ main(int argc, char *argv[])
fatal
(
"betypeinit failed"
);
lexinit
();
typeinit
(
L
BASE
TYPE
);
typeinit
(
L
A
TYPE
);
lineno
=
1
;
block
=
1
;
...
...
@@ -775,8 +775,6 @@ talph:
DBG
(
"lex: %S %s
\n
"
,
s
,
lexname
(
s
->
lexical
));
yylval
.
sym
=
s
;
if
(
s
->
lexical
==
LBASETYPE
)
return
LATYPE
;
return
s
->
lexical
;
tnum:
...
...
@@ -1111,25 +1109,25 @@ static struct
/* name lexical etype
*/
/* basic types */
"int8"
,
L
BASE
TYPE
,
TINT8
,
"int16"
,
L
BASE
TYPE
,
TINT16
,
"int32"
,
L
BASE
TYPE
,
TINT32
,
"int64"
,
L
BASE
TYPE
,
TINT64
,
"int8"
,
L
A
TYPE
,
TINT8
,
"int16"
,
L
A
TYPE
,
TINT16
,
"int32"
,
L
A
TYPE
,
TINT32
,
"int64"
,
L
A
TYPE
,
TINT64
,
"uint8"
,
L
BASE
TYPE
,
TUINT8
,
"uint16"
,
L
BASE
TYPE
,
TUINT16
,
"uint32"
,
L
BASE
TYPE
,
TUINT32
,
"uint64"
,
L
BASE
TYPE
,
TUINT64
,
"uint8"
,
L
A
TYPE
,
TUINT8
,
"uint16"
,
L
A
TYPE
,
TUINT16
,
"uint32"
,
L
A
TYPE
,
TUINT32
,
"uint64"
,
L
A
TYPE
,
TUINT64
,
"float32"
,
L
BASE
TYPE
,
TFLOAT32
,
"float64"
,
L
BASE
TYPE
,
TFLOAT64
,
"float80"
,
L
BASE
TYPE
,
TFLOAT80
,
"float32"
,
L
A
TYPE
,
TFLOAT32
,
"float64"
,
L
A
TYPE
,
TFLOAT64
,
"float80"
,
L
A
TYPE
,
TFLOAT80
,
"bool"
,
L
BASE
TYPE
,
TBOOL
,
"byte"
,
L
BASE
TYPE
,
TUINT8
,
"string"
,
L
BASE
TYPE
,
TSTRING
,
"bool"
,
L
A
TYPE
,
TBOOL
,
"byte"
,
L
A
TYPE
,
TUINT8
,
"string"
,
L
A
TYPE
,
TSTRING
,
"any"
,
L
BASE
TYPE
,
TANY
,
"any"
,
L
A
TYPE
,
TANY
,
"break"
,
LBREAK
,
Txxx
,
"case"
,
LCASE
,
Txxx
,
...
...
@@ -1197,10 +1195,10 @@ lexinit(void)
s
->
lexical
=
lex
;
s
->
package
=
package
;
if
(
lex
!=
LBASETYPE
)
etype
=
syms
[
i
].
etype
;
if
(
etype
==
Txxx
)
continue
;
etype
=
syms
[
i
].
etype
;
if
(
etype
<
0
||
etype
>=
nelem
(
types
))
fatal
(
"lexinit: %s bad etype"
,
s
->
name
);
...
...
@@ -1234,9 +1232,6 @@ struct
{
LANDAND
,
"ANDAND"
,
LASOP
,
"ASOP"
,
LACONST
,
"ACONST"
,
LATYPE
,
"ATYPE"
,
LBASETYPE
,
"BASETYPE"
,
LBREAK
,
"BREAK"
,
LCASE
,
"CASE"
,
LCHAN
,
"CHAN"
,
...
...
src/lib/Make.deps
View file @
2a4dcfff
...
...
@@ -10,7 +10,7 @@ exvar.install: fmt.install http.install io.install log.install strconv.install s
flag.install: fmt.install os.install strconv.install
fmt.install: io.install os.install reflect.install strconv.install utf8.install
go/ast.install: go/token.install unicode.install utf8.install
go/doc.install: container/vector.install fmt.install go/ast.install go/token.install io.install once.install regexp.install sort.install strings.install
go/doc.install: container/vector.install fmt.install go/ast.install go/token.install io.install once.install regexp.install sort.install strings.install
template.install
go/parser.install: container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install
go/scanner.install: go/token.install strconv.install unicode.install utf8.install
go/token.install: strconv.install
...
...
@@ -39,7 +39,7 @@ syscall.install: sync.install
tabwriter.install: container/vector.install io.install os.install utf8.install
template.install: container/vector.install fmt.install io.install os.install reflect.install runtime.install strings.install
testing.install: flag.install fmt.install os.install runtime.install
testing/iotest.install: io.install os.install
testing/iotest.install: io.install
log.install
os.install
time.install: io.install once.install os.install syscall.install
unicode.install:
utf8.install:
src/lib/bufio/bufio.go
View file @
2a4dcfff
...
...
@@ -109,11 +109,11 @@ func (b *Reader) fill() os.Error {
return
nil
}
// Read reads data into p.
//
It returns the number of bytes read
into p.
// If nn < len(p), also returns an error explaining
// Read reads data into p
, returning the number of bytes read
.
//
Read reads as much data as possible
into p.
// If nn < len(p),
Read
also returns an error explaining
// why the read is short. At EOF, the count will be
// zero and err will be io.ErrEOF.
// zero and err will be io.Err
Unexpected
EOF.
func
(
b
*
Reader
)
Read
(
p
[]
byte
)
(
nn
int
,
err
os
.
Error
)
{
nn
=
0
;
for
len
(
p
)
>
0
{
...
...
src/lib/io/io.go
View file @
2a4dcfff
...
...
@@ -69,7 +69,19 @@ type ReadWriteCloser interface {
Closer
;
}
// Convert a string to an array of bytes for easy marshaling.
// ReadByter is the interface that wraps the basic ReadByte method.
// Implementations of ReadByte typically use buffered I/O.
type
ReadByter
interface
{
ReadByte
()
(
byte
,
os
.
Error
);
}
// WriteByter is the interface that wraps the basic WriteByte method.
// Implementations of WriteByte typically use buffered I/O.
type
WriteByter
interface
{
WriteByte
(
byte
)
os
.
Error
;
}
// StringBytes converts a string to an array of bytes for easy marshaling.
func
StringBytes
(
s
string
)
[]
byte
{
b
:=
make
([]
byte
,
len
(
s
));
for
i
:=
0
;
i
<
len
(
s
);
i
++
{
...
...
src/lib/io/pipe.go
View file @
2a4dcfff
...
...
@@ -21,7 +21,9 @@ type pipeReturn struct {
// Shared pipe structure.
type
pipe
struct
{
rclosed
bool
;
// Read end closed?
rerr
os
.
Error
;
// Error supplied to CloseReader
wclosed
bool
;
// Write end closed?
werr
os
.
Error
;
// Error supplied to CloseWriter
wpend
[]
byte
;
// Written data waiting to be read.
wtot
int
;
// Bytes consumed so far in current write.
cr
chan
[]
byte
;
// Write sends data here...
...
...
@@ -39,7 +41,7 @@ func (p *pipe) Read(data []byte) (n int, err os.Error) {
p
.
wpend
=
<-
p
.
cr
;
}
if
p
.
wpend
==
nil
{
return
0
,
nil
;
return
0
,
p
.
werr
;
}
p
.
wtot
=
0
;
}
...
...
@@ -70,7 +72,7 @@ func (p *pipe) Write(data []byte) (n int, err os.Error) {
return
0
,
os
.
EINVAL
;
}
if
p
.
rclosed
{
return
0
,
os
.
EPIPE
;
return
0
,
p
.
rerr
;
}
// Send data to reader.
...
...
@@ -81,29 +83,34 @@ func (p *pipe) Write(data []byte) (n int, err os.Error) {
return
res
.
n
,
res
.
err
;
}
func
(
p
*
pipe
)
CloseReader
()
os
.
Error
{
func
(
p
*
pipe
)
CloseReader
(
rerr
os
.
Error
)
os
.
Error
{
if
p
==
nil
||
p
.
rclosed
{
return
os
.
EINVAL
;
}
// Stop any future writes.
p
.
rclosed
=
true
;
if
rerr
==
nil
{
rerr
=
os
.
EPIPE
;
}
p
.
rerr
=
rerr
;
// Stop the current write.
if
!
p
.
wclosed
{
p
.
cw
<-
pipeReturn
{
p
.
wtot
,
os
.
EPIPE
};
p
.
cw
<-
pipeReturn
{
p
.
wtot
,
rerr
};
}
return
nil
;
}
func
(
p
*
pipe
)
CloseWriter
()
os
.
Error
{
func
(
p
*
pipe
)
CloseWriter
(
werr
os
.
Error
)
os
.
Error
{
if
p
==
nil
||
p
.
wclosed
{
return
os
.
EINVAL
;
}
// Stop any future reads.
p
.
wclosed
=
true
;
p
.
werr
=
werr
;
// Stop the current read.
if
!
p
.
rclosed
{
...
...
@@ -121,70 +128,97 @@ func (p *pipe) CloseWriter() os.Error {
// 2. Clients cannot use interface conversions on the
// read end to find the Write method, and vice versa.
//
Read half of
pipe.
type
pipeRead
struct
{
//
A PipeReader is the read half of a
pipe.
type
PipeReader
struct
{
lock
sync
.
Mutex
;
p
*
pipe
;
}
func
(
r
*
pipeRead
)
Read
(
data
[]
byte
)
(
n
int
,
err
os
.
Error
)
{
// Read implements the standard Read interface:
// it reads data from the pipe, blocking until a writer
// arrives or the write end is closed.
// If the write end is closed with an error, that error is
// returned as err; otherwise err is nil.
func
(
r
*
PipeReader
)
Read
(
data
[]
byte
)
(
n
int
,
err
os
.
Error
)
{
r
.
lock
.
Lock
();
defer
r
.
lock
.
Unlock
();
return
r
.
p
.
Read
(
data
);
}
func
(
r
*
pipeRead
)
Close
()
os
.
Error
{
// Close closes the reader; subsequent writes to the
// write half of the pipe will return the error os.EPIPE.
func
(
r
*
PipeReader
)
Close
()
os
.
Error
{
r
.
lock
.
Lock
();
defer
r
.
lock
.
Unlock
();
return
r
.
p
.
CloseReader
(
nil
);
}
// CloseWithError closes the reader; subsequent writes
// to the write half of the pipe will return the error rerr.
func
(
r
*
PipeReader
)
CloseWithError
(
rerr
os
.
Error
)
os
.
Error
{
r
.
lock
.
Lock
();
defer
r
.
lock
.
Unlock
();
return
r
.
p
.
CloseReader
();
return
r
.
p
.
CloseReader
(
rerr
);
}
func
(
r
*
pipeRead
)
finish
()
{
func
(
r
*
PipeReader
)
finish
()
{
r
.
Close
();
}
// Write half of pipe.
type
pipeWrite
struct
{
type
PipeWriter
struct
{
lock
sync
.
Mutex
;
p
*
pipe
;
}
func
(
w
*
pipeWrite
)
Write
(
data
[]
byte
)
(
n
int
,
err
os
.
Error
)
{
// Write implements the standard Write interface:
// it writes data to the pipe, blocking until readers
// have consumed all the data or the read end is closed.
// If the read end is closed with an error, that err is
// returned as err; otherwise err is os.EPIPE.
func
(
w
*
PipeWriter
)
Write
(
data
[]
byte
)
(
n
int
,
err
os
.
Error
)
{
w
.
lock
.
Lock
();
defer
w
.
lock
.
Unlock
();
return
w
.
p
.
Write
(
data
);
}
func
(
w
*
pipeWrite
)
Close
()
os
.
Error
{
// Close closes the writer; subsequent reads from the
// read half of the pipe will return no bytes and a nil error.
func
(
w
*
PipeWriter
)
Close
()
os
.
Error
{
w
.
lock
.
Lock
();
defer
w
.
lock
.
Unlock
();
return
w
.
p
.
CloseWriter
(
nil
);
}
// CloseWithError closes the writer; subsequent reads from the
// read half of the pipe will return no bytes and the error werr.
func
(
w
*
PipeWriter
)
CloseWithError
(
werr
os
.
Error
)
os
.
Error
{
w
.
lock
.
Lock
();
defer
w
.
lock
.
Unlock
();
return
w
.
p
.
CloseWriter
();
return
w
.
p
.
CloseWriter
(
werr
);
}
func
(
w
*
pipeWrite
)
finish
()
{
func
(
w
*
PipeWriter
)
finish
()
{
w
.
Close
();
}
// Pipe creates a synchronous in-memory pipe.
//
U
sed to connect code expecting an io.Reader
//
It can be u
sed to connect code expecting an io.Reader
// with code expecting an io.Writer.
//
// Reads on one end are matched by writes on the other.
// Writes don't complete until all the data has been
// written or the read end is closed. Reads return
// any available data or block until the next write
// or the write end is closed.
func
Pipe
()
(
io
.
ReadCloser
,
io
.
WriteCloser
)
{
// Reads on one end are matched with writes on the other.
func
Pipe
()
(
*
PipeReader
,
*
PipeWriter
)
{
p
:=
new
(
pipe
);
p
.
cr
=
make
(
chan
[]
byte
,
1
);
p
.
cw
=
make
(
chan
pipeReturn
,
1
);
r
:=
new
(
pipeRead
);
r
:=
new
(
PipeReader
);
r
.
p
=
p
;
w
:=
new
(
pipeWrite
);
w
:=
new
(
PipeWriter
);
w
.
p
=
p
;
return
r
,
w
;
}
...
...
src/lib/runtime/types.go
0 → 100644
View file @
2a4dcfff
// 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.
// TODO(rsc): Doc comments
package
runtime
import
"unsafe"
// The Type interface stands for any of the run-time type structures
// in this package.
type
Type
interface
{
}
// All types begin with a few common fields needed for
// the interface runtime.
type
CommonType
struct
{
Size
uintptr
;
Hash
uint32
;
Alg
uint8
;
Align
uint8
;
FieldAlign
uint8
;
}
// Basic types; should these be one struct with an enum kind?
// The benefit of splitting them up into many types is that
// one can use a single type switch instead of needing an
// enum switch inside a type switch.
type
BoolType
CommonType
type
Float32Type
CommonType
type
Float64Type
CommonType
type
FloatType
CommonType
type
Int16Type
CommonType
type
Int32Type
CommonType
type
Int64Type
CommonType
type
Int8Type
CommonType
type
IntType
CommonType
type
Uint16Type
CommonType
type
Uint32Type
CommonType
type
Uint64Type
CommonType
type
Uint8Type
CommonType
type
UintType
CommonType
type
StringType
CommonType
type
UintptrType
CommonType
type
UnsafePointerType
CommonType
type
ArrayType
struct
{
CommonType
;
Elem
*
Type
;
Bound
int32
;
// -1 means slice
}
type
ChanDir
int
const
(
SendDir
ChanDir
=
1
<<
iota
;
RecvDir
;
BothDir
=
SendDir
|
RecvDir
;
)
type
ChanType
struct
{
CommonType
;
Elem
*
Type
;
Dir
ChanDir
;
}
type
FuncType
struct
{
CommonType
;
In
[]
*
Type
;
Out
[]
*
Type
;
}
type
IMethod
struct
{
Name
*
string
;
Package
*
string
;
Type
*
Type
;
}
type
InterfaceType
struct
{
CommonType
;
Methods
[]
*
IMethod
;
}
type
MapType
struct
{
CommonType
;
Key
*
Type
;
Elem
*
Type
;
}
type
Method
struct
{
Name
*
string
;
Package
*
string
;
Type
*
Type
;
Func
unsafe
.
Pointer
;
}
type
NamedType
struct
{
CommonType
;
Name
*
string
;
Package
*
string
;
Type
*
Type
;
ValueMethods
[]
*
Method
;
PtrMethods
[]
*
Method
;
}
type
PtrType
struct
{
CommonType
;
Sub
*
Type
;
}
type
StructField
struct
{
Name
*
string
;
Type
*
Type
;
Tag
*
string
;
Offset
uintptr
;
}
type
StructType
struct
{
CommonType
;
Fields
[]
*
StructField
;
}
src/lib/sync/mutex.go
View file @
2a4dcfff
...
...
@@ -2,19 +2,19 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/
/ The sync package provides basic synchronization primitives
// such as mutual exclusion locks. These are intended for use
// by low-level library routines. Higher-level synchronization
// is better done via channels and communication.
/
*
The sync /* package * / provides basic sync primitives.
// Such as mutual exclusion locks.
*/
package
sync
func
cas
(
val
*
int32
,
old
,
new
int32
)
bool
func
semacquire
(
*
int32
)
func
semrelease
(
*
int32
)
// A Mutex is a mutual exclusion lock.
// Mutexes can be created as part of other structures;
// the zero value for a Mutex is an unlocked mutex.
// A Mutex is a mutual exclusion lock.
// Mutexes can be created as part of other structures;
// the zero value for a Mutex is an unlocked mutex.
type
Mutex
struct
{
key
int32
;
sema
int32
;
...
...
@@ -30,9 +30,11 @@ func xadd(val *int32, delta int32) (new int32) {
panic
(
"unreached"
)
}
// Lock locks m.
// If the lock is already in use, the calling goroutine
// blocks until the mutex is available.
/*
* Lock locks m.
* If the lock is already in use, the calling goroutine
* blocks until the mutex is available.
*/
func
(
m
*
Mutex
)
Lock
()
{
if
xadd
(
&
m
.
key
,
1
)
==
1
{
// changed from 0 to 1; we hold lock
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment