github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/runtime/race/testdata/sync_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package race_test
     6  
     7  import (
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestNoRaceCond(t *testing.T) { // tsan's test02
    14  	ch := make(chan bool, 1)
    15  	var x int = 0
    16  	var mu sync.Mutex
    17  	var cond *sync.Cond = sync.NewCond(&mu)
    18  	var condition int = 0
    19  	var waker func()
    20  	waker = func() {
    21  		x = 1
    22  		mu.Lock()
    23  		condition = 1
    24  		cond.Signal()
    25  		mu.Unlock()
    26  	}
    27  
    28  	var waiter func()
    29  	waiter = func() {
    30  		go waker()
    31  		cond.L.Lock()
    32  		for condition != 1 {
    33  			cond.Wait()
    34  		}
    35  		cond.L.Unlock()
    36  		x = 2
    37  		ch <- true
    38  	}
    39  	go waiter()
    40  	<-ch
    41  }
    42  
    43  func TestRaceCond(t *testing.T) { // tsan's test50
    44  	ch := make(chan bool, 2)
    45  
    46  	var x int = 0
    47  	var mu sync.Mutex
    48  	var condition int = 0
    49  	var cond *sync.Cond = sync.NewCond(&mu)
    50  
    51  	var waker func() = func() {
    52  		<-time.After(1e5)
    53  		x = 1
    54  		mu.Lock()
    55  		condition = 1
    56  		cond.Signal()
    57  		mu.Unlock()
    58  		<-time.After(1e5)
    59  		mu.Lock()
    60  		x = 3
    61  		mu.Unlock()
    62  		ch <- true
    63  	}
    64  
    65  	var waiter func() = func() {
    66  		mu.Lock()
    67  		for condition != 1 {
    68  			cond.Wait()
    69  		}
    70  		mu.Unlock()
    71  		x = 2
    72  		ch <- true
    73  	}
    74  	x = 0
    75  	go waker()
    76  	go waiter()
    77  	<-ch
    78  	<-ch
    79  }
    80  
    81  // We do not currently automatically
    82  // parse this test. It is intended that the creation
    83  // stack is observed manually not to contain
    84  // off-by-one errors
    85  func TestRaceAnnounceThreads(t *testing.T) {
    86  	const N = 7
    87  	allDone := make(chan bool, N)
    88  
    89  	var x int
    90  
    91  	var f, g, h func()
    92  	f = func() {
    93  		x = 1
    94  		go g()
    95  		go func() {
    96  			x = 1
    97  			allDone <- true
    98  		}()
    99  		x = 2
   100  		allDone <- true
   101  	}
   102  
   103  	g = func() {
   104  		for i := 0; i < 2; i++ {
   105  			go func() {
   106  				x = 1
   107  				allDone <- true
   108  			}()
   109  			allDone <- true
   110  		}
   111  	}
   112  
   113  	h = func() {
   114  		x = 1
   115  		x = 2
   116  		go f()
   117  		allDone <- true
   118  	}
   119  
   120  	go h()
   121  
   122  	for i := 0; i < N; i++ {
   123  		<-allDone
   124  	}
   125  }
   126  
   127  func TestNoRaceAfterFunc1(t *testing.T) {
   128  	i := 2
   129  	c := make(chan bool)
   130  	var f func()
   131  	f = func() {
   132  		i--
   133  		if i >= 0 {
   134  			time.AfterFunc(0, f)
   135  		} else {
   136  			c <- true
   137  		}
   138  	}
   139  
   140  	time.AfterFunc(0, f)
   141  	<-c
   142  }
   143  
   144  func TestNoRaceAfterFunc2(t *testing.T) {
   145  	var x int
   146  	timer := time.AfterFunc(10, func() {
   147  		x = 1
   148  	})
   149  	defer timer.Stop()
   150  	_ = x
   151  }
   152  
   153  func TestNoRaceAfterFunc3(t *testing.T) {
   154  	c := make(chan bool, 1)
   155  	x := 0
   156  	time.AfterFunc(1e7, func() {
   157  		x = 1
   158  		c <- true
   159  	})
   160  	<-c
   161  }
   162  
   163  func TestRaceAfterFunc3(t *testing.T) {
   164  	c := make(chan bool, 2)
   165  	x := 0
   166  	time.AfterFunc(1e7, func() {
   167  		x = 1
   168  		c <- true
   169  	})
   170  	time.AfterFunc(2e7, func() {
   171  		x = 2
   172  		c <- true
   173  	})
   174  	<-c
   175  	<-c
   176  }
   177  
   178  // This test's output is intended to be
   179  // observed manually. One should check
   180  // that goroutine creation stack is
   181  // comprehensible.
   182  func TestRaceGoroutineCreationStack(t *testing.T) {
   183  	var x int
   184  	var ch = make(chan bool, 1)
   185  
   186  	f1 := func() {
   187  		x = 1
   188  		ch <- true
   189  	}
   190  	f2 := func() { go f1() }
   191  	f3 := func() { go f2() }
   192  	f4 := func() { go f3() }
   193  
   194  	go f4()
   195  	x = 2
   196  	<-ch
   197  }
   198  
   199  // A nil pointer in a mutex method call should not
   200  // corrupt the race detector state.
   201  // Used to hang indefinitely.
   202  func TestNoRaceNilMutexCrash(t *testing.T) {
   203  	var mutex sync.Mutex
   204  	panics := 0
   205  	defer func() {
   206  		if x := recover(); x != nil {
   207  			mutex.Lock()
   208  			panics++
   209  			mutex.Unlock()
   210  		} else {
   211  			panic("no panic")
   212  		}
   213  	}()
   214  	var othermutex *sync.RWMutex
   215  	othermutex.RLock()
   216  }