github.com/dshulyak/uring@v0.0.0-20210209113719-1b2ec51f1542/fixed/pool_test.go (about) 1 package fixed 2 3 import ( 4 "encoding/binary" 5 "io/ioutil" 6 "os" 7 "sync" 8 "syscall" 9 "testing" 10 11 "github.com/dshulyak/uring" 12 "github.com/dshulyak/uring/loop" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestWrite(t *testing.T) { 17 l, err := loop.Setup(1024, nil, nil) 18 require.NoError(t, err) 19 t.Cleanup(func() { l.Close() }) 20 21 f, err := ioutil.TempFile("", "test") 22 require.NoError(t, err) 23 defer os.Remove(f.Name()) 24 25 n := 100 26 size := 10 27 pool, err := New(l, size, n) 28 require.NoError(t, err) 29 30 run := func() { 31 for i := 0; i < n; i++ { 32 buf := pool.Get() 33 defer pool.Put(buf) 34 cqe, err := l.Syscall(func(sqe *uring.SQEntry) { 35 uring.WriteFixed(sqe, f.Fd(), buf.Base(), buf.Len(), 0, 0, buf.Index()) 36 }) 37 require.NoError(t, err) 38 require.Equal(t, int32(10), cqe.Result(), syscall.Errno(-cqe.Result())) 39 } 40 } 41 // run it couple of times to test that buffers are reused correctly 42 for i := 0; i < 3; i++ { 43 run() 44 } 45 } 46 47 func TestConcurrentWrites(t *testing.T) { 48 l, err := loop.Setup(1024, nil, nil) 49 require.NoError(t, err) 50 t.Cleanup(func() { l.Close() }) 51 52 f, err := ioutil.TempFile("", "test-concurrent-writes-") 53 require.NoError(t, err) 54 defer os.Remove(f.Name()) 55 56 var wg sync.WaitGroup 57 var n int64 = 10000 58 59 pool, err := New(l, 8, int(n)) 60 require.NoError(t, err) 61 for i := int64(0); i < n; i++ { 62 wg.Add(1) 63 go func(i uint64) { 64 buf := pool.Get() 65 defer pool.Put(buf) 66 binary.BigEndian.PutUint64(buf.Bytes(), i) 67 _, _ = l.Syscall(func(sqe *uring.SQEntry) { 68 uring.WriteFixed(sqe, f.Fd(), buf.Base(), buf.Len(), i*8, 0, buf.Index()) 69 }) 70 wg.Done() 71 }(uint64(i)) 72 } 73 wg.Wait() 74 75 buf2 := make([]byte, 8) 76 for i := int64(0); i < n; i++ { 77 _, err := f.ReadAt(buf2, i*8) 78 require.NoError(t, err) 79 rst := binary.BigEndian.Uint64(buf2[:]) 80 require.Equal(t, i, int64(rst)) 81 } 82 } 83 84 func BenchmarkPool(b *testing.B) { 85 l, err := loop.Setup(1024, nil, nil) 86 require.NoError(b, err) 87 b.Cleanup(func() { l.Close() }) 88 89 pool, err := New(l, 8, 50000) 90 require.NoError(b, err) 91 92 b.ResetTimer() 93 b.RunParallel(func(pb *testing.PB) { 94 for pb.Next() { 95 buf := pool.Get() 96 buf.B[0] = 10 97 pool.Put(buf) 98 } 99 }) 100 } 101 102 func BenchmarkSyncPool(b *testing.B) { 103 pool := sync.Pool{ 104 New: func() interface{} { 105 return make([]byte, 8) 106 }, 107 } 108 b.RunParallel(func(pb *testing.PB) { 109 for pb.Next() { 110 buf := pool.Get().([]byte) 111 buf[0] = 10 112 pool.Put(buf) 113 } 114 }) 115 }