Skip to content

Commit 29fdf80

Browse files
committed
samples: philosophers: Add sysmutex version
Add a version of the philosopher's demo that is built around sys::Mutex, in it's simplest use case. Signed-off-by: David Brown <[email protected]>
1 parent fd13559 commit 29fdf80

File tree

4 files changed

+80
-3
lines changed

4 files changed

+80
-3
lines changed

samples/philosophers/Kconfig

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ source "Kconfig.zephyr"
77

88
choice
99
prompt "Select Synchronization implementation"
10-
default SYNC_SYS_SEMAPHORE
10+
default SYNC_SYS_MUTEX
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::Semaphore, with one per form,
16-
to synchronize.
15+
Use to have the dining philosophers sample use sys::Mutex, with one per fork, to
16+
synchronize.
17+
18+
config SYNC_SYS_MUTEX
19+
bool "Use sys::Semaphore to synchronize forks"
20+
help
21+
Use to have the dining philosophers sample use sys::Mutex, with one per fork, to
22+
synchronize.
1723

1824
endchoice

samples/philosophers/sample.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,8 @@ tests:
2020
min_ram: 32
2121
extra_configs:
2222
- CONFIG_SYNC_SYS_SEMAPHORE=y
23+
sample.rust.philosopher.sysmutex:
24+
tags: introduction
25+
min_ram: 32
26+
extra_configs:
27+
- CONFIG_SYNC_SYS_MUTEX=y

samples/philosophers/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ use zephyr::{
2323

2424
// These are optional, based on Kconfig, so allow them to be unused.
2525
#[allow(unused_imports)]
26+
use crate::sysmutex::SysMutexSync;
27+
#[allow(unused_imports)]
2628
use crate::semsync::semaphore_sync;
2729

30+
mod sysmutex;
2831
mod semsync;
2932

3033
/// How many philosophers. There will be the same number of forks.
@@ -82,6 +85,18 @@ fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
8285
semaphore_sync()
8386
}
8487

88+
#[cfg(CONFIG_SYNC_SYS_MUTEX)]
89+
fn get_syncer() -> Vec<Arc<dyn ForkSync>> {
90+
let syncer = Box::new(SysMutexSync::new())
91+
as Box<dyn ForkSync>;
92+
let syncer: Arc<dyn ForkSync> = Arc::from(syncer);
93+
let mut result = Vec::new();
94+
for _ in 0..NUM_PHIL {
95+
result.push(syncer.clone());
96+
}
97+
result
98+
}
99+
85100
fn phil_thread(n: usize, syncer: Arc<dyn ForkSync>) {
86101
printkln!("Child {} started: {:?}", n, syncer);
87102

samples/philosophers/src/sysmutex.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) 2024 Linaro LTD
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! # sys::Mutex implementation of ForkSync
5+
//!
6+
//! This is a simple implementation of the Fork synchronizer that uses underlying Zephyr `k_mutex`
7+
//! wrapped in `sys::Mutex`. The ForkSync semantics map simply to these.
8+
9+
use crate::{
10+
ForkSync,
11+
NUM_PHIL,
12+
};
13+
use zephyr::kobj_define;
14+
use zephyr::sys::sync::Mutex;
15+
use zephyr::time::Forever;
16+
17+
type SysMutexes = [Mutex; NUM_PHIL];
18+
19+
/// A simple implementation of ForkSync based on underlying Zephyr sys::Mutex, which uses explicit
20+
/// lock and release semantics.
21+
22+
#[derive(Debug)]
23+
pub struct SysMutexSync {
24+
locks: SysMutexes,
25+
}
26+
27+
impl SysMutexSync {
28+
#[allow(dead_code)]
29+
pub fn new() -> SysMutexSync {
30+
let locks = MUTEXES.each_ref().map(|m| {
31+
m.init_once(()).unwrap()
32+
});
33+
SysMutexSync { locks }
34+
}
35+
}
36+
37+
impl ForkSync for SysMutexSync {
38+
fn take(&self, index: usize) {
39+
self.locks[index].lock(Forever).unwrap();
40+
}
41+
42+
fn release(&self, index: usize) {
43+
unsafe {
44+
self.locks[index].unlock().unwrap();
45+
}
46+
}
47+
}
48+
49+
kobj_define! {
50+
static MUTEXES: [StaticMutex; NUM_PHIL];
51+
}

0 commit comments

Comments
 (0)