dvcompute_gpss_dist/simulation/block/
basic.rs1use dvcompute_dist::simulation::event::*;
8use dvcompute_dist::simulation::process::*;
9
10use dvcompute_utils::grc::Grc;
11
12use crate::simulation::block::*;
13use crate::simulation::queue::*;
14use crate::simulation::facility::*;
15use crate::simulation::transact::*;
16
17#[inline]
19pub fn advance_block<M, T>(comp: M) -> impl Block<Input = T, Output = T> + Clone
20 where M: Process<Item = ()> + Clone + 'static,
21 T: Clone + 'static
22{
23 cons_block(move |x| {
24 comp.map(move |()| x)
25 })
26}
27
28#[inline]
30pub fn queue_block<T>(queue: Grc<Queue>, increment: isize) -> impl Block<Input = Transact<T>, Output = Transact<T>> + Clone
31 where T: Clone + 'static
32{
33 cons_block(move |x: Transact<T>| {
34 Queue::enqueue(queue, x.transact_id.clone(), increment)
35 .map(move |()| x)
36 .into_process()
37 })
38}
39
40#[inline]
42pub fn depart_block<T>(queue: Grc<Queue>, decrement: isize) -> impl Block<Input = Transact<T>, Output = Transact<T>> + Clone
43 where T: Clone + 'static
44{
45 cons_block(move |x: Transact<T>| {
46 Queue::dequeue(queue, x.transact_id.clone(), decrement)
47 .map(move |()| x)
48 .into_process()
49 })
50}
51
52#[inline]
54pub fn seize_block<T>(facility: Grc<Facility<T>>) -> impl Block<Input = Transact<T>, Output = Transact<T>> + Clone
55 where T: Clone + 'static
56{
57 cons_block(move |x: Transact<T>| {
58 seize_facility(facility, x.clone())
59 .map(move |()| x)
60 .into_process()
61 })
62}
63
64#[inline]
66pub fn release_block<T>(facility: Grc<Facility<T>>) -> impl Block<Input = Transact<T>, Output = Transact<T>> + Clone
67 where T: Clone + 'static
68{
69 cons_block(move |x: Transact<T>| {
70 release_facility(facility, x.transact_id.clone())
71 .map(move |()| x)
72 .into_process()
73 })
74}
75
76#[inline]
78pub fn return_block<T>(facility: Grc<Facility<T>>) -> impl Block<Input = Transact<T>, Output = Transact<T>> + Clone
79 where T: Clone + 'static
80{
81 cons_block(move |x: Transact<T>| {
82 return_facility(facility, x.transact_id.clone())
83 .map(move |()| x)
84 .into_process()
85 })
86}
87
88#[inline]
90pub fn preempt_block<T>(facility: Grc<Facility<T>>, mode: PreemptBlockMode<T>) -> impl Block<Input = Transact<T>, Output = Transact<T>> + Clone
91 where T: Clone + 'static
92{
93 cons_block(move |x: Transact<T>| {
94 preempt_facility(facility, x.clone(), mode.into())
95 .map(move |()| x)
96 .into_process()
97 })
98}
99
100#[derive(Clone)]
102pub struct PreemptBlockMode<T> {
103
104 pub priority_mode: bool,
106
107 pub transfer: Option<PreemptBlockTransfer<T>>,
111
112 pub remove_mode: bool
114}
115
116impl<T> From<FacilityPreemptMode<T>> for PreemptBlockMode<T>
117 where T: Clone + 'static
118{
119 fn from(mode: FacilityPreemptMode<T>) -> Self {
120 let FacilityPreemptMode { priority_mode, transfer, remove_mode } = mode;
121 let transfer = match transfer {
122 None => None,
123 Some(f) => Some({
124 PreemptBlockTransfer::new(move |dt| {
125 cons_block(move |transact| {
126 f.call_box((transact, dt))
127 }).into_boxed()
128 })
129 })
130 };
131
132 PreemptBlockMode {
133 priority_mode: priority_mode,
134 transfer: transfer,
135 remove_mode: remove_mode
136 }
137 }
138}
139
140pub struct PreemptBlockTransfer<T> {
143 f: Box<dyn PreemptBlockTransferFnBoxClone<T>>
144}
145
146impl<T> PreemptBlockTransfer<T> {
147
148 #[inline]
150 pub fn new<F>(f: F) -> Self
151 where F: FnOnce(Option<f64>) -> BlockBox<Transact<T>, ()> + Clone + 'static,
152 T: 'static
153 {
154 PreemptBlockTransfer {
155 f: Box::new(f)
156 }
157 }
158
159 #[inline]
161 pub fn call_box(self, arg: Option<f64>) -> BlockBox<Transact<T>, ()> {
162 let PreemptBlockTransfer { f } = self;
163 f.call_box(arg)
164 }
165}
166
167impl<T> Clone for PreemptBlockTransfer<T> {
168
169 #[inline]
170 fn clone(&self) -> Self {
171 PreemptBlockTransfer {
172 f: self.f.call_clone()
173 }
174 }
175}
176
177trait PreemptBlockTransferFnBox<T> {
179
180 fn call_box(self: Box<Self>, args: Option<f64>) -> BlockBox<Transact<T>, ()>;
182}
183
184impl<T, F> PreemptBlockTransferFnBox<T> for F
185 where F: FnOnce(Option<f64>) -> BlockBox<Transact<T>, ()>,
186 T: 'static
187{
188 fn call_box(self: Box<Self>, args: Option<f64>) -> BlockBox<Transact<T>, ()> {
189 let this: Self = *self;
190 this(args)
191 }
192}
193
194trait PreemptBlockTransferFnBoxClone<T>: PreemptBlockTransferFnBox<T> {
196
197 fn call_clone(&self) -> Box<dyn PreemptBlockTransferFnBoxClone<T>>;
199}
200
201impl<T, F> PreemptBlockTransferFnBoxClone<T> for F
202 where F: FnOnce(Option<f64>) -> BlockBox<Transact<T>, ()> + Clone + 'static,
203 T: 'static
204{
205 fn call_clone(&self) -> Box<dyn PreemptBlockTransferFnBoxClone<T>> {
206 Box::new(self.clone())
207 }
208}