Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/barrier.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/barrier.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/barrier.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,125 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+	"time"
+	"runtime"
+	"os"
+	"strconv"
+)
+
+var Processors, Tasks, BarrierSize int = 1, 1, 2
+var done bool = false;
+var total_operations uint64 = 0
+var m sync.Mutex
+
+var taskJoin chan int = make(chan int, Tasks + 1)
+
+var barWait chan int = make(chan int, 2 * BarrierSize)
+var entryWait chan int = make(chan int, 2 * BarrierSize)
+
+func initBarrier() {
+	for j := 0; j < BarrierSize; j++ {
+		entryWait <- j
+	}
+}
+
+func barrier() {
+	ticket := <-entryWait
+	if ( ticket == -1 ) {
+		entryWait <- -1
+		return
+	}
+	if ( ticket == BarrierSize - 1 ) {
+		for j := 0; j < BarrierSize - 1; j++ {
+			barWait <- j
+		}
+	} else {
+		ticket = <- barWait
+		if ( ticket == -1 ) {
+			barWait <- -1
+			return
+		}
+	}
+
+	// last one out
+	if ( BarrierSize == 1 || ticket == BarrierSize - 2 ) {
+		for j := 0; j < BarrierSize; j++ {
+			entryWait <- j
+		}
+	}
+}
+
+func task() {
+	var count uint64 = 0
+	for {
+		if done { break }
+		barrier()
+		count++
+	}
+	m.Lock()
+	total_operations += count
+	// fmt.Print("C: ",count)
+	m.Unlock()
+	taskJoin <- 0
+}
+
+func usage() {
+	fmt.Printf( "Usage: %v " +
+		"[ processors (> 0) | 'd' (default %v) ] " +
+		"[ BarrierSize (> 0) | 'd' (default %v) ]\n",
+		os.Args[0], Processors, BarrierSize );
+	os.Exit( 1 );
+}
+
+func main() {
+	switch len( os.Args ) {
+		case 3:
+			if os.Args[2] != "d" {							// default ?
+				BarrierSize, _ = strconv.Atoi( os.Args[2] )
+				if BarrierSize < 1 { usage(); }
+			} // if
+		fallthrough
+		case 2:
+			if os.Args[1] != "d" {							// default ?
+				Processors, _ = strconv.Atoi( os.Args[1] )
+				if Processors < 1 { usage(); }
+			} // if
+		case 1:											// use defaults
+		default:
+		usage();
+	} // switch
+	runtime.GOMAXPROCS( Processors );
+	Tasks = Processors
+
+	if ( Tasks < BarrierSize ) {
+        Tasks = BarrierSize
+	}
+
+	// fmt.Println("Processors: ",Processors," Channels: ",Channels," ProdsPerChan: ",ProdsPerChan," ConsPerChan: ",ConsPerChan," Channel Size: ",ChannelSize)
+	taskJoin = make(chan int, Tasks + 1)
+	barWait = make(chan int, 2 * BarrierSize)
+	entryWait = make(chan int, 2 * BarrierSize)
+	initBarrier()
+
+	for j := 0; j < Tasks; j++ {
+		go task()
+	}
+		
+	// wait 10 seconds
+	time.Sleep(time.Second * 10)
+	// fmt.Println("prod done\n")
+	done = true
+
+	for j := 0; j < BarrierSize; j++ {
+		barWait <- -1
+		entryWait <- -1
+	}
+
+	for j := 0; j < Tasks; j++ {
+		<-taskJoin
+	}
+
+    fmt.Println(total_operations)
+}
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/go.mod
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/barrier/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,3 @@
+module barrier
+
+go 1.18
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/churn.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/churn.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/churn.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,156 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+	"math/rand"
+	"time"
+	"runtime"
+	"os"
+	"strconv"
+)
+
+var Processors, Channels, Producers, Consumers, ChannelSize int = 1, 4, 1, 1, 128
+var cons_done, prod_done bool = false, false;
+var total_operations, cons_check, prod_check uint64 = 0, 0, 0
+var m sync.Mutex
+
+var prodJoin chan int = make(chan int, Producers + 1)
+var consJoin chan int = make(chan int, Consumers + 1)
+
+func getRandArray() []int {
+	chanIndices := make( [] int, Channels )
+	for i := 0; i < Channels; i += 1 {
+		chanIndices[i] = i
+	}
+	for i := 0; i < Channels; i += 1 {
+		var loc_1 int  = rand.Intn(Channels) % Channels
+        var loc_2 int  = rand.Intn(Channels) % Channels;
+        var temp int = chanIndices[loc_1]
+        chanIndices[loc_1] = chanIndices[loc_2]
+        chanIndices[loc_2] = temp
+	}
+	return chanIndices
+}
+
+func consumer( chans [] chan uint64 ) {
+	var count uint64 = 0
+	var checksum uint64 = 0
+	var i int = 0
+	chanIndices := getRandArray()
+	for {
+		if cons_done { break }
+		j := <- chans[ chanIndices[ i ] ]
+		i = (i + 1) % Channels
+		checksum = checksum ^ j
+		if ! prod_done { count++ }
+	}
+	m.Lock()
+	total_operations += count
+	cons_check = cons_check ^ checksum
+	m.Unlock()
+	consJoin <- 0
+}
+
+func producer( chans [] chan uint64 ) {
+	var count uint64 = 0
+	var i int = 0
+	var checksum uint64 = 0
+	chanIndices := getRandArray()
+	for {
+		if prod_done { break }
+		chans[ chanIndices[ i ] ] <- count
+		i = (i + 1) % Channels
+		checksum = checksum ^ count
+		count++
+	}
+	m.Lock()
+	total_operations += count
+	prod_check = prod_check ^ checksum
+	m.Unlock()
+	prodJoin <- 0
+}
+
+func usage() {
+	fmt.Printf( "Usage: %v " +
+		"[ processors (> 0) | 'd' (default %v) ] " +
+		"[ ChannelSize (> 0) | 'd' (default %v) ]\n",
+		os.Args[0], Processors, ChannelSize );
+	os.Exit( 1 );
+}
+
+func main() {
+	switch len( os.Args ) {
+		case 3:
+			if os.Args[2] != "d" {							// default ?
+				Channels, _ = strconv.Atoi( os.Args[2] )
+					if Channels < 0 { usage(); }
+			} // if
+		fallthrough
+		case 2:
+			if os.Args[1] != "d" {							// default ?
+				Processors, _ = strconv.Atoi( os.Args[1] )
+				if Processors < 1 { usage(); }
+			} // if
+		case 1:											// use defaults
+		default:
+		usage();
+	} // switch
+	runtime.GOMAXPROCS( Processors );
+	Producers = Processors /2
+	Consumers = Processors /2
+
+	// fmt.Println("Processors: ",Processors," Channels: ",Channels," Prods: ",Producers," Cons: ",Consumers," Channel Size: ",ChannelSize)
+
+	chans := make( [] chan uint64, Channels )
+	for i := range chans {
+		chans[i] = make(chan uint64, ChannelSize)
+	}
+
+	for j := 0; j < Consumers; j++ {
+		go consumer( chans )
+	}
+
+	for j := 0; j < Producers; j++ {
+		go producer( chans )
+	}
+
+	// wait 10 seconds
+	time.Sleep(time.Second * 10)
+	prod_done = true
+
+	for j := 0; j < Producers; j++ {
+		<-prodJoin
+	}
+
+	cons_done = true
+
+	for i := range chans {
+		for j := 0; j < Consumers; j++ {
+			select {
+				case chans[i] <- 0:
+					
+				default:
+					break
+			}
+		}
+	}
+	for j := 0; j < Consumers; j++{
+		<-consJoin
+	}
+	for i := range chans {
+		L: for {
+			select {
+				case k := <-chans[i]:
+					cons_check = cons_check ^ k
+				default:
+					break L
+			}
+		}
+	}
+	if cons_check != prod_check {
+		fmt.Println("\nChecksum mismatch: Cons: %d, Prods: %d", cons_check, prod_check)
+	}
+
+    fmt.Println(total_operations)
+}
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/go.mod
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/churn/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,3 @@
+module churn
+
+go 1.18
Index: c/theses/colby_parsons_MMAth/benchmarks/channels/go/contend.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend.go	(revision 76a84008dfde0f229572e7660c20a913b9486a59)
+++ 	(revision )
@@ -1,140 +1,0 @@
-package main
-
-import (
-	"fmt"
-	"sync"
-	"time"
-	"runtime"
-	"os"
-	"strconv"
-)
-
-var Processors, Channels, ProdsPerChan, ConsPerChan, ChannelSize int = 1, 1, 1, 1, 128
-var cons_done, prod_done bool = false, false;
-var total_operations, cons_check, prod_check uint64 = 0, 0, 0
-var m sync.Mutex
-
-var prodJoin chan int = make(chan int, ProdsPerChan * Channels + 1)
-var consJoin chan int = make(chan int, ConsPerChan * Channels + 1)
-
-func consumer( channel chan uint64 ) {
-	var count uint64 = 0
-	var checksum uint64 = 0
-	for {
-		if cons_done { break }
-		j := <- channel
-		checksum = checksum ^ j
-		if ! prod_done { count++ }
-	}
-	m.Lock()
-	total_operations += count
-	cons_check = cons_check ^ checksum
-	// fmt.Print("C: ",count)
-	m.Unlock()
-	consJoin <- 0
-}
-
-func producer( channel chan uint64 ) {
-	var count uint64 = 0
-	var checksum uint64 = 0
-	for {
-		if prod_done { break }
-		checksum = checksum ^ count
-		channel <- count
-		count++
-	}
-	m.Lock()
-	total_operations += count
-	prod_check = prod_check ^ checksum
-	// fmt.Print("P: ",count, " ")
-	m.Unlock()
-	prodJoin <- 0
-}
-
-func usage() {
-	fmt.Printf( "Usage: %v " +
-		"[ processors (> 0) | 'd' (default %v) ] " +
-		"[ ChannelSize (> 0) | 'd' (default %v) ]\n",
-		os.Args[0], Processors, ChannelSize );
-	os.Exit( 1 );
-}
-
-func main() {
-	switch len( os.Args ) {
-		case 3:
-			if os.Args[2] != "d" {							// default ?
-				ChannelSize, _ = strconv.Atoi( os.Args[1] )
-					if ChannelSize < 0 { usage(); }
-			} // if
-		fallthrough
-		case 2:
-			if os.Args[1] != "d" {							// default ?
-				Processors, _ = strconv.Atoi( os.Args[1] )
-				if Processors < 1 { usage(); }
-			} // if
-		case 1:											// use defaults
-		default:
-		usage();
-	} // switch
-	runtime.GOMAXPROCS( Processors );
-	ProdsPerChan = Processors
-	ConsPerChan = Processors
-
-	// 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 i := range chans {
-		for j := 0; j < ProdsPerChan; j++ {
-			go producer( chans[i] )
-		}
-
-		for j := 0; j < ConsPerChan; j++ {
-			go consumer( chans[i] )
-		}
-	}
-		
-
-	// wait 10 seconds
-	time.Sleep(time.Second * 10)
-	// fmt.Println("prod done\n")
-	prod_done = true
-	for j := 0; j < ProdsPerChan * Channels ; j++ {
-		<-prodJoin
-	}
-	// fmt.Println("cons done\n")
-	cons_done = true
-	for i := range chans {
-		J: for j := 0; j < ConsPerChan; j++ {
-			select {
-				case chans[i] <- 0:
-					
-				default:
-					break J
-			}
-		}
-	}
-	for j := 0; j < ConsPerChan * Channels; j++{
-		<-consJoin
-	}
-	
-	// for i := range chans {
-	// 	L: for {
-	// 		select {
-	// 			case k := <-chans[i]:
-	// 				cons_check = cons_check ^ k
-	// 			default:
-	// 				break L
-	// 		}
-	// 	}
-	// }
-	if cons_check != prod_check {
-		fmt.Println("\nChecksum mismatch: Cons: %d, Prods: %d", cons_check, prod_check)
-	}
-	for i := range chans {
-		close(chans[i])
-	}
-    fmt.Println(total_operations)
-}
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/contend.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/contend.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/contend.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,132 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+	"time"
+	"runtime"
+	"os"
+	"strconv"
+)
+
+var Processors, Channels, ProdsPerChan, ConsPerChan, ChannelSize int = 1, 1, 1, 1, 128
+var cons_done, prod_done bool = false, false;
+var total_operations, cons_check, prod_check uint64 = 0, 0, 0
+var m sync.Mutex
+
+var prodJoin chan int = make(chan int, ProdsPerChan * Channels + 1)
+var consJoin chan int = make(chan int, ConsPerChan * Channels + 1)
+
+func consumer( channel chan uint64 ) {
+	var count uint64 = 0
+	var checksum uint64 = 0
+	for {
+		if cons_done { break }
+		j := <- channel
+		checksum = checksum ^ j
+		if ! prod_done { count++ }
+	}
+	m.Lock()
+	total_operations += count
+	cons_check = cons_check ^ checksum
+	// fmt.Print("C: ",count)
+	m.Unlock()
+	consJoin <- 0
+}
+
+func producer( channel chan uint64 ) {
+	var count uint64 = 0
+	var checksum uint64 = 0
+	for {
+		if prod_done { break }
+		checksum = checksum ^ count
+		channel <- count
+		count++
+	}
+	m.Lock()
+	total_operations += count
+	prod_check = prod_check ^ checksum
+	// fmt.Print("P: ",count, " ")
+	m.Unlock()
+	prodJoin <- 0
+}
+
+func usage() {
+	fmt.Printf( "Usage: %v " +
+		"[ processors (> 0) | 'd' (default %v) ] " +
+		"[ ChannelSize (> 0) | 'd' (default %v) ]\n",
+		os.Args[0], Processors, 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 ?
+				Processors, _ = strconv.Atoi( os.Args[1] )
+				if Processors < 1 { usage(); }
+			} // if
+		case 1:											// use defaults
+		default:
+		usage();
+	} // switch
+	runtime.GOMAXPROCS( Processors );
+	ProdsPerChan = Processors /2
+	ConsPerChan = Processors / 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 i := range chans {
+		for j := 0; j < ProdsPerChan; j++ {
+			go producer( chans[i] )
+		}
+
+		for j := 0; j < ConsPerChan; j++ {
+			go consumer( chans[i] )
+		}
+	}
+		
+
+	// wait 10 seconds
+	time.Sleep(time.Second * 10)
+	// fmt.Println("prod done\n")
+	prod_done = true
+	for j := 0; j < ProdsPerChan * Channels ; j++ {
+		<-prodJoin
+	}
+	// fmt.Println("cons done\n")
+	cons_done = true
+	for i := range chans {
+		L: for {
+			select {
+				case k := <-chans[i]:
+					cons_check = cons_check ^ k
+				default:
+					break L
+			}
+		}
+	}
+	for i := range chans {
+		close(chans[i])
+	}
+
+	for j := 0; j < ConsPerChan * Channels; j++{
+		<-consJoin
+	}
+	
+	
+	if cons_check != prod_check {
+		fmt.Println("\nChecksum mismatch: Cons: %d, Prods: %d", cons_check, prod_check)
+	}
+    fmt.Println(total_operations)
+}
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/go.mod
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/contend/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,3 @@
+module contend
+
+go 1.18
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/daisy_chain.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/daisy_chain.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/daisy_chain.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,70 @@
+package main
+
+import (
+	"fmt"
+	"time"
+	"runtime"
+	"sync"
+	"os"
+	"strconv"
+)
+
+var done bool = false;
+var total_operations uint64 = 0
+var Processors int = 1
+var m sync.Mutex
+
+var taskJoin chan int = make(chan int, 2)
+var chain chan int = make(chan int, 2 )
+
+func Task() {
+	var count uint64 = 0 
+	for {
+		if done { break }
+		<-chain
+		chain<-0
+		count++;
+	}
+	
+	m.Lock()
+	total_operations += count
+	m.Unlock()
+	taskJoin <- 0
+}
+
+func main() {
+	switch len( os.Args ) {
+		case 2:
+			if os.Args[1] != "d" {							// default ?
+				Processors, _ = strconv.Atoi( os.Args[1] )
+			} // if
+		case 1:											// use defaults
+		default:
+			fmt.Printf( "Invalid args" );
+			os.Exit( 1 );
+	} // switch
+	runtime.GOMAXPROCS( Processors );
+
+	taskJoin= make(chan int, Processors)
+	chain= make(chan int, 2 * Processors )
+	
+	chain <- 0
+
+	for i := 0; i < Processors; i++ {
+		go Task()
+	}
+		
+	// wait 10 seconds
+	time.Sleep(time.Second * 10)
+	// fmt.Println("prod done\n")
+	done = true
+
+	for i := 0; i < Processors; i++ {
+		chain <- 0
+	}
+	for i := 0; i < Processors; i++ {
+		<-taskJoin
+	}
+
+    fmt.Println(total_operations)
+}
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/go.mod
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/daisy_chain/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,3 @@
+module daisy_chain
+
+go 1.18
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/go.mod
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,3 @@
+module hot_potato
+
+go 1.18
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/hot_potato.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/hot_potato.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/hot_potato/hot_potato.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,72 @@
+package main
+
+import (
+	"fmt"
+	"time"
+	"runtime"
+	"sync"
+	"os"
+	"strconv"
+)
+
+var done bool = false;
+var total_operations uint64 = 0
+var Processors int = 1
+var m sync.Mutex
+
+var taskJoin chan int = make(chan int, 2)
+
+func Task( chans [] chan uint64, id int ) {
+	var count uint64 = 0
+	right := (id + 1) % Processors
+	for {
+		if done { break }
+		<-chans[id]
+		chans[right]<-0
+		count++;
+	}
+	m.Lock()
+	total_operations += count
+	m.Unlock()
+	taskJoin <- 0
+}
+
+func main() {
+	switch len( os.Args ) {
+		case 2:
+			if os.Args[1] != "d" {							// default ?
+				Processors, _ = strconv.Atoi( os.Args[1] )
+			} // if
+		case 1:											// use defaults
+		default:
+			fmt.Printf( "Invalid args" );
+			os.Exit( 1 );
+	} // switch
+	runtime.GOMAXPROCS( Processors );
+
+	taskJoin = make(chan int, Processors)
+	chans := make( [] chan uint64, Processors )
+	for i := range chans {
+		chans[i] = make(chan uint64, 3)
+	}
+
+	chans[0] <- 0
+
+	for i := 0; i < Processors; i++ {
+		go Task( chans, i )
+	}
+		
+	// wait 10 seconds
+	time.Sleep(time.Second * 10)
+	// fmt.Println("prod done\n")
+	done = true
+
+	for i := 0; i < Processors; i++ {
+		chans[i] <- 0
+	}
+	for i := 0; i < Processors; i++ {
+		<-taskJoin
+	}
+
+    fmt.Println(total_operations)
+}
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/go.mod
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,3 @@
+module ping_pong
+
+go 1.18
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/ping_pong.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/ping_pong.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/ping_pong/ping_pong.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,54 @@
+package main
+
+import (
+	"fmt"
+	"time"
+	"runtime"
+)
+
+var done bool = false;
+var total_operations uint64 = 0
+
+var taskJoin chan int = make(chan int, 2)
+
+var ping chan int = make(chan int, 2 )
+var pong chan int = make(chan int, 2 )
+
+func Ping() {
+	for {
+		if done { break }
+		pong <- 1
+		<-ping
+	}
+	taskJoin <- 0
+}
+
+func Pong() {
+	for {
+		if done { break }
+		<-pong
+		ping <- 0
+		total_operations++
+	}
+	taskJoin <- 0
+}
+
+func main() {
+	runtime.GOMAXPROCS( 2 );
+
+	go Ping()
+	go Pong()
+		
+	// wait 10 seconds
+	time.Sleep(time.Second * 10)
+	// fmt.Println("prod done\n")
+	done = true
+
+	ping <- 2
+	pong <- 2
+
+	<-taskJoin
+	<-taskJoin
+
+    fmt.Println(total_operations)
+}
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/go.mod
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/go.mod	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,3 @@
+module pub_sub
+
+go 1.18
Index: doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/pub_sub.go
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/pub_sub.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
+++ doc/theses/colby_parsons_MMAth/benchmarks/channels/go/pub_sub/pub_sub.go	(revision e2f827f9e2081dbb0e6aa5328faacc19f8633e06)
@@ -0,0 +1,145 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+	"time"
+	"runtime"
+	"os"
+	"strconv"
+)
+
+var Processors, Tasks int = 1, 1
+var BarrierSize int = 2
+var done bool = false;
+var total_operations uint64 = 0
+var m sync.Mutex
+
+var taskJoin chan int = make(chan int, Tasks + 1)
+
+var barWait chan int = make(chan int, 2 * BarrierSize)
+var entryWait chan int = make(chan int, 2 * BarrierSize)
+
+func flushBarrier() {
+	for j := 0; j < BarrierSize; j++ {
+		barWait <- -1
+		entryWait <- -1
+	}
+}
+
+func initBarrier() {
+	for j := 0; j < BarrierSize; j++ {
+		entryWait <- j
+	}
+}
+
+func barrier() {
+	ticket := <-entryWait
+	if ( ticket == -1 ) {
+		entryWait <- -1
+		return
+	}
+	if ( ticket == BarrierSize - 1 ) {
+		for j := 0; j < BarrierSize - 1; j++ {
+			barWait <- j
+		}
+	} else {
+		ticket = <- barWait
+		if ( ticket == -1 ) {
+			barWait <- -1
+			return
+		}
+	}
+
+	// last one out
+	if ( BarrierSize == 1 || ticket == BarrierSize - 2 ) {
+		for j := 0; j < BarrierSize; j++ {
+			entryWait <- j
+		}
+	}
+}
+
+func task( chans [] chan uint64 ) {
+	var count uint64 = 0
+	for {
+		if done { break }
+		for j := 0; j < Tasks; j++ {
+			chans[j] <- 0
+		}
+
+		for j := 0; j < Tasks; j++ {
+			<- chans[j]
+		}
+		barrier()
+		count++
+	}
+	m.Lock()
+	total_operations += count
+	// fmt.Print("C: ",count)
+	m.Unlock()
+	taskJoin <- 0
+}
+
+func usage() {
+	fmt.Printf( "Usage: %v " +
+		"[ processors (> 0) | 'd' (default %v) ] " +
+		"[ BarrierSize (> 0) | 'd' (default %v) ]\n",
+		os.Args[0], Processors, BarrierSize );
+	os.Exit( 1 );
+}
+
+func main() {
+	switch len( os.Args ) {
+		case 3:
+			if os.Args[2] != "d" {							// default ?
+				Tasks, _ = strconv.Atoi( os.Args[2] )
+				if Tasks < 1 { usage(); }
+			} // if
+		fallthrough
+		case 2:
+			if os.Args[1] != "d" {							// default ?
+				Processors, _ = strconv.Atoi( os.Args[1] )
+				if Processors < 1 { usage(); }
+			} // if
+		case 1:											// use defaults
+		default:
+		usage();
+	} // switch
+	runtime.GOMAXPROCS( Processors );
+	Tasks = Processors
+	BarrierSize = Tasks
+
+	// fmt.Println("Processors: ",Processors," Channels: ",Channels," ProdsPerChan: ",ProdsPerChan," ConsPerChan: ",ConsPerChan," Channel Size: ",ChannelSize)
+	taskJoin = make(chan int, Tasks + 1)
+	barWait = make(chan int, 2 * BarrierSize)
+	entryWait = make(chan int, 2 * BarrierSize)
+	initBarrier()
+
+	chans := make( [] chan uint64, Tasks )
+	for i := range chans {
+		chans[i] = make(chan uint64, 2 * Tasks)
+	}
+
+	for j := 0; j < Tasks; j++ {
+		go task( chans )
+	}
+		
+	// wait 10 seconds
+	time.Sleep(time.Second * 10)
+	// fmt.Println("prod done\n")
+	done = true
+
+	for i := 0; i < Tasks; i++ {
+		for j := 0; j < Tasks; j++ {
+			chans[i] <- 0
+		}
+	}
+
+	flushBarrier()
+	
+	for j := 0; j < Tasks; j++ {
+		<-taskJoin
+	}
+
+    fmt.Println(total_operations)
+}
