11/**
22 * Copyright (C) 2020 TU Dresden
3- *
3+ *
44 * This benchmark is very similar to the concurrent Dictionary benchmark.
55 * It only uses a sorted linked list instead of a dictionary.
6- *
6+ *
77 * @author Christian Menard
88 * @author Hannes Klein
99 * @author Johannes Hayeß
@@ -19,32 +19,32 @@ import BenchmarkRunner from "../lib/BenchmarkRunner.lf";
1919
2020reactor Manager(numWorkers: usize(20)) {
2121 state num_workers(numWorkers);
22-
22+
2323 state numWorkersTerminated: usize(0);
24-
24+
2525 input start: unit;
2626 output finished: unit;
27-
27+
2828 input[numWorkers] workersFinished: unit;
2929
3030 logical action finish: unit;
31-
31+
3232 reaction(finish) -> finished {=
3333 ctx.set(finished, ());
3434 =}
35-
35+
3636 reaction(workersFinished) -> finish {=
37- for (i, worker) in workersFinished.into_iter().enumerate () {
37+ for worker in workersFinished.into_iter() {
3838 if ctx.is_present(&worker) {
3939 self.numWorkersTerminated += 1;
40-
40+
4141 if self.numWorkersTerminated == self.num_workers {
4242 ctx.schedule(finish, Asap);
4343 }
4444 }
4545 }
4646 =}
47-
47+
4848 reaction(start) {=
4949 // reset local state
5050 self.numWorkersTerminated = 0;
@@ -61,57 +61,57 @@ reactor Worker(
6161 state num_messages_per_worker(numMessagesPerWorker);
6262 state write_percentage(writePercentage);
6363 state size_percentage(sizePercentage);
64-
64+
6565 state messageCount: usize(0);
6666 state random: PseudoRandomGenerator;
67-
67+
6868 input doWork: unit;
6969 output finished: unit;
70-
70+
7171 output request: Message;
7272 input response: i32;
73-
73+
7474 preamble {=
7575 use crate::pseudo_random::PseudoRandomGenerator;
7676 =}
77-
77+
7878 reaction(doWork, response) -> request, finished {=
7979 if ctx.is_present(doWork) {
8080 // reset local state
8181 self.messageCount = 0;
8282 self.random = PseudoRandomGenerator::from(
83- (self.bank_index +
83+ (self.bank_index +
8484 self.num_messages_per_worker +
8585 self.write_percentage +
86- self.size_percentage) as u64
86+ self.size_percentage) as i64
8787 );
8888 }
89-
89+
9090 if self.messageCount < self.num_messages_per_worker {
9191 self.messageCount += 1;
92- let num = self.random.gen_range (0..100) as usize ;
93-
92+ let num: usize = self.random.next_in_range (0..100).into() ;
93+
9494 if num < self.size_percentage {
9595 ctx.set(request, Message {mtype: AccessType::Size, value: -1});
9696 } else if num < (self.size_percentage + self.write_percentage) {
97- ctx.set(request, Message {mtype: AccessType::Write, value: self.random.next() as i32 });
97+ ctx.set(request, Message {mtype: AccessType::Write, value: self.random.next().into() });
9898 } else {
99- ctx.set(request, Message {mtype: AccessType::Contains, value: self.random.next() as i32 });
99+ ctx.set(request, Message {mtype: AccessType::Contains, value: self.random.next().into() });
100100 }
101101 } else {
102102 // signal that work is complete
103103 ctx.set(finished, ());
104104 }
105105 =}
106-
106+
107107 preamble {=
108108 #[derive(Copy, Clone)]
109109 pub enum AccessType {
110110 Write,
111111 Size,
112112 Contains,
113113 }
114-
114+
115115 #[derive(Copy, Clone)]
116116 pub struct Message {
117117 pub mtype: AccessType,
@@ -121,38 +121,38 @@ reactor Worker(
121121}
122122
123123reactor SortedListImpl(numWorkers: usize(20)) {
124-
124+
125125 state dataList: SortedLinkedList<isize>;
126126 state responsesToSend: Vec<i32>({= vec![-1; numWorkers] =}) ;
127-
127+
128128 input printResult: unit;
129129 input[numWorkers] requests: Message;
130130 output[numWorkers] responses: i32;
131-
131+
132132 logical action sendResponses: unit;
133-
133+
134134 preamble {=
135135 use crate::reactors::worker::{Message, AccessType};
136136 =}
137-
137+
138138 reaction(printResult) {=
139139 // check result
140140 println!("List Size = {}", self.dataList.len());
141-
141+
142142 // reset local state
143143 self.dataList.clear();
144144 =}
145-
145+
146146 reaction(sendResponses) -> responses {=
147147 for (i, response) in responses.into_iter().enumerate() {
148148 ctx.set(response, self.responsesToSend[i]);
149149 info!("Reply to worker {} with {}", i, self.responsesToSend[i]);
150150 }
151151 =}
152-
152+
153153 reaction(requests) -> sendResponses {=
154154 ctx.schedule(sendResponses, Asap);
155-
155+
156156 for (i, request) in requests.into_iter().enumerate() {
157157 let msg = ctx.get(&request).unwrap();
158158 match msg.mtype {
@@ -178,11 +178,11 @@ reactor SortedListImpl(numWorkers: usize(20)) {
178178 }
179179 }
180180 =}
181-
181+
182182 preamble {=
183183 use std::collections::LinkedList;
184184 use std::cmp::{PartialEq, PartialOrd};
185-
185+
186186 // Linked list sorted in ascending order.
187187 // We are using the standard library here for a linked list, instead of
188188 // directly porting the naive C++ implementation.
@@ -194,25 +194,25 @@ reactor SortedListImpl(numWorkers: usize(20)) {
194194 pub struct SortedLinkedList<T> {
195195 list: LinkedList<T>,
196196 }
197-
197+
198198 impl <T: PartialEq + PartialOrd + Copy> SortedLinkedList<T> {
199199 pub fn new() -> Self {
200200 SortedLinkedList::<T> {
201201 list: LinkedList::<T>::new(),
202202 }
203203 }
204-
204+
205205 pub fn is_empty(&self) -> bool {
206206 self.list.is_empty()
207207 }
208-
208+
209209 pub fn add(&mut self, item: &T) {
210210 if self.list.is_empty() {
211211 self.list.push_back(*item);
212212 } else if item < self.list.front().unwrap() {
213- self.list.push_front(*item);
213+ self.list.push_front(*item);
214214 } else if self.list.back().unwrap() < item {
215- self.list.push_back(*item);
215+ self.list.push_back(*item);
216216 } else {
217217 for (i, ele) in self.list.iter().enumerate() {
218218 if item < ele {
@@ -226,27 +226,27 @@ reactor SortedListImpl(numWorkers: usize(20)) {
226226 }
227227 }
228228 }
229-
229+
230230 pub fn contains(&self, item: &T) -> bool {
231231 self.list.contains(item)
232232 }
233-
233+
234234 pub fn len(&self) -> usize {
235- self.list.len()
235+ self.list.len()
236236 }
237-
237+
238238 pub fn clear(&mut self) {
239239 self.list.clear();
240240 }
241241 }
242-
242+
243243 impl <T: Default + PartialEq + PartialOrd + Copy> Default for SortedLinkedList<T> {
244244 fn default() -> Self {
245245 SortedLinkedList::<T>::new()
246246 }
247247 }
248248 =}
249-
249+
250250}
251251
252252main reactor (numIterations: usize(12), numMessagesPerWorker: usize(8000), writePercentage: usize(10), sizePercentage:usize(1), numWorkers: usize(20)) {
@@ -255,13 +255,13 @@ main reactor (numIterations: usize(12), numMessagesPerWorker: usize(8000), write
255255 state write_percentage(writePercentage);
256256 state size_percentage(sizePercentage);
257257 state num_workers(numWorkers);
258-
258+
259259 manager = new Manager(numWorkers=numWorkers);
260260 workers = new[numWorkers] Worker(numMessagesPerWorker=numMessagesPerWorker, writePercentage=writePercentage, sizePercentage=sizePercentage);
261261 sortedList = new SortedListImpl(numWorkers=numWorkers);
262-
262+
263263 runner = new BenchmarkRunner(num_iterations=numIterations);
264-
264+
265265 reaction(startup) {=
266266 print_benchmark_info("SortedListBenchmark");
267267 print_args!(
@@ -278,17 +278,16 @@ main reactor (numIterations: usize(12), numMessagesPerWorker: usize(8000), write
278278 );
279279 print_system_info();
280280 =}
281-
281+
282282 (runner.start)+ -> manager.start, workers.doWork;
283283 manager.finished -> runner.finished;
284284 manager.finished -> sortedList.printResult;
285-
285+
286286 workers.request -> sortedList.requests;
287287 sortedList.responses -> workers.response;
288288 workers.finished -> manager.workersFinished;
289-
289+
290290 preamble {=
291291 use crate::{print_args,reactors::benchmark_runner::{print_system_info, print_benchmark_info}};
292- =}
292+ =}
293293}
294-
0 commit comments