85 lines
1.3 KiB
V
85 lines
1.3 KiB
V
import sync
|
|
import time
|
|
|
|
struct St {
|
|
mut:
|
|
a int
|
|
}
|
|
|
|
fn (shared x St) f(shared z St) {
|
|
for _ in 0 .. reads_per_thread {
|
|
rlock x { // other instances may read at the same time
|
|
time.sleep(time.millisecond)
|
|
assert x.a == 7 || x.a == 5
|
|
}
|
|
}
|
|
lock z {
|
|
z.a--
|
|
}
|
|
}
|
|
|
|
fn g() shared St {
|
|
shared x := St{a: 12 }
|
|
return x
|
|
}
|
|
|
|
fn h() ?shared St {
|
|
return error('no value')
|
|
}
|
|
|
|
fn k() {
|
|
shared x := g()
|
|
shared y := h() or {
|
|
shared f := St{}
|
|
f
|
|
}
|
|
shared z := h()?
|
|
shared p := v
|
|
v := rlock z { z.a }
|
|
rlock x; lock y, z; rlock p {
|
|
z.a = x.a + y.a
|
|
}
|
|
println(v)
|
|
}
|
|
|
|
const (
|
|
reads_per_thread = 30
|
|
read_threads = 10
|
|
writes = 5
|
|
)
|
|
|
|
fn test_shared_lock() {
|
|
// object with separate read/write lock
|
|
shared x := &St {
|
|
a: 5
|
|
}
|
|
shared z :=
|
|
&St{
|
|
a: read_threads
|
|
}
|
|
for _ in 0.. read_threads {
|
|
go x.f(shared z)
|
|
}
|
|
for i in 0..writes {
|
|
lock x { // wait for ongoing reads to finish, don't start new ones
|
|
x.a = 17 // this value should never be read
|
|
time.sleep(50* time.millisecond)
|
|
x.a = if (i & 1) == 0 {
|
|
7} else {5}
|
|
} // now new reads are possible again
|
|
time.sleep(20*time.millisecond)
|
|
}
|
|
// wait until all read threads are finished
|
|
for finished:=false;; {
|
|
mut rr := 0
|
|
rlock z {
|
|
rr = z.a
|
|
finished = z.a == 0
|
|
}
|
|
if finished {
|
|
break
|
|
}
|
|
time.sleep(100*time.millisecond)
|
|
}
|
|
}
|