alphadose / haxmap

Fastest and most memory efficient golang concurrent hashmap
MIT License
915 stars 45 forks source link

Seems not thread safe #21

Closed CMGS closed 1 year ago

CMGS commented 1 year ago

I update the vendor with the latest main branch and wrote this test code to simulate the situation.

func TestDebug(t *testing.T) {
    var wg sync.WaitGroup
    m := haxmap.New[string, struct{}]()

    acquire := func(key string) (free func(), acquired bool) {
        if _, loaded := m.GetOrSet(key, struct{}{}); loaded {
            return nil, false
        }

        free = func() {
            m.Del(key)
        }

        return free, true
    }

    n := 1000
    key := "key"
    var sum int32
    wg.Add(n)

    for i := 0; i < n; i++ {
        go func(idx int) {
            defer wg.Done()

            _, acq := acquire(fmt.Sprintf("%d", idx))
            require.True(t, acq)

            free, acquired := acquire(key)
            t.Log(acquired)
            if !acquired {
                return
            }

            // makes sure that there're only one thread has been acquired.
            require.True(t, atomic.CompareAndSwapInt32(&sum, 0, 1), atomic.LoadInt32(&sum))
            // marks there's no thread is acquired in advance.
            require.True(t, atomic.CompareAndSwapInt32(&sum, 1, 0))

            free()
        }(i)
    }

    wg.Wait()
}

When run go test without -race it shows fine, no errors. But if enable race detection, it will fail like

    sync_test.go:94: false
    sync_test.go:100:
            Error Trace:    /Users/cmgs/.go/src/github/projecteru2/agent/utils/sync_test.go:100
                                        /Users/cmgs/.go/src/github/projecteru2/agent/utils/asm_arm64.s:1172
            Error:          Should be true
            Test:           TestDebug
            Messages:       1
    sync_test.go:100:
            Error Trace:    /Users/cmgs/.go/src/github/projecteru2/agent/utils/sync_test.go:100
                                        /Users/cmgs/.go/src/github/projecteru2/agent/utils/asm_arm64.s:1172
            Error:          Should be true
            Test:           TestDebug
            Messages:       1
FAIL
FAIL    github.com/projecteru2/agent/utils  0.208s
FAIL

The test command is (I put this code under the utils pkg)

GOOS=darwin GOARCH=arm64 go test -race -count=1 -timeout 120s -run TestDebug ./utils/...

Not sure what happen, because the this error only shows under GOOS=darwin and GOARCH=arm64 (I use M1 macbook). can pass in linux env(https://github.com/projecteru2/agent/actions/runs/3359505108/jobs/5567595644).

Any ideas?

alphadose commented 1 year ago

@CMGS I also use an M1 mac, let me run the snippet in my own system as well as a linux system and then get back to you

alphadose commented 1 year ago

@CMGS getting the same error as you with -race flag, its specifically in this line from the golang runtime itself https://github.com/golang/go/blob/master/src/runtime/asm_arm64.s#L1172

The stability issue, in this case, is due to the golang runtime implementation on ARM64 devices not because of haxmap implementation

CMGS commented 1 year ago

haha I guess so, because running in linux is ok, that's why I create this issue. hope the next version of golang can fix it.