You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have found a strange problem where the format in which a number constant is declared
causes
deadlock. The same program runs fine with:
const nUM_SERVERS = 10 // works
but crashes with:
const nUM_SERVERS = 1e1 // causes deadlock
The same happens for numbers of any size, even for:
const nUM_SERVERS = 1e0 // causes deadlock
and
const nUM_SERVERS = 1e6 // causes deadlock
This const is used in only place in the program:
var svrCh [nUM_SERVERS]chan int
The same problem occurs when the relevant literals are used in the var declaration.
The full test program is attached below.
> hg identify
7a249afa5ed3 tip
GOARCH=amd64
GOOS=darwin
To reproduce the problem:
Comment the nUM_SERVERS declaration at the top of the program as follows:
/*const nUM_SERVERS = 10 // works*/
const nUM_SERVERS = 1e1 // causes deadlock
Compile and run:
6g tstGo.go; 6l tstGo.6; ./6.out
I expect something like the following output:
start of output>
setup complete in 0.000111 s
1000 msgs sent in 0.004202 s
<end of output
The output above was generated by the following constant declaration configuration:
const nUM_SERVERS = 10 // works
/*const nUM_SERVERS = 1e1 // causes deadlock*/
Instead the following output is generated:
setup complete in 4.3e-05 s
throw: all goroutines are asleep - deadlock!
panic PC=0x2c5068
throw+0x3e /Users/marius/local/go/src/pkg/runtime/runtime.c:74
throw(0x52cc3, 0x0)
nextgandunlock+0x15a /Users/marius/local/go/src/pkg/runtime/proc.c:344
nextgandunlock()
scheduler+0xe0 /Users/marius/local/go/src/pkg/runtime/proc.c:509
scheduler()
mstart+0x47 /Users/marius/local/go/src/pkg/runtime/proc.c:400
mstart()
bsdthread_start+0x14 /Users/marius/local/go/src/pkg/runtime/darwin/amd64/sys.s:148
bsdthread_start()
goroutine 2 [4]:
gosched+0x4e /Users/marius/local/go/src/pkg/runtime/proc.c:530
gosched()
runtime.selectgo+0x3d0 /Users/marius/local/go/src/pkg/runtime/chan.c:792
runtime.selectgo(0x29e400, 0x0)
main.bank+0xee /Users/marius/nextPrj/gotest/tstGo.go:70
main.bank(0x2a3180, 0x0, 0x2a31e0, 0x0)
goexit /Users/marius/local/go/src/pkg/runtime/proc.c:140
goexit()
0x2a3180 unknown pc
goroutine 1 [4]:
gosched+0x4e /Users/marius/local/go/src/pkg/runtime/proc.c:530
gosched()
chanrecv+0x39b /Users/marius/local/go/src/pkg/runtime/chan.c:326
chanrecv(0x2a3240, 0x0, 0x2a5f10, 0x0, 0x0, ...)
runtime.chanrecv1+0x50 /Users/marius/local/go/src/pkg/runtime/chan.c:423
runtime.chanrecv1(0x2a3240, 0x0)
main.spray+0x7f /Users/marius/nextPrj/gotest/tstGo.go:35
main.spray(0x2a3240, 0x0)
main.main+0x270 /Users/marius/nextPrj/gotest/tstGo.go:26
main.main()
mainstart+0xf /Users/marius/local/go/src/pkg/runtime/amd64/asm.s:54
mainstart()
goexit /Users/marius/local/go/src/pkg/runtime/proc.c:140
goexit()
The full test program follows:
tstGo.go:
-------------------------------
package main
import(
"fmt"
"time"
)
/*const nUM_SERVERS = 10 // works*/
const nUM_SERVERS = 1e1 // causes deadlock
const nUM_MSGS = 1e3
const cREDIT = 30
var svrCh [nUM_SERVERS]chan int
func main() {
startTime := time.Nanoseconds()
bankReqCh := make(chan *reqCredit)
bankRelCh := make(chan int)
go bank(bankReqCh, bankRelCh)
respCh := make(chan int)
for i := 0; i < len(svrCh); i++ {
svrCh[i] = make(chan int)
go svr(i, svrCh[i], respCh, bankReqCh, bankRelCh)
}
fmt.Println("setup complete in ", float64(time.Nanoseconds()-startTime)/1.0e9, "s")
spray(respCh)
}
func spray(respCh chan int) {
startTime := time.Nanoseconds()
for i := 0; i < len(svrCh); i++ {
svrCh[i] <- 1
}
for numMsgs := 0; numMsgs < nUM_MSGS; {
svr := <- respCh
numMsgs++
svrCh[svr] <- 1
}
fmt.Println(nUM_MSGS, "msgs sent in ", float64(time.Nanoseconds()-startTime)/1.0e9, "s")
}
func svr(id int, clientReq chan int, clientRsp chan int, bankReq chan *reqCredit,
bankRel chan int)
{
reply := make(chan int)
req := reqCredit{reply, 1}
for {
<- clientReq
bankReq <- &req
credit := <- reply
bankRel <- credit
clientRsp <- id
}
}
type reqCredit struct {
replyTo chan int
credit int
}
func bank(request chan *reqCredit, release chan int) {
credit := cREDIT
for {
if credit > 0 {
select {
case req := <- request:
credit -= req.credit
req.replyTo <- req.credit
case c := <- release:
credit += c
}
}else{
c := <- release
credit += c
}
}
}
The text was updated successfully, but these errors were encountered:
The problem appears to be the use of an untyped constant in an array declaration.
The following program:
package main
var a [10]int
var b [1e1]int
func main() {
println("len(a) =", len(a))
println("len(b) =", len(b))
}
prints:
len(a) = 10
len(b) = 0
even though it should print 10 both times. In your program, the empty array leads to
a deadlock.
This is compiler bug.
by marius@vastech.co.za:
The text was updated successfully, but these errors were encountered: