kernel/timer: Spinlockify
Simple global lock around the timer API. Actually a lot of this usage
was using needless vestigial locking around existing scheduler and
timeout APIs that are now internally synchronized.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
diff --git a/kernel/timer.c b/kernel/timer.c
index e523d7d..8c858d4 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -10,10 +10,13 @@
#include <wait_q.h>
#include <syscall_handler.h>
#include <stdbool.h>
+#include <spinlock.h>
extern struct k_timer _k_timer_list_start[];
extern struct k_timer _k_timer_list_end[];
+static struct k_spinlock lock;
+
#ifdef CONFIG_OBJECT_TRACING
struct k_timer *_trace_list_k_timer;
@@ -48,17 +51,14 @@
{
struct k_timer *timer = CONTAINER_OF(t, struct k_timer, timeout);
struct k_thread *thread;
- unsigned int key;
/*
* if the timer is periodic, start it again; don't add _TICK_ALIGN
* since we're already aligned to a tick boundary
*/
if (timer->period > 0) {
- key = irq_lock();
_add_timeout(&timer->timeout, _timer_expiration_handler,
timer->period);
- irq_unlock(key);
}
/* update timer's status */
@@ -85,9 +85,7 @@
*/
_unpend_thread_no_timeout(thread);
- key = irq_lock();
_ready_thread(thread);
- irq_unlock(key);
_set_thread_return_value(thread, 0);
}
@@ -121,14 +119,11 @@
period_in_ticks = _ms_to_ticks(period);
duration_in_ticks = _ms_to_ticks(duration);
- unsigned int key = irq_lock();
-
(void)_abort_timeout(&timer->timeout);
timer->period = period_in_ticks;
timer->status = 0;
_add_timeout(&timer->timeout, _timer_expiration_handler,
duration_in_ticks);
- irq_unlock(key);
}
#ifdef CONFIG_USERSPACE
@@ -149,11 +144,8 @@
void _impl_k_timer_stop(struct k_timer *timer)
{
- unsigned int key = irq_lock();
int inactive = _abort_timeout(&timer->timeout) != 0;
- irq_unlock(key);
-
if (inactive) {
return;
}
@@ -162,17 +154,11 @@
timer->stop_fn(timer);
}
- key = irq_lock();
struct k_thread *pending_thread = _unpend1_no_timeout(&timer->wait_q);
if (pending_thread != NULL) {
_ready_thread(pending_thread);
- }
-
- if (_is_in_isr()) {
- irq_unlock(key);
- } else {
- _reschedule_irqlock(key);
+ _reschedule_unlocked();
}
}
@@ -182,11 +168,11 @@
u32_t _impl_k_timer_status_get(struct k_timer *timer)
{
- unsigned int key = irq_lock();
+ k_spinlock_key_t key = k_spin_lock(&lock);
u32_t result = timer->status;
timer->status = 0;
- irq_unlock(key);
+ k_spin_unlock(&lock, key);
return result;
}
@@ -199,16 +185,16 @@
{
__ASSERT(!_is_in_isr(), "");
- unsigned int key = irq_lock();
+ k_spinlock_key_t key = k_spin_lock(&lock);
u32_t result = timer->status;
if (result == 0) {
if (!_is_inactive_timeout(&timer->timeout)) {
/* wait for timer to expire or stop */
- (void)_pend_curr_irqlock(key, &timer->wait_q, K_FOREVER);
+ (void)_pend_curr(&lock, key, &timer->wait_q, K_FOREVER);
/* get updated timer status */
- key = irq_lock();
+ key = k_spin_lock(&lock);
result = timer->status;
} else {
/* timer is already stopped */
@@ -218,7 +204,7 @@
}
timer->status = 0;
- irq_unlock(key);
+ k_spin_unlock(&lock, key);
return result;
}