#![allow( clippy::large_enum_variant, clippy::type_complexity, clippy::too_many_arguments )] use criterion::{black_box, criterion_group, criterion_main, Criterion}; use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send, session::Session}; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use mpstthree::{ bundle_struct_fork_close_multi, choose_mpst_multi_to_all, create_multiple_normal_name, create_multiple_normal_role, create_recv_mpst_session_bundle, create_send_mpst_session_bundle, offer_mpst, }; use std::error::Error; // See the folder scribble_protocols for the related Scribble protocol // Create new roles // normal create_multiple_normal_role!( RoleC, RoleCDual | RoleS, RoleSDual | ); // Create new names create_multiple_normal_name!(NameC, NameS); // Create new send functions // C create_send_mpst_session_bundle!( send_mpst_c_to_s, RoleS, 1 | => NameC, MeshedChannels, 2 ); // S create_send_mpst_session_bundle!( send_mpst_s_to_c, RoleC, 1 | => NameS, MeshedChannels, 2 ); // Create new recv functions and related types // C create_recv_mpst_session_bundle!( recv_mpst_c_from_s, RoleS, 1 | => NameC, MeshedChannels, 2 ); // S create_recv_mpst_session_bundle!( recv_mpst_s_from_c, RoleC, 1 | => NameS, MeshedChannels, 2 ); // Create the new MeshedChannels for three participants and the close and fork functions bundle_struct_fork_close_multi!(close_mpst_multi, fork_mpst, MeshedChannels, 2); // Types // Step 0 // C type Choose0fromCtoS = Send; type EndpointC0 = MeshedChannels, RoleS, NameC>; // S enum Branching0fromCtoS { Continue(MeshedChannels, RoleC, NameS>), Quit(MeshedChannels, RoleC, NameS>), } type Offer0fromCtoS = ::Dual; type EndpointS0 = MeshedChannels, RoleC>, NameS>; // Step 1 // C enum Branching1fromStoC { Continue(MeshedChannels, RoleS, NameC>), Loop(MeshedChannels, RoleS>, NameC>), } type Offer1fromStoC = ::Dual; type EndpointC1 = MeshedChannels, NameC>; // S type Choose1fromStoC = Send; type EndpointS1 = MeshedChannels; // Step 2 // C type Choose2fromCtoS = Send; type EndpointC2 = MeshedChannels; // S enum Branching2fromCtoS { Continue( MeshedChannels>, RoleC>>, NameS>, ), Quit(MeshedChannels, RoleC, NameS>), } type Offer2fromCtoS = ::Dual; type EndpointS2 = MeshedChannels, NameS>; // Step 3 // C type Choose3fromCtoS = Send; type EndpointC3 = MeshedChannels; // S enum Branching3fromCtoS { Continue(MeshedChannels, RoleC, NameS>), Quit(MeshedChannels, RoleC, NameS>), } type Offer3fromCtoS = ::Dual; type EndpointS3 = MeshedChannels, NameS>; // Step 4 // C enum Branching4fromStoC { Continue(MeshedChannels, RoleS, NameC>), Loop(MeshedChannels, RoleS>, NameC>), } type Offer4fromStoC = ::Dual; type EndpointC4 = MeshedChannels, NameC>; // S type Choose4fromStoC = Send; type EndpointS4 = MeshedChannels; // Step 5 // C type Choose5fromCtoS = Send; type EndpointC5 = MeshedChannels; // S enum Branching5fromCtoS { Continue(MeshedChannels, RoleC, NameS>), Quit(MeshedChannels, RoleC, NameS>), } type Offer5fromCtoS = ::Dual; type EndpointS5 = MeshedChannels, NameS>; // Step 6 // C enum Branching6fromStoC { Continue(MeshedChannels, RoleS, NameC>), Loop(MeshedChannels, RoleS>, NameC>), } type Offer6fromStoC = ::Dual; type EndpointC6 = MeshedChannels, NameC>; // S type Choose6fromStoC = Send; type EndpointS6 = MeshedChannels; // Step 7 // C type Choose7fromCtoS = Send; type EndpointC7 = MeshedChannels; // S enum Branching7fromCtoS { Continue(MeshedChannels, RoleC, NameS>), Quit(MeshedChannels, RoleC, NameS>), } type Offer7fromCtoS = ::Dual; type EndpointS7 = MeshedChannels, NameS>; // Step 8 // C enum Branching8fromStoC { Continue(MeshedChannels, RoleS, NameC>), Loop(MeshedChannels, RoleS, NameC>), } type Offer8fromStoC = ::Dual; type EndpointC8 = MeshedChannels, NameC>; // S type Choose8fromStoC = Send; type EndpointS8 = MeshedChannels; // Step 9 // C type Choose9fromCtoS = Send; type EndpointC9 = MeshedChannels; // S enum Branching9fromCtoS { Continue( MeshedChannels< Recv<(), Send<(), Recv<(), Recv<(), Offer10fromCtoS>>>>, RoleC>>>>, NameS, >, ), Loop(MeshedChannels>, RoleC>>, NameS>), } type Offer9fromCtoS = ::Dual; type EndpointS9 = MeshedChannels, NameS>; // Step 10 // C type Choose10fromCtoS = Send; type EndpointC10 = MeshedChannels; // S enum Branching10fromCtoS { Data(MeshedChannels>, RoleC>>, NameS>), Subject( MeshedChannels>, RoleC>>, NameS>, ), End(MeshedChannels>, RoleC>>, NameS>), } type Offer10fromCtoS = ::Dual; type EndpointS10 = MeshedChannels, NameS>; // Functions fn endpoint_c_init(s: EndpointC0) -> Result<(), Box> { endpoint_c_0(s, 100) } fn endpoint_c_0(s: EndpointC0, loops: i32) -> Result<(), Box> { let (_, s) = recv_mpst_c_from_s(s)?; match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching0fromCtoS::Quit, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); close_mpst_multi(s) } _ => { let s = choose_mpst_multi_to_all!( s, Branching0fromCtoS::Continue, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); endpoint_c_1(s, loops) } } } fn endpoint_c_1(s: EndpointC1, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_c_from_s, { Branching1fromStoC::Continue(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_2(s, loops) }, Branching1fromStoC::Loop(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_1(s, loops) }, }) } fn endpoint_c_2(s: EndpointC2, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching2fromCtoS::Quit, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); close_mpst_multi(s) } _ => { let s = choose_mpst_multi_to_all!( s, Branching2fromCtoS::Continue, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_3(s, loops) } } } fn endpoint_c_3(s: EndpointC3, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching3fromCtoS::Quit, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); close_mpst_multi(s) } _ => { let s = choose_mpst_multi_to_all!( s, Branching3fromCtoS::Continue, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); endpoint_c_4(s, loops) } } } fn endpoint_c_4(s: EndpointC4, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_c_from_s, { Branching4fromStoC::Continue(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_5(s, loops) }, Branching4fromStoC::Loop(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_4(s, loops) }, }) } fn endpoint_c_5(s: EndpointC5, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching5fromCtoS::Quit, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); close_mpst_multi(s) } _ => { let s = choose_mpst_multi_to_all!( s, Branching5fromCtoS::Continue, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); endpoint_c_6(s, loops) } } } fn endpoint_c_6(s: EndpointC6, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_c_from_s, { Branching6fromStoC::Continue(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_7(s, loops) }, Branching6fromStoC::Loop(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_6(s, loops) }, }) } fn endpoint_c_7(s: EndpointC7, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching7fromCtoS::Quit, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); close_mpst_multi(s) } _ => { let s = choose_mpst_multi_to_all!( s, Branching7fromCtoS::Continue, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); endpoint_c_8(s, loops) } } } fn endpoint_c_8(s: EndpointC8, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_c_from_s, { Branching8fromStoC::Continue(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_9(s, loops) }, Branching8fromStoC::Loop(s) => { let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_7(s, loops) }, }) } fn endpoint_c_9(s: EndpointC9, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching9fromCtoS::Loop, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_9(s, loops) } _ => { let s = choose_mpst_multi_to_all!( s, Branching9fromCtoS::Continue, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); let (_, s) = recv_mpst_c_from_s(s)?; let s = send_mpst_c_to_s((), s); let s = send_mpst_c_to_s((), s); endpoint_c_10(s, loops) } } } fn endpoint_c_10(s: EndpointC10, loops: i32) -> Result<(), Box> { if loops == 0 { let s = choose_mpst_multi_to_all!( s, Branching10fromCtoS::End, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); let (_, s) = recv_mpst_c_from_s(s)?; endpoint_c_7(s, loops) } else if loops % 2 == 1 { let s = choose_mpst_multi_to_all!( s, Branching10fromCtoS::Subject, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); let s = send_mpst_c_to_s((), s); endpoint_c_10(s, loops - 1) } else { let s = choose_mpst_multi_to_all!( s, Branching10fromCtoS::Data, => NameC, MeshedChannels, 1 ); let s = send_mpst_c_to_s((), s); let s = send_mpst_c_to_s((), s); endpoint_c_10(s, loops - 1) } } /// fn endpoint_s_init(s: EndpointS0) -> Result<(), Box> { endpoint_s_0(s, 100) } fn endpoint_s_0(s: EndpointS0, loops: i32) -> Result<(), Box> { let s = send_mpst_s_to_c((), s); offer_mpst!(s, recv_mpst_s_from_c, { Branching0fromCtoS::Quit(s) => { let (_, s) = recv_mpst_s_from_c(s)?; close_mpst_multi(s) }, Branching0fromCtoS::Continue(s) => { let (_, s) = recv_mpst_s_from_c(s)?; endpoint_s_1(s, loops) }, }) } fn endpoint_s_1(s: EndpointS1, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching1fromStoC::Loop, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_1(s, loops) } _ => { let s = choose_mpst_multi_to_all!( s, Branching1fromStoC::Continue, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_2(s, loops) } } } fn endpoint_s_2(s: EndpointS2, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_s_from_c, { Branching2fromCtoS::Quit(s) => { let (_, s) = recv_mpst_s_from_c(s)?; close_mpst_multi(s) }, Branching2fromCtoS::Continue(s) => { let (_, s) = recv_mpst_s_from_c(s)?; let s = send_mpst_s_to_c((), s); endpoint_s_3(s, loops) }, }) } fn endpoint_s_3(s: EndpointS3, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_s_from_c, { Branching3fromCtoS::Quit(s) => { let (_, s) = recv_mpst_s_from_c(s)?; close_mpst_multi(s) }, Branching3fromCtoS::Continue(s) => { let (_, s) = recv_mpst_s_from_c(s)?; endpoint_s_4(s, loops) }, }) } fn endpoint_s_4(s: EndpointS4, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching4fromStoC::Loop, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_4(s, loops) } _ => { let s = choose_mpst_multi_to_all!( s, Branching4fromStoC::Continue, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_5(s, loops) } } } fn endpoint_s_5(s: EndpointS5, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_s_from_c, { Branching5fromCtoS::Quit(s) => { let (_, s) = recv_mpst_s_from_c(s)?; close_mpst_multi(s) }, Branching5fromCtoS::Continue(s) => { let (_, s) = recv_mpst_s_from_c(s)?; endpoint_s_6(s, loops) }, }) } fn endpoint_s_6(s: EndpointS6, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching6fromStoC::Loop, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_6(s, loops) } _ => { let s = choose_mpst_multi_to_all!( s, Branching6fromStoC::Continue, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_7(s, loops) } } } fn endpoint_s_7(s: EndpointS7, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_s_from_c, { Branching7fromCtoS::Quit(s) => { let (_, s) = recv_mpst_s_from_c(s)?; close_mpst_multi(s) }, Branching7fromCtoS::Continue(s) => { let (_, s) = recv_mpst_s_from_c(s)?; endpoint_s_8(s, loops) }, }) } fn endpoint_s_8(s: EndpointS8, loops: i32) -> Result<(), Box> { match loops { 0 => { let s = choose_mpst_multi_to_all!( s, Branching8fromStoC::Loop, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_7(s, loops) } _ => { let s = choose_mpst_multi_to_all!( s, Branching8fromStoC::Continue, => NameS, MeshedChannels, 2 ); let s = send_mpst_s_to_c((), s); endpoint_s_9(s, loops) } } } fn endpoint_s_9(s: EndpointS9, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_s_from_c, { Branching9fromCtoS::Loop(s) => { let (_, s) = recv_mpst_s_from_c(s)?; let s = send_mpst_s_to_c((), s); endpoint_s_9(s, loops) }, Branching9fromCtoS::Continue(s) => { let (_, s) = recv_mpst_s_from_c(s)?; let s = send_mpst_s_to_c((), s); let (_, s) = recv_mpst_s_from_c(s)?; let (_, s) = recv_mpst_s_from_c(s)?; endpoint_s_10(s, loops) }, }) } fn endpoint_s_10(s: EndpointS10, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_mpst_s_from_c, { Branching10fromCtoS::Data(s) => { let (_, s) = recv_mpst_s_from_c(s)?; let (_, s) = recv_mpst_s_from_c(s)?; endpoint_s_10(s, loops - 1) }, Branching10fromCtoS::Subject(s) => { let (_, s) = recv_mpst_s_from_c(s)?; let (_, s) = recv_mpst_s_from_c(s)?; endpoint_s_10(s, loops - 1) }, Branching10fromCtoS::End(s) => { let (_, s) = recv_mpst_s_from_c(s)?; let s = send_mpst_s_to_c((), s); endpoint_s_7(s, loops - 1) }, }) } ///////////////////////// fn aux() { let (thread_c, thread_s) = fork_mpst(black_box(endpoint_c_init), black_box(endpoint_s_init)); thread_c.join().unwrap(); thread_s.join().unwrap(); } ///////////////////////// pub fn smtp(c: &mut Criterion) { c.bench_function("SMTP basic", |b| b.iter(aux)); } ///////////////////////// criterion_group! { name = bench; config = Criterion::default().significance_level(0.05).without_plots().sample_size(100000); targets = smtp, } criterion_main! { bench }