#![allow( clippy::type_complexity, clippy::too_many_arguments, clippy::large_enum_variant )] use criterion::{black_box, criterion_group, criterion_main, Criterion}; use mpstthree::binary::struct_trait::session::Session; use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::generate; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use std::error::Error; // Create the new MeshedChannels for three participants and the close and fork functions generate!( "rec_and_cancel", MeshedChannels, Calculator1, Calculator2, Server ); // Labels struct Data1 {} struct Data2 {} struct ProcesData2 {} struct ProcesData3 {} struct Complete {} struct Stop {} // Types // Calculator1 type OfferFromServertoCalculator1 = Recv; type Calculator1toCalculator2Data = Recv>; type Calculator1toServerData = Recv>; type Calculator1toCalculator2Stop = End; type Calculator1toServerStop = Recv; enum BranchingFromServertoCalculator1 { Data( MeshedChannels< Calculator1toCalculator2Data, Calculator1toServerData, RoleServer>>>>, NameCalculator1, >, ), Stop( MeshedChannels< Calculator1toCalculator2Stop, Calculator1toServerStop, RoleServer, NameCalculator1, >, ), } // Calculator2 type OfferFromServertoCalculator2 = Recv; type Calculator2toCalculator1Data = Send>; type Calculator2toServerData = Recv>; type Calculator2toCalculator1Stop = End; type Calculator2toServerStop = Recv; enum BranchingFromServertoCalculator2 { Data( MeshedChannels< Calculator2toCalculator1Data, Calculator2toServerData, RoleServer>>>>, NameCalculator2, >, ), Stop( MeshedChannels< Calculator2toCalculator1Stop, Calculator2toServerStop, RoleServer, NameCalculator2, >, ), } // Server type ChooseFromServertoCalculator1 = ::Dual; type ChooseFromServertoCalculator2 = ::Dual; type ServertoCalculator1Data = ::Dual; type ServertoCalculator2Data = ::Dual; type ServertoCalculator1Stop = ::Dual; type ServertoCalculator2Stop = ::Dual; // Endpoints // Calculator1 type Endpoint0Calculator1 = MeshedChannels, NameCalculator1>; // Calculator2 type Endpoint0Calculator2 = MeshedChannels, NameCalculator2>; // Server type Endpoint0Server = MeshedChannels< ChooseFromServertoCalculator1, ChooseFromServertoCalculator2, RoleBroadcast, NameServer, >; type Endpoint1ServerData = MeshedChannels< ServertoCalculator1Data, ServertoCalculator2Data, RoleCalculator1>>>, NameServer, >; type Endpoint1ServerStop = MeshedChannels< ServertoCalculator1Stop, ServertoCalculator2Stop, RoleCalculator1>, NameServer, >; // Functions ///////////////////////// // Calculator1 fn endpoint_calculator_1(s: Endpoint0Calculator1) -> Result<(), Box> { recurs_calculator_1(s) } fn recurs_calculator_1(s: Endpoint0Calculator1) -> Result<(), Box> { offer_mpst!(s, { BranchingFromServertoCalculator1::Stop(s) => { let (_stop, s) = s.recv()?; s.close() }, BranchingFromServertoCalculator1::Data(s) => { let (_data_1, s) = s.recv()?; let (_processed_data_2, s) = s.recv()?; let s = s.send(ProcesData3 {})?; let s = s.send(Complete {})?; recurs_calculator_1(s) }, }) } ///////////////////////// // Calculator2 fn endpoint_calculator_2(s: Endpoint0Calculator2) -> Result<(), Box> { recurs_calculator_2(s) } fn recurs_calculator_2(s: Endpoint0Calculator2) -> Result<(), Box> { offer_mpst!(s, { BranchingFromServertoCalculator2::Stop(s) => { let (_stop, s) = s.recv()?; s.close() }, BranchingFromServertoCalculator2::Data(s) => { let (_data_2, s) = s.recv()?; let s = s.send(ProcesData2 {})?; let (_complete, s) = s.recv()?; let (_complete, s) = s.recv()?; recurs_calculator_2(s) }, }) } ///////////////////////// // Server fn endpoint_server(s: Endpoint0Server) -> Result<(), Box> { recurs_server(s, LOOPS) } fn recurs_server(s: Endpoint0Server, loops: i64) -> Result<(), Box> { match loops { 0 => { let s: Endpoint1ServerStop = choose_mpst_server_to_all!( s, BranchingFromServertoCalculator1::Stop, BranchingFromServertoCalculator2::Stop, ); let s = s.send(Stop {})?; let s = s.send(Stop {})?; s.close() } i => { let s: Endpoint1ServerData = choose_mpst_server_to_all!( s, BranchingFromServertoCalculator1::Data, BranchingFromServertoCalculator2::Data, ); let s = s.send(Data1 {})?; let s = s.send(Data2 {})?; let (_data, s) = s.recv()?; let s = s.send(Complete {})?; recurs_server(s, i - 1) } } } ///////////////////////// fn aux() { let (thread_calculator_1, thread_calculator_2, thread_server) = fork_mpst( black_box(endpoint_calculator_1), black_box(endpoint_calculator_2), black_box(endpoint_server), ); thread_calculator_1.join().unwrap(); thread_calculator_2.join().unwrap(); thread_server.join().unwrap(); } ///////////////////////// static LOOPS: i64 = 100; pub fn distributed_calculators(c: &mut Criterion) { c.bench_function("Distributed calculators AMPST", |b| b.iter(aux)); } ///////////////////////// criterion_group! { name = bench; config = Criterion::default().significance_level(0.05).without_plots().sample_size(100000); targets = distributed_calculators, } criterion_main! { bench }