Skip to content

Commit 8be9b79

Browse files
committed
samples: philosophers: Add dynamic semaphore example
Add a sample that implements the forks using dynamically allocate semaphores. Signed-off-by: David Brown <[email protected]>
1 parent d8dc4fe commit 8be9b79

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

samples/philosophers/Kconfig

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@ source "Kconfig.zephyr"
77

88
choice
99
prompt "Select Synchronization implementation"
10-
default SYNC_CHANNEL
10+
default SYNC_SYS_DYNAMIC_SEMAPHORE
1111

1212
config SYNC_SYS_SEMAPHORE
1313
bool "Use sys::Semaphore to synchronize forks"
1414
help
15-
Use to have the dining philosophers sample use sys::Mutex, with one per fork, to
15+
Use to have the dining philosophers sample use sys::Semaphore, with one per fork, to
1616
synchronize.
1717

18+
config SYNC_SYS_DYNAMIC_SEMAPHORE
19+
bool "Use a dynamic sys::Semaphore to synchronize forks"
20+
help
21+
Use to have the dining philosophers sample use sys::Semaphore, with one per fork, to
22+
synchronize. The Semaphores will be dynamically allocated.
23+
1824
config SYNC_SYS_MUTEX
1925
bool "Use sys::Semaphore to synchronize forks"
2026
help

samples/philosophers/sample.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ tests:
1717
min_ram: 32
1818
extra_configs:
1919
- CONFIG_SYNC_SYS_SEMAPHORE=y
20+
sample.rust.philosopher.dynsemaphore:
21+
tags: introduction
22+
min_ram: 32
23+
extra_configs:
24+
- CONFIG_SYNC_SYS_DYNAMIC_SEMAPHORE=y
2025
sample.rust.philosopher.sysmutex:
2126
tags: introduction
2227
min_ram: 32
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) 2023 Linaro LTD
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Semaphore based sync.
5+
//!
6+
//! This is the simplest type of sync, which uses a single semaphore per fork.
7+
8+
extern crate alloc;
9+
10+
use alloc::vec::Vec;
11+
use alloc::boxed::Box;
12+
13+
use zephyr::{
14+
sync::Arc, sys::sync::Semaphore, time::Forever
15+
};
16+
17+
use crate::{ForkSync, NUM_PHIL};
18+
19+
#[derive(Debug)]
20+
pub struct SemSync {
21+
/// The forks for this philosopher. This is a big excessive, as we really don't need all of
22+
/// them, but the ForSync code uses the index here.
23+
forks: [Arc<Semaphore>; NUM_PHIL],
24+
}
25+
26+
impl ForkSync for SemSync {
27+
fn take(&self, index: usize) {
28+
self.forks[index].take(Forever).unwrap();
29+
}
30+
31+
fn release(&self, index: usize) {
32+
self.forks[index].give();
33+
}
34+
}
35+
36+
#[allow(dead_code)]
37+
pub fn dyn_semaphore_sync() -> Vec<Arc<dyn ForkSync>> {
38+
let forks = [(); NUM_PHIL].each_ref().map(|()| {
39+
Arc::new(Semaphore::new(1, 1).unwrap())
40+
});
41+
42+
let syncers = (0..NUM_PHIL).map(|_| {
43+
let syncer = SemSync {
44+
forks: forks.clone(),
45+
};
46+
let item = Box::new(syncer) as Box<dyn ForkSync>;
47+
Arc::from(item)
48+
}).collect();
49+
50+
syncers
51+
}

samples/philosophers/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ use crate::sysmutex::SysMutexSync;
3030
use crate::channel::get_channel_syncer;
3131
#[allow(unused_imports)]
3232
use crate::semsync::semaphore_sync;
33+
#[allow(unused_imports)]
34+
use crate::dynsemsync::dyn_semaphore_sync;
3335

3436
mod channel;
3537
mod condsync;
38+
mod dynsemsync;
3639
mod sysmutex;
3740
mod semsync;
3841

@@ -95,6 +98,11 @@ fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
9598
semaphore_sync()
9699
}
97100

101+
#[cfg(CONFIG_SYNC_SYS_DYNAMIC_SEMAPHORE)]
102+
fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
103+
dyn_semaphore_sync()
104+
}
105+
98106
#[cfg(CONFIG_SYNC_SYS_MUTEX)]
99107
fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
100108
let syncer = Box::new(SysMutexSync::new())

0 commit comments

Comments
 (0)