github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/sync/pool_test.go (about)

     1  // Copyright 2013 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  // Pool is no-op under race detector, so all these tests do not work.
     6  // +build !race
     7  
     8  package sync_test
     9  
    10  import (
    11  	"runtime"
    12  	"runtime/debug"
    13  	. "sync"
    14  	"sync/atomic"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  func TestPool(t *testing.T) {
    20  	// disable GC so we can control when it happens.
    21  	defer debug.SetGCPercent(debug.SetGCPercent(-1))
    22  	var p Pool
    23  	if p.Get() != nil {
    24  		t.Fatal("expected empty")
    25  	}
    26  	p.Put("a")
    27  	p.Put("b")
    28  	if g := p.Get(); g != "a" {
    29  		t.Fatalf("got %#v; want a", g)
    30  	}
    31  	if g := p.Get(); g != "b" {
    32  		t.Fatalf("got %#v; want b", g)
    33  	}
    34  	if g := p.Get(); g != nil {
    35  		t.Fatalf("got %#v; want nil", g)
    36  	}
    37  
    38  	p.Put("c")
    39  	debug.SetGCPercent(100) // to allow following GC to actually run
    40  	runtime.GC()
    41  	if g := p.Get(); g != nil {
    42  		t.Fatalf("got %#v; want nil after GC", g)
    43  	}
    44  }
    45  
    46  func TestPoolNew(t *testing.T) {
    47  	// disable GC so we can control when it happens.
    48  	defer debug.SetGCPercent(debug.SetGCPercent(-1))
    49  
    50  	i := 0
    51  	p := Pool{
    52  		New: func() interface{} {
    53  			i++
    54  			return i
    55  		},
    56  	}
    57  	if v := p.Get(); v != 1 {
    58  		t.Fatalf("got %v; want 1", v)
    59  	}
    60  	if v := p.Get(); v != 2 {
    61  		t.Fatalf("got %v; want 2", v)
    62  	}
    63  	p.Put(42)
    64  	if v := p.Get(); v != 42 {
    65  		t.Fatalf("got %v; want 42", v)
    66  	}
    67  	if v := p.Get(); v != 3 {
    68  		t.Fatalf("got %v; want 3", v)
    69  	}
    70  }
    71  
    72  // Test that Pool does not hold pointers to previously cached resources.
    73  func TestPoolGC(t *testing.T) {
    74  	testPool(t, true)
    75  }
    76  
    77  // Test that Pool releases resources on GC.
    78  func TestPoolRelease(t *testing.T) {
    79  	testPool(t, false)
    80  }
    81  
    82  func testPool(t *testing.T, drain bool) {
    83  	t.Skip("gccgo imprecise GC breaks this test")
    84  	var p Pool
    85  	const N = 100
    86  loop:
    87  	for try := 0; try < 3; try++ {
    88  		var fin, fin1 uint32
    89  		for i := 0; i < N; i++ {
    90  			v := new(string)
    91  			runtime.SetFinalizer(v, func(vv *string) {
    92  				atomic.AddUint32(&fin, 1)
    93  			})
    94  			p.Put(v)
    95  		}
    96  		if drain {
    97  			for i := 0; i < N; i++ {
    98  				p.Get()
    99  			}
   100  		}
   101  		for i := 0; i < 5; i++ {
   102  			runtime.GC()
   103  			time.Sleep(time.Duration(i*100+10) * time.Millisecond)
   104  			// 1 pointer can remain on stack or elsewhere
   105  			if fin1 = atomic.LoadUint32(&fin); fin1 >= N-1 {
   106  				continue loop
   107  			}
   108  		}
   109  		t.Fatalf("only %v out of %v resources are finalized on try %v", fin1, N, try)
   110  	}
   111  }
   112  
   113  func TestPoolStress(t *testing.T) {
   114  	const P = 10
   115  	N := int(1e6)
   116  	if testing.Short() {
   117  		N /= 100
   118  	}
   119  	var p Pool
   120  	done := make(chan bool)
   121  	for i := 0; i < P; i++ {
   122  		go func() {
   123  			var v interface{} = 0
   124  			for j := 0; j < N; j++ {
   125  				if v == nil {
   126  					v = 0
   127  				}
   128  				p.Put(v)
   129  				v = p.Get()
   130  				if v != nil && v.(int) != 0 {
   131  					t.Fatalf("expect 0, got %v", v)
   132  				}
   133  			}
   134  			done <- true
   135  		}()
   136  	}
   137  	for i := 0; i < P; i++ {
   138  		<-done
   139  	}
   140  }
   141  
   142  func BenchmarkPool(b *testing.B) {
   143  	var p Pool
   144  	b.RunParallel(func(pb *testing.PB) {
   145  		for pb.Next() {
   146  			p.Put(1)
   147  			p.Get()
   148  		}
   149  	})
   150  }
   151  
   152  func BenchmarkPoolOverflow(b *testing.B) {
   153  	var p Pool
   154  	b.RunParallel(func(pb *testing.PB) {
   155  		for pb.Next() {
   156  			for b := 0; b < 100; b++ {
   157  				p.Put(1)
   158  			}
   159  			for b := 0; b < 100; b++ {
   160  				p.Get()
   161  			}
   162  		}
   163  	})
   164  }