Source file src/runtime/race/testdata/sync_test.go

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

View as plain text