diff --git a/adapter/thread_metric/BUILD.gn b/adapter/thread_metric/BUILD.gn index a0de91e9..efbeb366 100644 --- a/adapter/thread_metric/BUILD.gn +++ b/adapter/thread_metric/BUILD.gn @@ -45,10 +45,17 @@ tm_case("tm_cooperative_scheduling_test") { [ "//external/thread_metric/v6.4.2/src/tm_cooperative_scheduling_test.c" ] } +tm_case("tm_synchronization_processing_test") { + sources = [ + "//external/thread_metric/v6.4.2/src/tm_synchronization_processing_test.c", + ] +} + group("run_tests") { testonly = true deps = [ ":run_tm_basic_process_test", ":run_tm_preemptive_scheduling_test", + ":run_tm_synchronization_processing_test", ] } diff --git a/adapter/thread_metric/src/lib.rs b/adapter/thread_metric/src/lib.rs index 03a60b78..103408fe 100644 --- a/adapter/thread_metric/src/lib.rs +++ b/adapter/thread_metric/src/lib.rs @@ -17,6 +17,7 @@ use blueos::{ scheduler, scheduler::InsertToEnd, + sync::semaphore::Semaphore, thread, thread::{Entry, Thread, ThreadNode, IDLE, READY, RUNNING, SUSPENDED}, time, @@ -33,6 +34,9 @@ const TM_ERROR: c_int = 1; const MAX_THREADS: usize = 8; static mut TM_THREADS: [MaybeUninit; MAX_THREADS] = [const { MaybeUninit::zeroed() }; MAX_THREADS]; +const MAX_SEMAS: usize = 8; +static mut TM_SEMAS: [MaybeUninit>; MAX_SEMAS] = + [const { MaybeUninit::zeroed() }; MAX_SEMAS]; #[no_mangle] pub extern "C" fn tm_initialize(test_initialization_function: extern "C" fn()) { @@ -108,3 +112,29 @@ pub extern "C" fn tm_thread_relinquish() { pub extern "C" fn tm_thread_sleep(secs: c_int) { scheduler::suspend_me_for::<()>(Tick(TICKS_PER_SECOND * secs as usize), None); } + +#[no_mangle] +pub extern "C" fn tm_semaphore_create(sema_id: c_int) -> c_int { + let sema = Arc::new(Semaphore::new()); + sema.init(1); + unsafe { + TM_SEMAS[sema_id as usize].write(sema); + } + TM_SUCCESS +} + +#[no_mangle] +pub extern "C" fn tm_semaphore_get(sema_id: c_int) -> c_int { + let sema = unsafe { TM_SEMAS[sema_id as usize].assume_init_ref() }; + if sema.acquire_notimeout::() { + return TM_SUCCESS; + } + TM_ERROR +} + +#[no_mangle] +pub extern "C" fn tm_semaphore_put(sema_id: c_int) -> c_int { + let sema = unsafe { TM_SEMAS[sema_id as usize].assume_init_ref() }; + sema.release(); + TM_SUCCESS +} diff --git a/adapter/thread_metric/tests/tm_synchronization_processing_test.checker b/adapter/thread_metric/tests/tm_synchronization_processing_test.checker new file mode 100644 index 00000000..a50c4c43 --- /dev/null +++ b/adapter/thread_metric/tests/tm_synchronization_processing_test.checker @@ -0,0 +1,3 @@ +// TOTAL-TIMEOUT: 30 +// ASSERT-SUCC: Relative Time: 20 +// ASSERT-FAIL: ERROR \ No newline at end of file diff --git a/kernel/src/sync/semaphore.rs b/kernel/src/sync/semaphore.rs index 6996fac6..0ec31aed 100644 --- a/kernel/src/sync/semaphore.rs +++ b/kernel/src/sync/semaphore.rs @@ -49,7 +49,7 @@ impl Semaphore { self.counter.get() } - #[inline] + #[inline(always)] pub fn try_acquire(&self) -> bool where M: InsertModeTrait, @@ -69,7 +69,6 @@ impl Semaphore { true } - #[inline(never)] pub fn acquire_notimeout(&self) -> bool where M: InsertModeTrait, @@ -171,7 +170,6 @@ impl Semaphore { self.acquire_timeout::(timeout) } - #[inline(never)] pub fn release(&self) { let mut w = self.pending.irqsave_lock(); let old = self.counter.get(); @@ -208,7 +206,6 @@ impl Semaphore { scheduler::yield_me_now_or_later(); } - #[inline(never)] pub fn reset(&self) -> usize { let mut w = self.pending.irqsave_lock(); self.counter.set(0);