Skip to content

Commit 67e7b62

Browse files
committed
introduce query_wait and family
1 parent 39bd42f commit 67e7b62

File tree

3 files changed

+162
-2
lines changed

3 files changed

+162
-2
lines changed

src/QuantumSavory.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ export
7373
observable,
7474
# uptotime.jl
7575
uptotime!, overwritetime!,
76-
# tags.jl and queries.jl
77-
Tag, tag!, untag!, W, ❓, query, queryall, querydelete!, findfreeslot,
76+
# tags.jl and queries.jl and querywait.jl
77+
Tag, tag!, untag!, W, ❓, query, queryall, querydelete!, query_wait, querydelete_wait!,
78+
findfreeslot,
7879
#messagebuffer.jl
7980
MessageBuffer,
8081
# quantumchannel.jl
@@ -140,6 +141,7 @@ include("baseops/uptotime.jl")
140141
include("baseops/observable.jl")
141142

142143
include("queries.jl")
144+
include("querywait.jl")
143145

144146
include("representations.jl")
145147
include("backgrounds.jl")

src/querywait.jl

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# TODO weird ordering of what should be kwargs due to https://github.com/JuliaDynamics/ResumableFunctions.jl/issues/135
2+
@resumable function _query_wait(sim, reg::Register, locked::Union{Nothing,Bool}, assigned::Union{Nothing,Bool}, args...)
3+
q = query(reg, args...; locked, assigned)
4+
while isnothing(q)
5+
@yield onchange_tag(reg)
6+
q = query(reg, args...; locked, assigned)
7+
end
8+
return q
9+
end
10+
function query_wait(store::Register, args...; locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing)
11+
# TODO weird ordering of what should be kwargs due to https://github.com/JuliaDynamics/ResumableFunctions.jl/issues/135
12+
return @process _query_wait(get_time_tracker(store), store, locked, assigned, args...)
13+
end
14+
15+
@resumable function _query_wait(sim, mb::MessageBuffer, args...)
16+
q = query(mb, args...)
17+
while isnothing(q)
18+
@yield wait(mb)
19+
q = query(mb, args...)
20+
end
21+
return q
22+
end
23+
function query_wait(store::MessageBuffer, args...)
24+
return @process _query_wait(get_time_tracker(store), store, args...)
25+
end
26+
27+
@resumable function _querydelete_wait(sim, mb::Register, locked::Union{Nothing,Bool}, assigned::Union{Nothing,Bool}, args...)
28+
q = querydelete!(mb, args...; locked, assigned)
29+
while isnothing(q)
30+
@yield onchange_tag(mb)
31+
q = querydelete!(mb, args...; locked, assigned)
32+
end
33+
return q
34+
end
35+
function querydelete_wait!(store::Register, args...; locked::Union{Nothing,Bool}=nothing, assigned::Union{Nothing,Bool}=nothing)
36+
return @process _querydelete_wait(get_time_tracker(store), store, locked, assigned, args...)
37+
end
38+
39+
@resumable function _querydelete_wait(sim, mb::MessageBuffer, args...)
40+
q = querydelete!(mb, args...)
41+
while isnothing(q)
42+
@yield wait(mb)
43+
q = querydelete!(mb, args...)
44+
end
45+
return q
46+
end
47+
function querydelete_wait!(store::MessageBuffer, args...)
48+
return @process _querydelete_wait(get_time_tracker(store), store, args...)
49+
end

test/test_querywait.jl

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
@testitem "Query Wait" tags=[:querywait] begin
2+
using Test
3+
using QuantumSavory
4+
using ResumableFunctions, ConcurrentSim
5+
6+
@testset "querydelete_wait!" begin
7+
@resumable function sender(sim, store, putf)
8+
putf(store, :something)
9+
@yield timeout(sim, 1.0)
10+
putf(store, :something)
11+
@yield timeout(sim, 1.0)
12+
putf(store, :something)
13+
@yield timeout(sim, 1.0)
14+
putf(store, :something)
15+
@yield timeout(sim, 1.0)
16+
putf(store, :something)
17+
end
18+
@resumable function receiver(sim, store, LOG)
19+
while true
20+
qw = querydelete_wait!(store, :something)
21+
res = @yield qw
22+
push!(LOG, res)
23+
end
24+
end
25+
26+
reg = Register(10)
27+
net = RegisterNet([reg])
28+
sim = get_time_tracker(net)
29+
store, putf = messagebuffer(reg), put!
30+
LOG = []
31+
@process receiver(sim, store, LOG)
32+
@process sender(sim, store, putf)
33+
@test length(LOG) == 0
34+
run(sim, 0.1)
35+
@test length(LOG) == 1
36+
run(sim, 1.1)
37+
@test length(LOG) == 2
38+
run(sim, 2.1)
39+
@test length(LOG) == 3
40+
run(sim, 3.1)
41+
@test length(LOG) == 4
42+
run(sim, 4.1)
43+
@test length(LOG) == 5
44+
run(sim, 5.1)
45+
@test length(LOG) == 5
46+
47+
reg = Register(10)
48+
net = RegisterNet([reg])
49+
sim = get_time_tracker(net)
50+
store, putf = reg, tag!
51+
LOG = []
52+
@process receiver(sim, store, LOG)
53+
@process sender(sim, store[1], putf)
54+
@test length(LOG) == 0
55+
run(sim, 0.1)
56+
@test length(LOG) == 1
57+
run(sim, 1.1)
58+
@test length(LOG) == 2
59+
run(sim, 2.1)
60+
@test length(LOG) == 3
61+
run(sim, 3.1)
62+
@test length(LOG) == 4
63+
run(sim, 4.1)
64+
@test length(LOG) == 5
65+
run(sim, 5.1)
66+
@test length(LOG) == 5
67+
end
68+
69+
@testset "query_wait" begin
70+
@resumable function sender(sim, store, putf)
71+
@yield timeout(sim, 1.0)
72+
putf(store, :something)
73+
end
74+
@resumable function receiver(sim, store, LOG)
75+
qw = query_wait(store, :something)
76+
res = @yield qw
77+
push!(LOG, res)
78+
end
79+
80+
reg = Register(10)
81+
net = RegisterNet([reg])
82+
sim = get_time_tracker(net)
83+
store, putf = messagebuffer(reg), put!
84+
LOG = []
85+
@process receiver(sim, store, LOG)
86+
@process sender(sim, store, putf)
87+
@test length(LOG) == 0
88+
run(sim, 0.1)
89+
@test length(LOG) == 0
90+
run(sim, 1.1)
91+
@test length(LOG) == 1
92+
run(sim, 2.1)
93+
@test length(LOG) == 1
94+
95+
reg = Register(10)
96+
net = RegisterNet([reg])
97+
sim = get_time_tracker(net)
98+
store, putf = reg, tag!
99+
LOG = []
100+
@process receiver(sim, store, LOG)
101+
@process sender(sim, store[1], putf)
102+
@test length(LOG) == 0
103+
run(sim, 0.1)
104+
@test length(LOG) == 0
105+
run(sim, 1.1)
106+
@test length(LOG) == 1
107+
run(sim, 2.1)
108+
@test length(LOG) == 1
109+
end

0 commit comments

Comments
 (0)