func (s *SpcInfo) sendio(wg *sync.WaitGroup, iostream <-chan *IoStats, iotime chan<- *IoStats) { defer wg.Done() buffer := make([]byte, 4*KB*64) for iostat := range iostream { // Make sure the io is correct io := iostat.Io godbc.Invariant(io) if io.Asu == 3 { s.asus[ASU3].WriteAt( buffer[0:io.Blocks*4*KB], int64(io.Offset)*int64(4*KB)) } else { // Send the io if io.Isread { if s.pblcache == nil { s.asus[io.Asu-1].ReadAt(buffer[0:io.Blocks*4*KB], int64(io.Offset)*4*KB) } else { read(s.asus[io.Asu-1], s.pblcache, io.Asu, io.Offset, io.Blocks, buffer[0:io.Blocks*4*KB]) } } else { if s.pblcache == nil { s.asus[io.Asu-1].WriteAt(buffer[0:io.Blocks*4*KB], int64(io.Offset)*4*KB) } else { write(s.asus[io.Asu-1], s.pblcache, io.Asu, io.Offset, io.Blocks, buffer[0:io.Blocks*4*KB]) } } } // Report back the latency iostat.Latency = time.Now().Sub(iostat.Start) iotime <- iostat } }
// Use as a goroutine to start the io workload // Create one of these per context set on Spc1Init() func (s *SpcInfo) Context(wg *sync.WaitGroup, iotime chan<- *IoStats, quit <-chan struct{}, runlen, context int) { defer wg.Done() // Spc generator specifies that each context have // 8 io streams. Spc generator will specify which // io stream to use. streams := 8 iostreams := make([]chan *IoStats, streams) var iostreamwg sync.WaitGroup for stream := 0; stream < streams; stream++ { // Allow for queued requests iostreams[stream] = make(chan *IoStats, 64) // Create 32 io contexts per stream for i := 0; i < 32; i++ { iostreamwg.Add(1) go s.sendio(&iostreamwg, iostreams[stream], iotime) } } start := time.Now() lastiotime := start stop := time.After(time.Second * time.Duration(runlen)) ioloop := true for ioloop { select { case <-quit: ioloop = false case <-stop: ioloop = false default: // Get the next io io := spc1.NewSpc1Io(context) err := io.Generate() godbc.Check(err == nil) godbc.Invariant(io) // Check how much time we should wait sleep_time := start.Add(io.When).Sub(lastiotime) if sleep_time > 0 { time.Sleep(sleep_time) } // Send io to io stream iostreams[io.Stream] <- &IoStats{ Io: io, Start: time.Now(), } lastiotime = time.Now() } } // close the streams for this context for stream := 0; stream < streams; stream++ { close(iostreams[stream]) } iostreamwg.Wait() }