diff --git a/examples/x86-fizz-buzz/.cargo/config.toml b/examples/x86-fizz-buzz/.cargo/config.toml new file mode 100644 index 00000000..3be3b8e3 --- /dev/null +++ b/examples/x86-fizz-buzz/.cargo/config.toml @@ -0,0 +1,6 @@ +[build] +target = "x86_64-unknown-linux-gnu" + +[env] +AERUGO_TASKLET_COUNT = { value = "5" } +AERUGO_EVENT_COUNT = { value = "3" } diff --git a/examples/x86-fizz-buzz/Cargo.toml b/examples/x86-fizz-buzz/Cargo.toml new file mode 100644 index 00000000..3dd27a8b --- /dev/null +++ b/examples/x86-fizz-buzz/Cargo.toml @@ -0,0 +1,8 @@ +[package] +authors = ["Filip Demski "] +edition = "2021" +name = "x86-fizz-buzz" +version = "0.1.0" + +[dependencies] +aerugo = { version = "0.1.0", path = "../..", features = ["use-aerugo-x86"] } diff --git a/examples/x86-fizz-buzz/src/main.rs b/examples/x86-fizz-buzz/src/main.rs new file mode 100644 index 00000000..4cc68c38 --- /dev/null +++ b/examples/x86-fizz-buzz/src/main.rs @@ -0,0 +1,241 @@ +use aerugo::{ + log, BooleanConditionHandle, BooleanConditionSet, BooleanConditionStorage, EventId, InitApi, + MessageQueueHandle, MessageQueueStorage, RuntimeApi, SystemHardwareConfig, TaskletConfig, + TaskletStorage, AERUGO, +}; + +struct ProducerContext { + acc: u8, + elem_queue_handle: MessageQueueHandle, + generate_numbers_condition_handle: BooleanConditionHandle, +} + +fn producer(_: (), context: &mut ProducerContext, _: &dyn RuntimeApi) { + context.acc = context.acc.wrapping_add(1); + + context + .elem_queue_handle + .send_data(context.acc) + .expect("Failed to send data to elem Queue"); + + if context.acc == u8::MAX { + context.generate_numbers_condition_handle.set_value(false); + } +} + +#[derive(Default)] +struct DistributorContext {} + +fn distributor(val: u8, _: &mut DistributorContext, api: &'static dyn RuntimeApi) { + match (val % 3, val % 5) { + (0, 0) => api + .emit_event(FizzBuzzEvents::FizzBuzz.into()) + .expect("Failed to emit FizzBuzz"), + (0, _) => api + .emit_event(FizzBuzzEvents::Fizz.into()) + .expect("Failed to emit Fizz"), + (_, 0) => api + .emit_event(FizzBuzzEvents::Buzz.into()) + .expect("Failed to emit Buzz"), + _ => log!("{}\n", val), + } +} + +#[derive(Default)] +struct FizzContext {} + +fn fizz(val: EventId, _: &mut FizzContext, _: &'static dyn RuntimeApi) { + log!("Fizz"); + + if let FizzBuzzEvents::Fizz = val.into() { + log!("\n"); + } +} + +#[derive(Default)] +struct BuzzContext {} + +fn buzz(_: EventId, _: &mut BuzzContext, _: &'static dyn RuntimeApi) { + log!("Buzz\n"); +} + +#[derive(Default)] +struct DoneContext {} + +fn done(_: bool, _: &mut DoneContext, _: &'static dyn RuntimeApi) { + log!("Done!\n"); + + std::process::exit(0); +} + +static PRODUCER_STORAGE: TaskletStorage<(), ProducerContext, 1> = TaskletStorage::new(); +static DISTRIBUTOR_STORAGE: TaskletStorage = TaskletStorage::new(); +static FIZZ_STORAGE: TaskletStorage = TaskletStorage::new(); +static BUZZ_STORAGE: TaskletStorage = TaskletStorage::new(); +static DONE_STORAGE: TaskletStorage = TaskletStorage::new(); + +static ELEM_QUEUE: MessageQueueStorage = MessageQueueStorage::new(); + +static GENERATE_NUMBERS_CONDITION_STORAGE: BooleanConditionStorage = BooleanConditionStorage::new(); + +enum FizzBuzzEvents { + Fizz, + Buzz, + FizzBuzz, +} + +impl From for EventId { + fn from(value: FizzBuzzEvents) -> Self { + match value { + FizzBuzzEvents::Fizz => 3, + FizzBuzzEvents::Buzz => 5, + FizzBuzzEvents::FizzBuzz => 15, + } + } +} + +impl From for FizzBuzzEvents { + fn from(value: EventId) -> Self { + match value { + 3 => FizzBuzzEvents::Fizz, + 5 => FizzBuzzEvents::Buzz, + 15 => FizzBuzzEvents::FizzBuzz, + _ => unreachable!(), + } + } +} + +fn main() -> ! { + AERUGO.initialize(SystemHardwareConfig::default()); + + AERUGO + .create_message_queue(&ELEM_QUEUE) + .expect("Unable to create ElemQueue"); + + AERUGO + .create_event(FizzBuzzEvents::Fizz.into()) + .expect("Unable to create Fizz event"); + AERUGO + .create_event(FizzBuzzEvents::Buzz.into()) + .expect("Unable to create Buzz event"); + AERUGO + .create_event(FizzBuzzEvents::FizzBuzz.into()) + .expect("Unable to create FizzBuzz event"); + + AERUGO + .create_boolean_condition(&GENERATE_NUMBERS_CONDITION_STORAGE, true) + .expect("Unable to create GenerateNumbersCondition"); + + let elem_queue_handle = ELEM_QUEUE + .create_handle() + .expect("Unable to create ElemQueue"); + + let generate_numbers_condition_handle = GENERATE_NUMBERS_CONDITION_STORAGE + .create_handle() + .expect("Unable to create GenerateNumbersCondition handle"); + + let producer_config = TaskletConfig { + name: "Producer", + ..Default::default() + }; + let producer_context = ProducerContext { + acc: 0, + elem_queue_handle, + generate_numbers_condition_handle, + }; + + AERUGO + .create_tasklet_with_context( + producer_config, + producer, + producer_context, + &PRODUCER_STORAGE, + ) + .expect("Unable to create Producer"); + + let distributor_config = TaskletConfig { + name: "Distributor", + ..Default::default() + }; + + AERUGO + .create_tasklet(distributor_config, distributor, &DISTRIBUTOR_STORAGE) + .expect("Unable to create Distributor"); + + let fizz_config = TaskletConfig { + name: "Fizz", + priority: 2, + }; + + AERUGO + .create_tasklet(fizz_config, fizz, &FIZZ_STORAGE) + .expect("Unable to create Fizz"); + + let buzz_config = TaskletConfig { + name: "Buzz", + priority: 1, + }; + + AERUGO + .create_tasklet(buzz_config, buzz, &BUZZ_STORAGE) + .expect("Unable to create Buzz"); + + let done_config = TaskletConfig { + name: "Done", + priority: 3, + }; + + AERUGO + .create_tasklet(done_config, done, &DONE_STORAGE) + .expect("Unable to create Done"); + + let producer_condition_set = BooleanConditionSet::from(generate_numbers_condition_handle); + + let producer_handle = PRODUCER_STORAGE + .create_handle() + .expect("Unable to create handle to Producer"); + AERUGO + .set_tasklet_conditions(&producer_handle, producer_condition_set) + .expect("Unable to set Producer condition set"); + AERUGO + .subscribe_tasklet_to_cyclic(&producer_handle, None) + .expect("Unable to set cyclic on Producer"); + + let distributor_handle = DISTRIBUTOR_STORAGE + .create_handle() + .expect("Unable to create handle to Distributor"); + AERUGO + .subscribe_tasklet_to_queue(&distributor_handle, &elem_queue_handle) + .expect("Unable to subscribe Distributor to ElemQueue"); + + let fizz_handle = FIZZ_STORAGE + .create_handle() + .expect("Unable to create handle to Fizz"); + AERUGO + .subscribe_tasklet_to_events(&fizz_handle) + .expect("Unable to subscribe Fizz to events") + .enable(FizzBuzzEvents::Fizz.into()) + .expect("Unable to enable Fizz event for Fizz") + .enable(FizzBuzzEvents::FizzBuzz.into()) + .expect("Unable to enable FizzBuzz event for Fizz"); + + let buzz_handle = BUZZ_STORAGE + .create_handle() + .expect("Unable to create handle to Buzz"); + AERUGO + .subscribe_tasklet_to_events(&buzz_handle) + .expect("Unable to subscribe Buzz to events") + .enable(FizzBuzzEvents::Buzz.into()) + .expect("Unable to enable Buzz event for Buzz") + .enable(FizzBuzzEvents::FizzBuzz.into()) + .expect("Unable to enable FizzBuzz event for Buzz"); + + let done_handle = DONE_STORAGE + .create_handle() + .expect("Unable to create handle to Done"); + AERUGO + .subscribe_tasklet_to_condition(&done_handle, &generate_numbers_condition_handle) + .expect("Unable to subscribe Done to GenerateNumbersCondition"); + + AERUGO.start(); +}