Skip to content

Commit

Permalink
Merge pull request #35 from Glamhoth/ros-136/x86-fizz-buzz-example
Browse files Browse the repository at this point in the history
ROS#136 - Created FizzBuzz example for x86
  • Loading branch information
Glamhoth authored Aug 21, 2023
2 parents d13902d + 3d6a787 commit cabd397
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 0 deletions.
6 changes: 6 additions & 0 deletions examples/x86-fizz-buzz/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[build]
target = "x86_64-unknown-linux-gnu"

[env]
AERUGO_TASKLET_COUNT = { value = "5" }
AERUGO_EVENT_COUNT = { value = "3" }
8 changes: 8 additions & 0 deletions examples/x86-fizz-buzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
authors = ["Filip Demski <glamhoth@protonmail.com>"]
edition = "2021"
name = "x86-fizz-buzz"
version = "0.1.0"

[dependencies]
aerugo = { version = "0.1.0", path = "../..", features = ["use-aerugo-x86"] }
241 changes: 241 additions & 0 deletions examples/x86-fizz-buzz/src/main.rs
Original file line number Diff line number Diff line change
@@ -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<u8, 10>,
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<u8, DistributorContext, 0> = TaskletStorage::new();
static FIZZ_STORAGE: TaskletStorage<EventId, FizzContext, 0> = TaskletStorage::new();
static BUZZ_STORAGE: TaskletStorage<EventId, BuzzContext, 0> = TaskletStorage::new();
static DONE_STORAGE: TaskletStorage<bool, DoneContext, 0> = TaskletStorage::new();

static ELEM_QUEUE: MessageQueueStorage<u8, 10> = MessageQueueStorage::new();

static GENERATE_NUMBERS_CONDITION_STORAGE: BooleanConditionStorage = BooleanConditionStorage::new();

enum FizzBuzzEvents {
Fizz,
Buzz,
FizzBuzz,
}

impl From<FizzBuzzEvents> for EventId {
fn from(value: FizzBuzzEvents) -> Self {
match value {
FizzBuzzEvents::Fizz => 3,
FizzBuzzEvents::Buzz => 5,
FizzBuzzEvents::FizzBuzz => 15,
}
}
}

impl From<EventId> 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();
}

0 comments on commit cabd397

Please sign in to comment.