-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathqueue_test.go
More file actions
96 lines (83 loc) · 2.13 KB
/
queue_test.go
File metadata and controls
96 lines (83 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// queue_test.go
package queue
import (
"fmt"
"runtime"
"sync/atomic"
"testing"
)
var counter int32
var q = New()
const NUM_ENQUEUE = 5000000
// queuer starts a goroutine that concurrently queues and enqueues shared incremental values until NUM_ENQUEUE is reached
func queuer(id int, dequeued chan int, done chan int) {
go func() {
runtime.LockOSThread()
for {
// Enqueuing a value
c := int(atomic.AddInt32(&counter, 1))
if c > NUM_ENQUEUE {
break
}
q.Enqueue(c)
// Dequeuing a value
v, ok := q.Dequeue()
if !ok {
fmt.Println("Dequeue returned false")
} else {
dequeued <- v.(int)
}
}
done <- id
}()
}
// Test_Queue starts equal number of goroutines as there are CPU's, each goroutine Enqueueing and Dequeueing
// concurrently an increamental value until NUM_ENQUEUE has been reached.
// The test is passed if the dequeued values are the same as the enqueued
func Test_Queue(t *testing.T) {
queuers := runtime.NumCPU()
runtime.GOMAXPROCS(queuers)
fmt.Printf("CPU's: %d\n", queuers)
// Create the channel that will check read results. Buffer overkill
dequeued := make(chan int, NUM_ENQUEUE)
// Create the channel that will retrieve done message from the queuers
done := make(chan int, queuers)
// An array keeping count of the number of times each value is dequeued
valcount := make([]int, NUM_ENQUEUE)
for i := 0; i < queuers; i++ {
// Starting up a queuer
queuer(i, dequeued, done)
}
for i := 0; i < NUM_ENQUEUE; i++ {
// Checking if any queuers are done
/*for j:=0; j<queuers; j++ {
select {
case <-l_done[j]: fmt.Printf("Queuer %d is done\n", j)
default:
}
}*/
select {
case v := <-dequeued:
if v < 1 || v > NUM_ENQUEUE {
t.Errorf("Value %d is out of range", v)
break
}
valcount[v-1]++
}
}
for i := 0; i < NUM_ENQUEUE; i++ {
switch {
case valcount[i] == 0:
t.Errorf("Value %d never returned", i)
case valcount[i] > 1:
t.Errorf("Value %d returned %d times", i, valcount[i])
}
}
// Checking if any queuers are done
for j := 0; j < queuers; j++ {
select {
case id := <-done:
fmt.Printf("Queuer %d is done\n", id)
}
}
}