Skip to content

Commit

Permalink
samples: philosophers: Add dynamic semaphore example
Browse files Browse the repository at this point in the history
Add a sample that implements the forks using dynamically allocate
semaphores.

Signed-off-by: David Brown <[email protected]>
  • Loading branch information
d3zd3z committed Oct 24, 2024
1 parent d8dc4fe commit 8be9b79
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 2 deletions.
10 changes: 8 additions & 2 deletions samples/philosophers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ source "Kconfig.zephyr"

choice
prompt "Select Synchronization implementation"
default SYNC_CHANNEL
default SYNC_SYS_DYNAMIC_SEMAPHORE

config SYNC_SYS_SEMAPHORE
bool "Use sys::Semaphore to synchronize forks"
help
Use to have the dining philosophers sample use sys::Mutex, with one per fork, to
Use to have the dining philosophers sample use sys::Semaphore, with one per fork, to
synchronize.

config SYNC_SYS_DYNAMIC_SEMAPHORE
bool "Use a dynamic sys::Semaphore to synchronize forks"
help
Use to have the dining philosophers sample use sys::Semaphore, with one per fork, to
synchronize. The Semaphores will be dynamically allocated.

config SYNC_SYS_MUTEX
bool "Use sys::Semaphore to synchronize forks"
help
Expand Down
5 changes: 5 additions & 0 deletions samples/philosophers/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ tests:
min_ram: 32
extra_configs:
- CONFIG_SYNC_SYS_SEMAPHORE=y
sample.rust.philosopher.dynsemaphore:
tags: introduction
min_ram: 32
extra_configs:
- CONFIG_SYNC_SYS_DYNAMIC_SEMAPHORE=y
sample.rust.philosopher.sysmutex:
tags: introduction
min_ram: 32
Expand Down
51 changes: 51 additions & 0 deletions samples/philosophers/src/dynsemsync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2023 Linaro LTD
// SPDX-License-Identifier: Apache-2.0

//! Semaphore based sync.
//!
//! This is the simplest type of sync, which uses a single semaphore per fork.
extern crate alloc;

use alloc::vec::Vec;
use alloc::boxed::Box;

use zephyr::{
sync::Arc, sys::sync::Semaphore, time::Forever
};

use crate::{ForkSync, NUM_PHIL};

#[derive(Debug)]
pub struct SemSync {
/// The forks for this philosopher. This is a big excessive, as we really don't need all of
/// them, but the ForSync code uses the index here.
forks: [Arc<Semaphore>; NUM_PHIL],
}

impl ForkSync for SemSync {
fn take(&self, index: usize) {
self.forks[index].take(Forever).unwrap();
}

fn release(&self, index: usize) {
self.forks[index].give();
}
}

#[allow(dead_code)]
pub fn dyn_semaphore_sync() -> Vec<Arc<dyn ForkSync>> {
let forks = [(); NUM_PHIL].each_ref().map(|()| {
Arc::new(Semaphore::new(1, 1).unwrap())
});

let syncers = (0..NUM_PHIL).map(|_| {
let syncer = SemSync {
forks: forks.clone(),
};
let item = Box::new(syncer) as Box<dyn ForkSync>;
Arc::from(item)
}).collect();

syncers
}
8 changes: 8 additions & 0 deletions samples/philosophers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ use crate::sysmutex::SysMutexSync;
use crate::channel::get_channel_syncer;
#[allow(unused_imports)]
use crate::semsync::semaphore_sync;
#[allow(unused_imports)]
use crate::dynsemsync::dyn_semaphore_sync;

mod channel;
mod condsync;
mod dynsemsync;
mod sysmutex;
mod semsync;

Expand Down Expand Up @@ -95,6 +98,11 @@ fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
semaphore_sync()
}

#[cfg(CONFIG_SYNC_SYS_DYNAMIC_SEMAPHORE)]
fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
dyn_semaphore_sync()
}

#[cfg(CONFIG_SYNC_SYS_MUTEX)]
fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
let syncer = Box::new(SysMutexSync::new())
Expand Down

0 comments on commit 8be9b79

Please sign in to comment.