package main import ( "fmt" "sync" "time" "runtime" "os" "strconv" ) var Sets, Channels, ChannelSize int = 1, 2, 100 var cons_done, prod_done bool = false, false; var total_operations uint64 = 0 var m sync.Mutex var prodJoin chan int = make(chan int) var consJoin chan int = make(chan int) func selectconsumer( chans [] chan uint64 ) { var count uint64 = 0 for { if cons_done { break } select { case <- chans[0]: case <- chans[1]: } if ! prod_done { count++ } } m.Lock() total_operations += count m.Unlock() consJoin <- 0 } func consumer( channel chan uint64 ) { var count uint64 = 0 for { if cons_done { break } <-channel if ! prod_done { count++ } } m.Lock() total_operations += count m.Unlock() consJoin <- 0 } func selectproducer( chans [] chan uint64 ) { var count uint64 = 0 var checksum uint64 = 0 for { if prod_done { break } checksum = checksum ^ count select { case chans[0] <- count: case chans[1] <- count: } count++ } prodJoin <- 0 } func producer( channel chan uint64 ) { var count uint64 = 0 for { if prod_done { break } channel <- count count++ } prodJoin <- 0 } func usage() { fmt.Printf( "Usage: %v " + "[ sets (> 0) | 'd' (default %v) ] " + "[ ChannelSize (> 0) | 'd' (default %v) ]\n", os.Args[0], Sets, ChannelSize ); os.Exit( 1 ); } func main() { switch len( os.Args ) { case 3: if os.Args[2] != "d" { // default ? ChannelSize, _ = strconv.Atoi( os.Args[2] ) if ChannelSize < 0 { usage(); } } // if fallthrough case 2: if os.Args[1] != "d" { // default ? Sets, _ = strconv.Atoi( os.Args[1] ) if Sets < 1 { usage(); } } // if case 1: // use defaults default: usage(); } // switch runtime.GOMAXPROCS( Sets * 2 + Sets * Channels * 2 ); // fmt.Println("Processors: ",Processors," Channels: ",Channels," ProdsPerChan: ",ProdsPerChan," ConsPerChan: ",ConsPerChan," Channel Size: ",ChannelSize) chans := make( [] chan uint64, Channels ) for i := range chans { chans[i] = make(chan uint64, ChannelSize) } for j := 0; j < Sets; j++ { go selectproducer( chans ) go selectconsumer( chans ) for i := 0; i < Channels; i++ { go producer( chans[i] ) go consumer( chans[i] ) } } // wait 10 seconds time.Sleep(time.Second * 10) // fmt.Println("prod done\n") prod_done = true for j := 0; j < Sets + Sets * Channels; j++ { <-prodJoin } // fmt.Println("cons done\n") cons_done = true for i := range chans { close(chans[i]) } for j := 0; j < Sets + Sets * Channels; j++{ <-consJoin } fmt.Println(total_operations) }