Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove duplicated alarm syscall. #636

Merged
merged 2 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ features = ["no_auto_layout", "no_debug_memop"]
libtock_buttons = { path = "third_party/libtock-rs/apis/buttons" }
libtock_platform = { path = "third_party/libtock-rs/platform" }
libtock_drivers = { path = "third_party/libtock-drivers" }
libtock_alarm = { path = "third_party/libtock-rs/apis/alarm" }
libtock_console = { path = "third_party/libtock-rs/apis/console" }
libtock_leds = { path = "third_party/libtock-rs/apis/leds" }
lang_items = { path = "third_party/lang-items" }
Expand Down
10 changes: 6 additions & 4 deletions src/env/tock/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
// limitations under the License.

use core::marker::PhantomData;
use libtock_drivers::timer::{get_clock_frequency, get_ticks};
use libtock_alarm::Alarm;
use libtock_drivers::result::FlexUnwrap;
use libtock_drivers::timer::Timer;
use libtock_platform::Syscalls;
use opensk::api::clock::Clock;

Expand Down Expand Up @@ -63,7 +65,7 @@ impl<S: Syscalls> TockClock<S> {
///
/// Call this regularly to timeout reliably despite wrapping clock ticks.
pub fn tickle(&mut self) {
let cur_tick = get_ticks::<S>().ok().unwrap();
let cur_tick = Timer::<S>::get_ticks().flex_unwrap();
if cur_tick < self.now.tick {
self.now.epoch += 1;
}
Expand All @@ -77,7 +79,7 @@ impl<S: Syscalls> Clock for TockClock<S> {
fn make_timer(&mut self, milliseconds: usize) -> Self::Timer {
let milliseconds = milliseconds as u32;
self.tickle();
let clock_frequency = get_clock_frequency::<S>().ok().unwrap();
let clock_frequency = Alarm::<S>::get_frequency().ok().unwrap().0;
let delta_tick = match milliseconds.checked_mul(clock_frequency) {
Some(x) => x / 1000,
// All CTAP timeouts are multiples of 100 so far. Worst case we timeout too early.
Expand All @@ -95,7 +97,7 @@ impl<S: Syscalls> Clock for TockClock<S> {

#[cfg(feature = "debug_ctap")]
fn timestamp_us(&mut self) -> usize {
let clock_frequency = get_clock_frequency::<S>().ok().unwrap();
let clock_frequency = Alarm::<S>::get_frequency().ok().unwrap().0;
let total_ticks = 0x100_0000u64 * self.now.epoch as u64 + self.now.tick as u64;
(total_ticks.wrapping_mul(1_000_000u64) / clock_frequency as u64) as usize
}
Expand Down
1 change: 1 addition & 0 deletions third_party/lang-items/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ libtock_drivers = { path = "../libtock-drivers" }
libtock_platform = { path = "../../third_party/libtock-rs/platform" }
libtock_low_level_debug = { path = "../../third_party/libtock-rs/apis/low_level_debug" }
libtock_leds = { path = "../../third_party/libtock-rs/apis/leds" }
libtock_alarm = { path = "../../third_party/libtock-rs/apis/alarm" }
libtock_console = { path = "../../third_party/libtock-rs/apis/console" }

[dependencies.linked_list_allocator]
Expand Down
8 changes: 4 additions & 4 deletions third_party/lang-items/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use libtock_drivers::timer;
use libtock_alarm::{Alarm, Milliseconds};
use libtock_leds::Leds;
use libtock_low_level_debug::{AlertCode, LowLevelDebug};
use libtock_platform as platform;
Expand Down Expand Up @@ -28,13 +28,13 @@ impl<S: Syscalls, C: platform::subscribe::Config> Util<S, C> {
let _ = Leds::<S>::on(led);
}
}
let _ = timer::Alarm::<S, C>::sleep_for(timer::Milliseconds(100));
let _ = Alarm::<S, C>::sleep_for(Milliseconds(100));
if let Ok(led_count) = Leds::<S>::count() {
for led in 0..led_count {
let _ = Leds::<S>::off(led);
}
}
let _ = timer::Alarm::<S, C>::sleep_for(timer::Milliseconds(100));
let _ = Alarm::<S, C>::sleep_for(Milliseconds(100));
}
}

Expand All @@ -47,7 +47,7 @@ impl<S: Syscalls, C: platform::subscribe::Config> Util<S, C> {
if let Ok(leds) = Leds::<S>::count() {
for led in 0..leds {
let _ = Leds::<S>::on(led);
let _ = timer::Alarm::<S, C>::sleep_for(timer::Milliseconds(100));
let _ = Alarm::<S, C>::sleep_for(Milliseconds(100));
let _ = Leds::<S>::off(led);
}
}
Expand Down
1 change: 1 addition & 0 deletions third_party/libtock-drivers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license = "MIT/Apache-2.0"
edition = "2018"

[dependencies]
libtock_alarm = { path = "../../third_party/libtock-rs/apis/alarm" }
libtock_console = { path = "../../third_party/libtock-rs/apis/console" }
libtock_platform = { path = "../../third_party/libtock-rs/platform" }

Expand Down
121 changes: 8 additions & 113 deletions third_party/libtock-drivers/src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,105 +8,16 @@
//!
//! Adapted from the [libtock-rs](https://github.com/tock/libtock-rs/blob/master/apis/alarm/src/lib.rs) alarm driver interface

use crate::result::{FlexUnwrap, OtherError, TockError, TockResult};
use crate::util::Util;
use core::cell::Cell;
use crate::result::{OtherError, TockResult};
use core::marker::PhantomData;
use core::ops::{Add, AddAssign, Sub};
use libtock_alarm::{Hz, Alarm, Milliseconds, Convert};
use libtock_platform as platform;
use libtock_platform::{share, DefaultConfig, ErrorCode, Syscalls};
use libtock_platform::{DefaultConfig, ErrorCode, Syscalls};
use platform::share::Handle;
use platform::subscribe::OneId;
use platform::{Subscribe, Upcall};

pub struct Alarm<S: Syscalls, C: platform::subscribe::Config = DefaultConfig>(S, C);

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Hz(pub u32);

pub trait Convert {
/// Converts a time unit by rounding up.
fn to_ticks(self, freq: Hz) -> Ticks;
}

#[derive(Copy, Clone, Debug)]
pub struct Ticks(pub u32);

impl Convert for Ticks {
fn to_ticks(self, _freq: Hz) -> Ticks {
self
}
}

pub fn get_ticks<S: Syscalls>() -> TockResult<u32> {
Ok(S::command(DRIVER_NUM, command::TIME, 0, 0).to_result::<u32, ErrorCode>()?)
}

pub fn get_clock_frequency<S: Syscalls>() -> TockResult<u32> {
Ok(S::command(DRIVER_NUM, command::FREQUENCY, 0, 0).to_result::<u32, ErrorCode>()?)
}

#[derive(Copy, Clone)]
pub struct Milliseconds(pub u32);

impl Convert for Milliseconds {
fn to_ticks(self, freq: Hz) -> Ticks {
// Saturating multiplication will top out at about 1 hour at 1MHz.
// It's large enough for an alarm, and much simpler than failing
// or losing precision for short sleeps.

/// u32::div_ceil is still unstable.
fn div_ceil(a: u32, other: u32) -> u32 {
let d = a / other;
let m = a % other;
if m == 0 {
d
} else {
d + 1
}
}
Ticks(div_ceil(self.0.saturating_mul(freq.0), 1000))
}
}

impl<S: Syscalls, C: platform::subscribe::Config> Alarm<S, C> {
/// Run a check against the console capsule to ensure it is present.
///
/// Returns number of concurrent notifications supported,
/// 0 if unbounded.
#[inline(always)]
pub fn driver_check() -> Result<u32, ErrorCode> {
S::command(DRIVER_NUM, command::DRIVER_CHECK, 0, 0).to_result()
}

pub fn get_frequency() -> Result<Hz, ErrorCode> {
S::command(DRIVER_NUM, command::FREQUENCY, 0, 0)
.to_result()
.map(Hz)
}

pub fn sleep_for<T: Convert>(time: T) -> Result<(), ErrorCode> {
let freq = Self::get_frequency()?;
let ticks = time.to_ticks(freq);

let called: Cell<Option<(u32, u32)>> = Cell::new(None);
share::scope(|subscribe| {
S::subscribe::<_, _, C, DRIVER_NUM, { subscribe::CALLBACK }>(subscribe, &called)?;

S::command(DRIVER_NUM, command::SET_RELATIVE, ticks.0, 0)
.to_result()
.map(|_when: u32| ())?;

loop {
S::yield_wait();
if let Some((_when, _ref)) = called.get() {
return Ok(());
}
}
})
}
}

pub struct Timer<S: Syscalls, C: platform::subscribe::Config = DefaultConfig> {
clock_frequency: Hz,
s: PhantomData<S>,
Expand Down Expand Up @@ -157,16 +68,13 @@ impl<S: Syscalls, C: platform::subscribe::Config, CB: Fn(ClockValue)>
S::command(DRIVER_NUM, command::DRIVER_CHECK, 0, 0).to_result::<(), ErrorCode>()?;
// Alarm driver only returns success as only a single concurrent timer is supported.

let clock_frequency =
S::command(DRIVER_NUM, command::FREQUENCY, 0, 0).to_result::<u32, ErrorCode>()?;
let clock_frequency = Alarm::<S>::get_frequency()?;

if clock_frequency < 1_000 {
if clock_frequency.0 < 1_000 {
// The alarm's frequency must be at least 1 kHz.
return Err(OtherError::TimerDriverErroneousClockFrequency.into());
}

let clock_frequency = Hz(clock_frequency);

Ok(Timer {
clock_frequency,
c: PhantomData,
Expand Down Expand Up @@ -202,19 +110,8 @@ impl<S: Syscalls, C: platform::subscribe::Config> Timer<S, C> {
}
}

pub fn sleep(duration: Duration<isize>) -> TockResult<()> {
let expired = Cell::new(false);
let mut with_callback = with_callback::<S, C, _>(|_| expired.set(true));

let mut timer = with_callback.init().flex_unwrap();
timer.set_alarm(duration).flex_unwrap();

Util::<S>::yieldk_for(|| expired.get());

match timer.stop_alarm() {
Ok(_) | Err(TockError::Command(ErrorCode::Already)) => Ok(()),
Err(e) => Err(e),
}
pub fn get_ticks() -> TockResult<u32> {
Ok(S::command(DRIVER_NUM, command::TIME, 0, 0).to_result::<u32, ErrorCode>()?)
}

/// Returns the clock frequency of the timer.
Expand All @@ -224,10 +121,8 @@ impl<S: Syscalls, C: platform::subscribe::Config> Timer<S, C> {

/// Returns the current counter tick value.
pub fn get_current_counter_ticks(&self) -> TockResult<ClockValue> {
let ticks = S::command(DRIVER_NUM, command::TIME, 0, 0).to_result::<u32, ErrorCode>()?;

Ok(ClockValue {
num_ticks: ticks as isize,
num_ticks: Self::get_ticks()? as isize,
clock_frequency: self.clock_frequency(),
})
}
Expand Down