Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format of number in const declaration causes deadlock #587

Closed
gopherbot opened this issue Feb 4, 2010 · 2 comments
Closed

Format of number in const declaration causes deadlock #587

gopherbot opened this issue Feb 4, 2010 · 2 comments

Comments

@gopherbot
Copy link
Contributor

by marius@vastech.co.za:

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
        }
    }
}
@griesemer
Copy link
Contributor

Comment 1:

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.

Owner changed to r...@golang.org.

Status changed to Accepted.

@rsc
Copy link
Contributor

rsc commented Feb 12, 2010

Comment 2:

This issue was closed by revision 5ab8f00.

Status changed to Fixed.

Merged into issue #-.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
@rsc rsc removed their assignment Jun 22, 2022
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants