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

math/big: data race on cacheBase10 #4218

Closed
dvyukov opened this issue Oct 9, 2012 · 2 comments
Closed

math/big: data race on cacheBase10 #4218

dvyukov opened this issue Oct 9, 2012 · 2 comments
Milestone

Comments

@dvyukov
Copy link
Member

dvyukov commented Oct 9, 2012

14574:2c2052f38c3c tip

Add the following test to math/big tests:

func TestScanPiParallel(t *testing.T) {
    c := make(chan bool)
    for i := 0; i < 2; i++ {
        go func() {
            TestScanPi(t)
            c <- true
        }()
    }
    for i := 0; i < 2; i++ {
        <-c
    }
}

ThreadSanitizer says:

WARNING: DATA RACE at 0x000000ac6ab0
Read by goroutine 4:
  math/big.divisors()
      src/pkg/math/big/nat.go:956 +0x1aa
  math/big.nat.string()
      src/pkg/math/big/nat.go:807 +0x84d
  math/big.nat.decimalString()
      src/pkg/math/big/nat.go:731 +0x7e
  math/big.TestScanPi()
      src/pkg/math/big/nat_test.go:407 +0x1d6
  math/big.func·006()
      src/pkg/math/big/nat_test.go:416 +0x3a

Previous write by goroutine 3:
  math/big.divisors()
      src/pkg/math/big/nat.go:970 +0xa90
  math/big.nat.string()
      src/pkg/math/big/nat.go:807 +0x84d
  math/big.nat.decimalString()
      src/pkg/math/big/nat.go:731 +0x7e
  math/big.TestScanPi()
      src/pkg/math/big/nat_test.go:407 +0x1d6
  math/big.func·006()
      src/pkg/math/big/nat_test.go:416 +0x3a

Goroutine 4 (running) created at:
  math/big.TestScanPiParallel()
      src/pkg/math/big/nat_test.go:418 +0xac
  testing.tRunner()
      src/pkg/testing/testing.go:301 +0x86

Goroutine 3 (finished) created at:
  math/big.TestScanPiParallel()
      src/pkg/math/big/nat_test.go:418 +0xac
  testing.tRunner()
      src/pkg/testing/testing.go:301 +0x86

The issue is in the following code. If table[k-1].ndigits != 0 it does not mean that the
table is fully initialized. Occasionally I see "div by zero" crashes when
running in parallel.

    // extend table
    if table[k-1].ndigits == 0 {
        if cached {
            cacheLock.Lock() // begin critical section
        }

        // add new entries as needed
        var larger nat
        for i := 0; i < k; i++ {
            if table[i].ndigits == 0 {
                if i == 0 {
                    table[i].bbb = nat(nil).expWW(bb, Word(leafSize))
                    table[i].ndigits = ndigits * leafSize
                } else {
                    table[i].bbb = nat(nil).mul(table[i-1].bbb, table[i-1].bbb)
                    table[i].ndigits = 2 * table[i-1].ndigits
                }

                // optimization: exploit aggregated extra bits in macro blocks
                larger = nat(nil).set(table[i].bbb)
                for mulAddVWW(larger, larger, b, 0) == 0 {
                    table[i].bbb = table[i].bbb.set(larger)
                    table[i].ndigits++
                }

                table[i].nbits = table[i].bbb.bitLen()
            }
        }

        if cached {
            cacheLock.Unlock() // end critical section
        }
    }
@griesemer
Copy link
Contributor

Comment 1:

Owner changed to @griesemer.

Status changed to Accepted.

@griesemer
Copy link
Contributor

Comment 2:

This issue was closed by revision 4bee88d.

Status changed to Fixed.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015
@rsc rsc removed the go1.1 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
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

4 participants