detalhes finais do relatorio
[3hU9fRjo95.git] / pc_monitor_cond~
blob63c2b4826383893242c8c1e2fd1b8e46635757be
1 /* pc_monitor.go */
3 package main
5 import (
6         . "fmt"
7         "crypto/rand"
8         "time"
9         . "sync"
12 func random_between (begin, end int64) int64 {
13         random_byte := make([]byte, 1)
14         rand.Read(random_byte)
15         return int64(random_byte[0]) % (end - begin + 1) + begin
18 func random_sleep () {
19         time.Sleep(random_between(0, MAX_SLEEP_TIME) * 10e7)
22 func signal (channel chan int) {
23         if len(channel) < cap(channel) || cap(channel) == 0 {
24                 channel <- 0
25         }
28 func wait (channel chan int) {
29         <-channel
32 const (
33         MAX_SLEEP_TIME = 5
34         BUFFER_SIZE = 5
37 type Monitor struct {
38         mutex *Mutex
39         empty, full chan int
40         buffer []int
41         front, rear, count int
44 var monitor *Monitor
46 func newMonitor () *Monitor {
47         return &Monitor {
48                 new(Mutex),
49                 make(chan int),
50                 make(chan int),
51                 make([]int, BUFFER_SIZE),
52                 0, 0, 0 }
55 func (m *Monitor) produce (i int) {
56         m.mutex.Lock()
57                 for m.count == BUFFER_SIZE {
58                         c := make(chan int)
59                         go waiter(m.empty, c) // necessário para simular a atomicidade
60                         m.mutex.Unlock()
61                         wait(c)    // variável de condição
62                         m.mutex.Lock()
63                 }
64                 Println("producing:", i)
65                 m.buffer[m.rear] = i
66                 m.rear = (m.rear + 1) % BUFFER_SIZE
67                 m.count++
68                 signal(m.full)
69         m.mutex.Unlock()
72 func (m *Monitor) consume () {
73         m.mutex.Lock()
74                 for m.count == 0 {
75                         c := make(chan int)
76                         go waiter(m.full, c) // necessário para simular a atomicidade
77                         m.mutex.Unlock()
78                         wait(c)
79                         m.mutex.Lock()
80                 }
81                 v := m.buffer[m.front]
82                 m.front = (m.front + 1) % BUFFER_SIZE
83                 m.count--
84                 Println("\t\t\tconsuming:", v)
85                 signal(m.empty)
86         m.mutex.Unlock()
89 func producer () {
90         for i := 0; ; i++ { // laço infinito
91                 monitor.produce(i)
92                 random_sleep()
93         }
96 func consumer () {
97         for { // laço infinito
98                 monitor.consume()
99                 random_sleep()
100         }
103 func main () {
104         monitor = newMonitor()
105         go producer()
106         go consumer()
107         wait(make(chan int)) // espera indefinidamente