1mod generator {
2 pub struct GeneratorState {
3 sigma: f64,
4 period: f64,
5 count: usize,
6 }
7
8 impl GeneratorState {
9 pub fn new(period: f64) -> Self {
10 Self {
11 sigma: 0.0,
12 period,
13 count: 0,
14 }
15 }
16 }
17
18 xdevs::component!(
19 ident = Generator,
20 input = {
21 in_stop<bool>,
22 },
23 output = {
24 out_job<usize>,
25 },
26 state = GeneratorState,
27 );
28
29 impl xdevs::Atomic for Generator {
30 fn delta_int(state: &mut Self::State) {
31 state.count += 1;
32 state.sigma = state.period;
33 }
34
35 fn lambda(state: &Self::State, output: &mut Self::Output) {
36 println!("[G] sending job {}", state.count);
37 output.out_job.add_value(state.count).unwrap();
38 }
39
40 fn ta(state: &Self::State) -> f64 {
41 state.sigma
42 }
43
44 fn delta_ext(state: &mut Self::State, e: f64, x: &Self::Input) {
45 state.sigma -= e;
46 if let Some(&stop) = x.in_stop.get_values().last() {
47 println!("[G] received stop: {}", stop);
48 if stop {
49 state.sigma = f64::INFINITY;
50 }
51 }
52 }
53 }
54}
55
56mod processor {
57 pub struct ProcessorState {
58 sigma: f64,
59 time: f64,
60 job: Option<usize>,
61 }
62
63 impl ProcessorState {
64 pub fn new(time: f64) -> Self {
65 Self {
66 sigma: 0.0,
67 time,
68 job: None,
69 }
70 }
71 }
72
73 xdevs::component!(
74 ident = Processor,
75 input = {
76 in_job<usize, 1>
77 },
78 output = {
79 out_job<usize>
80 },
81 state = ProcessorState,
82 );
83
84 impl xdevs::Atomic for Processor {
85 fn delta_int(state: &mut Self::State) {
86 state.sigma = f64::INFINITY;
87 if let Some(job) = state.job {
88 println!("[P] processed job {}", job);
89 state.job = None;
90 }
91 }
92
93 fn lambda(state: &Self::State, output: &mut Self::Output) {
94 if let Some(job) = state.job {
95 output.out_job.add_value(job).unwrap();
96 }
97 }
98
99 fn ta(state: &Self::State) -> f64 {
100 state.sigma
101 }
102
103 fn delta_ext(state: &mut Self::State, e: f64, x: &Self::Input) {
104 state.sigma -= e;
105 if let Some(&job) = x.in_job.get_values().last() {
106 print!("[P] received job {}", job);
107 if state.job.is_none() {
108 println!(" (idle)");
109 state.job = Some(job);
110 state.sigma = state.time;
111 } else {
112 println!(" (busy)");
113 }
114 }
115 }
116 }
117}
118
119mod transducer {
120 pub struct TransducerState {
121 sigma: f64,
122 clock: f64,
123 n_generated: usize,
124 n_processed: usize,
125 }
126
127 impl TransducerState {
128 pub fn new(obs_time: f64) -> Self {
129 Self {
130 sigma: obs_time,
131 clock: 0.0,
132 n_generated: 0,
133 n_processed: 0,
134 }
135 }
136 }
137
138 xdevs::component!(
139 ident = Transducer,
140 input = {
141 in_generator<usize, 1>,
142 in_processor<usize, 1>,
143 },
144 output = {
145 out_stop<bool>
146 },
147 state = TransducerState,
148 );
149
150 impl xdevs::Atomic for Transducer {
151 fn delta_int(state: &mut Self::State) {
152 state.clock += state.sigma;
153 let (acceptance, throughput) = if state.n_processed > 0 {
154 (
155 state.n_processed as f64 / state.n_generated as f64,
156 state.n_processed as f64 / state.clock,
157 )
158 } else {
159 (0.0, 0.0)
160 };
161 println!(
162 "[T] acceptance: {:.2}, throughput: {:.2}",
163 acceptance, throughput
164 );
165 state.sigma = f64::INFINITY;
166 }
167
168 fn lambda(_state: &Self::State, output: &mut Self::Output) {
169 output.out_stop.add_value(true).unwrap();
170 }
171
172 fn ta(state: &Self::State) -> f64 {
173 state.sigma
174 }
175
176 fn delta_ext(state: &mut Self::State, e: f64, x: &Self::Input) {
177 state.sigma -= e;
178 state.clock += e;
179 state.n_generated += x.in_generator.get_values().len();
180 state.n_processed += x.in_processor.get_values().len();
181 }
182 }
183}
184
185xdevs::component!(
186 ident = GPT,
187 components = {
188 generator: generator::Generator,
189 processor: processor::Processor,
190 transducer: transducer::Transducer,
191 },
192 couplings = {
193 generator.out_job -> processor.in_job,
194 processor.out_job -> transducer.in_processor,
195 generator.out_job -> transducer.in_generator,
196 transducer.out_stop -> generator.in_stop,
197 }
198);
199
200xdevs::component!(
201 ident = EF,
202 input = {
203 in_processor<usize, 1>,
204 },
205 output = {
206 out_generator<usize, 1>,
207 },
208 components = {
209 generator: generator::Generator,
210 transducer: transducer::Transducer,
211 },
212 couplings = {
213 in_processor -> transducer.in_processor,
214 generator.out_job -> transducer.in_generator,
215 transducer.out_stop -> generator.in_stop,
216 generator.out_job -> out_generator,
217 }
218);
219
220xdevs::component!(
221 ident = EFP,
222 components = {
223 ef: EF,
224 processor: processor::Processor,
225 },
226 couplings = {
227 ef.out_generator -> processor.in_job,
228 processor.out_job -> ef.in_processor,
229 }
230);
231
232fn main() {
233 let period = 1.;
234 let proc_time = 1.1;
235 let obs_time = 10.;
236
237 let generator = generator::Generator::new(generator::GeneratorState::new(period));
238 let processor = processor::Processor::new(processor::ProcessorState::new(proc_time));
239 let transducer = transducer::Transducer::new(transducer::TransducerState::new(obs_time));
240
241 let ef = EF::new(generator, transducer);
242 let efp = EFP::new(ef, processor);
243
244 let mut simulator = xdevs::simulator::Simulator::new(efp);
245 simulator.simulate_rt(
246 0.0,
247 14.0,
248 xdevs::simulator::std::sleep(0.0, 1.0, None),
249 |_| {},
250 );
251}