// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2019 The gVisor Authors.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// GOMAXPROCS=10 go test

// Copy/pasted from the standard library's sync/rwmutex_test.go, except for the
// addition of downgradingWriter and the renaming of num_iterations to
// numIterations to shut up Golint.

package sync

import (
	"fmt"
	"runtime"
	"sync/atomic"
	"testing"
)

func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) {
	m.RLock()
	clocked <- true
	<-cunlock
	m.RUnlock()
	cdone <- true
}

func doTestParallelReaders(numReaders, gomaxprocs int) {
	runtime.GOMAXPROCS(gomaxprocs)
	var m RWMutex
	clocked := make(chan bool)
	cunlock := make(chan bool)
	cdone := make(chan bool)
	for i := 0; i < numReaders; i++ {
		go parallelReader(&m, clocked, cunlock, cdone)
	}
	// Wait for all parallel RLock()s to succeed.
	for i := 0; i < numReaders; i++ {
		<-clocked
	}
	for i := 0; i < numReaders; i++ {
		cunlock <- true
	}
	// Wait for the goroutines to finish.
	for i := 0; i < numReaders; i++ {
		<-cdone
	}
}

func TestParallelReaders(t *testing.T) {
	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
	doTestParallelReaders(1, 4)
	doTestParallelReaders(3, 4)
	doTestParallelReaders(4, 2)
}

func reader(rwm *RWMutex, numIterations int, activity *int32, cdone chan bool) {
	for i := 0; i < numIterations; i++ {
		rwm.RLock()
		n := atomic.AddInt32(activity, 1)
		if n < 1 || n >= 10000 {
			panic(fmt.Sprintf("wlock(%d)\n", n))
		}
		for i := 0; i < 100; i++ {
		}
		atomic.AddInt32(activity, -1)
		rwm.RUnlock()
	}
	cdone <- true
}

func writer(rwm *RWMutex, numIterations int, activity *int32, cdone chan bool) {
	for i := 0; i < numIterations; i++ {
		rwm.Lock()
		n := atomic.AddInt32(activity, 10000)
		if n != 10000 {
			panic(fmt.Sprintf("wlock(%d)\n", n))
		}
		for i := 0; i < 100; i++ {
		}
		atomic.AddInt32(activity, -10000)
		rwm.Unlock()
	}
	cdone <- true
}

func downgradingWriter(rwm *RWMutex, numIterations int, activity *int32, cdone chan bool) {
	for i := 0; i < numIterations; i++ {
		rwm.Lock()
		n := atomic.AddInt32(activity, 10000)
		if n != 10000 {
			panic(fmt.Sprintf("wlock(%d)\n", n))
		}
		for i := 0; i < 100; i++ {
		}
		atomic.AddInt32(activity, -10000)
		rwm.DowngradeLock()
		n = atomic.AddInt32(activity, 1)
		if n < 1 || n >= 10000 {
			panic(fmt.Sprintf("wlock(%d)\n", n))
		}
		for i := 0; i < 100; i++ {
		}
		n = atomic.AddInt32(activity, -1)
		rwm.RUnlock()
	}
	cdone <- true
}

func HammerDowngradableRWMutex(gomaxprocs, numReaders, numIterations int) {
	runtime.GOMAXPROCS(gomaxprocs)
	// Number of active readers + 10000 * number of active writers.
	var activity int32
	var rwm RWMutex
	cdone := make(chan bool)
	go writer(&rwm, numIterations, &activity, cdone)
	go downgradingWriter(&rwm, numIterations, &activity, cdone)
	var i int
	for i = 0; i < numReaders/2; i++ {
		go reader(&rwm, numIterations, &activity, cdone)
	}
	go writer(&rwm, numIterations, &activity, cdone)
	go downgradingWriter(&rwm, numIterations, &activity, cdone)
	for ; i < numReaders; i++ {
		go reader(&rwm, numIterations, &activity, cdone)
	}
	// Wait for the 4 writers and all readers to finish.
	for i := 0; i < 4+numReaders; i++ {
		<-cdone
	}
}

func TestDowngradableRWMutex(t *testing.T) {
	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
	n := 1000
	if testing.Short() {
		n = 5
	}
	HammerDowngradableRWMutex(1, 1, n)
	HammerDowngradableRWMutex(1, 3, n)
	HammerDowngradableRWMutex(1, 10, n)
	HammerDowngradableRWMutex(4, 1, n)
	HammerDowngradableRWMutex(4, 3, n)
	HammerDowngradableRWMutex(4, 10, n)
	HammerDowngradableRWMutex(10, 1, n)
	HammerDowngradableRWMutex(10, 3, n)
	HammerDowngradableRWMutex(10, 10, n)
	HammerDowngradableRWMutex(10, 5, n)
}

func TestRWDoubleTryLock(t *testing.T) {
	var rwm RWMutex
	if !rwm.TryLock() {
		t.Fatal("failed to aquire lock")
	}
	if rwm.TryLock() {
		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
	}
}

func TestRWTryLockAfterLock(t *testing.T) {
	var rwm RWMutex
	rwm.Lock()
	if rwm.TryLock() {
		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
	}
}

func TestRWTryLockUnlock(t *testing.T) {
	var rwm RWMutex
	if !rwm.TryLock() {
		t.Fatal("failed to aquire lock")
	}
	rwm.Unlock()
	if !rwm.TryLock() {
		t.Fatal("failed to aquire lock after unlock")
	}
}

func TestTryRLockAfterLock(t *testing.T) {
	var rwm RWMutex
	rwm.Lock()
	if rwm.TryRLock() {
		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
	}
}

func TestTryLockAfterRLock(t *testing.T) {
	var rwm RWMutex
	rwm.RLock()
	if rwm.TryLock() {
		t.Fatal("unexpectedly succeeded in aquiring locked mutex")
	}
}

func TestDoubleTryRLock(t *testing.T) {
	var rwm RWMutex
	if !rwm.TryRLock() {
		t.Fatal("failed to aquire lock")
	}
	if !rwm.TryRLock() {
		t.Fatal("failed to read aquire read locked lock")
	}
}
