func benchmarkEndToEnd(dial func() (*Client, error), b *testing.B) { b.StopTimer() once.Do(startServer) client, err := dial() if err != nil { b.Fatal("error dialing:", err) } // Synchronous calls args := &Args{7, 8} procs := runtime.GOMAXPROCS(-1) N := int32(b.N) var wg sync.WaitGroup wg.Add(procs) b.StartTimer() for p := 0; p < procs; p++ { go func() { reply := new(Reply) for atomic.AddInt32(&N, -1) >= 0 { err := client.Call("Arith.Add", args, reply) if err != nil { b.Critical("rpc error: Add: expected no error but got string %q", err.Error()) } if reply.C != args.A+args.B { b.Critical("rpc error: Add: expected %d got %d", reply.C, args.A+args.B) } } wg.Done() }() } wg.Wait() }
func benchmarkEndToEndAsync(dial func() (*Client, error), b *testing.B) { const MaxConcurrentCalls = 100 b.StopTimer() once.Do(startServer) client, err := dial() if err != nil { b.Fatal("error dialing:", err) } // Asynchronous calls args := &Args{7, 8} procs := 4 * runtime.GOMAXPROCS(-1) send := int32(b.N) recv := int32(b.N) var wg sync.WaitGroup wg.Add(procs) gate := make(chan bool, MaxConcurrentCalls) res := make(chan *Call, MaxConcurrentCalls) b.StartTimer() for p := 0; p < procs; p++ { go func() { for atomic.AddInt32(&send, -1) >= 0 { gate <- true reply := new(Reply) client.Go("Arith.Add", args, reply, res) } }() go func() { for call := range res { A := call.Args.(*Args).A B := call.Args.(*Args).B C := call.Reply.(*Reply).C if A+B != C { b.Critical("incorrect reply: Add: expected %d got %d", A+B, C) } <-gate if atomic.AddInt32(&recv, -1) == 0 { close(res) } } wg.Done() }() } wg.Wait() }