Skip to content
Snippets Groups Projects
Commit ac8ee8dc authored by Luis Gerhorst's avatar Luis Gerhorst
Browse files

per-cpu arm_arch_timer lock and last_cycle

parent 51624cf1
No related branches found
No related tags found
No related merge requests found
...@@ -15,8 +15,11 @@ ...@@ -15,8 +15,11 @@
#define MAX_TICKS INT32_MAX #define MAX_TICKS INT32_MAX
#define MIN_DELAY (1000) #define MIN_DELAY (1000)
static struct k_spinlock lock; struct arm_arch_timer {
static volatile uint64_t last_cycle; struct k_spinlock lock;
volatile uint64_t last_cycle;
};
static struct arm_arch_timer timer[CONFIG_MP_NUM_CPUS];
static void arm_arch_timer_compare_isr(const void *arg) static void arm_arch_timer_compare_isr(const void *arg)
{ {
...@@ -24,15 +27,18 @@ static void arm_arch_timer_compare_isr(const void *arg) ...@@ -24,15 +27,18 @@ static void arm_arch_timer_compare_isr(const void *arg)
printk("%s on cpu%d\n", __func__, arch_curr_cpu()->id); printk("%s on cpu%d\n", __func__, arch_curr_cpu()->id);
k_spinlock_key_t key = k_spin_lock(&lock); int cpu = arch_curr_cpu()->id;
struct arm_arch_timer *cpu_timer = &timer[cpu];
k_spinlock_key_t key = k_spin_lock(&cpu_timer->lock);
uint64_t curr_cycle = arm_arch_timer_count(); uint64_t curr_cycle = arm_arch_timer_count();
uint32_t delta_ticks = (uint32_t)((curr_cycle - last_cycle) / CYC_PER_TICK); uint32_t delta_ticks = (uint32_t)((curr_cycle - cpu_timer->last_cycle) / CYC_PER_TICK);
last_cycle += delta_ticks * CYC_PER_TICK; cpu_timer->last_cycle += delta_ticks * CYC_PER_TICK;
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
uint64_t next_cycle = last_cycle + CYC_PER_TICK; uint64_t next_cycle = cpu_timer->last_cycle + CYC_PER_TICK;
if ((uint64_t)(next_cycle - curr_cycle) < MIN_DELAY) { if ((uint64_t)(next_cycle - curr_cycle) < MIN_DELAY) {
next_cycle += CYC_PER_TICK; next_cycle += CYC_PER_TICK;
...@@ -40,7 +46,7 @@ static void arm_arch_timer_compare_isr(const void *arg) ...@@ -40,7 +46,7 @@ static void arm_arch_timer_compare_isr(const void *arg)
arm_arch_timer_set_compare(next_cycle); arm_arch_timer_set_compare(next_cycle);
} }
k_spin_unlock(&lock, key); k_spin_unlock(&cpu_timer->lock, key);
z_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? delta_ticks : 1); z_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? delta_ticks : 1);
} }
...@@ -71,21 +77,24 @@ void z_clock_set_timeout(int32_t ticks, bool idle) ...@@ -71,21 +77,24 @@ void z_clock_set_timeout(int32_t ticks, bool idle)
ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : \ ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : \
MIN(MAX_TICKS, MAX(ticks - 1, 0)); MIN(MAX_TICKS, MAX(ticks - 1, 0));
k_spinlock_key_t key = k_spin_lock(&lock); int cpu = arch_curr_cpu()->id;
struct arm_arch_timer *cpu_timer = &timer[cpu];
k_spinlock_key_t key = k_spin_lock(&cpu_timer->lock);
uint64_t curr_cycle = arm_arch_timer_count(); uint64_t curr_cycle = arm_arch_timer_count();
uint64_t req_cycle = ticks * CYC_PER_TICK; uint64_t req_cycle = ticks * CYC_PER_TICK;
/* Round up to next tick boundary */ /* Round up to next tick boundary */
req_cycle += (curr_cycle - last_cycle) + (CYC_PER_TICK - 1); req_cycle += (curr_cycle - cpu_timer->last_cycle) + (CYC_PER_TICK - 1);
req_cycle = (req_cycle / CYC_PER_TICK) * CYC_PER_TICK; req_cycle = (req_cycle / CYC_PER_TICK) * CYC_PER_TICK;
if ((req_cycle + last_cycle - curr_cycle) < MIN_DELAY) { if ((req_cycle + cpu_timer->last_cycle - curr_cycle) < MIN_DELAY) {
req_cycle += CYC_PER_TICK; req_cycle += CYC_PER_TICK;
} }
arm_arch_timer_set_compare(req_cycle + last_cycle); arm_arch_timer_set_compare(req_cycle + cpu_timer->last_cycle);
k_spin_unlock(&lock, key); k_spin_unlock(&cpu_timer->lock, key);
#endif #endif
} }
...@@ -96,11 +105,15 @@ uint32_t z_clock_elapsed(void) ...@@ -96,11 +105,15 @@ uint32_t z_clock_elapsed(void)
return 0; return 0;
} }
k_spinlock_key_t key = k_spin_lock(&lock); /* TODO: irq_lock? */
uint32_t ret = (uint32_t)((arm_arch_timer_count() - last_cycle) int cpu = arch_curr_cpu()->id;
struct arm_arch_timer *cpu_timer = &timer[cpu];
k_spinlock_key_t key = k_spin_lock(&cpu_timer->lock);
uint32_t ret = (uint32_t)((arm_arch_timer_count() - cpu_timer->last_cycle)
/ CYC_PER_TICK); / CYC_PER_TICK);
k_spin_unlock(&lock, key); k_spin_unlock(&cpu_timer->lock, key);
return ret; return ret;
} }
...@@ -112,9 +125,9 @@ uint32_t z_timer_cycle_get_32(void) ...@@ -112,9 +125,9 @@ uint32_t z_timer_cycle_get_32(void)
#if defined(CONFIG_SMP) && CONFIG_MP_NUM_CPUS > 1 #if defined(CONFIG_SMP) && CONFIG_MP_NUM_CPUS > 1
void smp_timer_init(void) void smp_timer_init(void)
{ {
printk("%s()\n", __func__); printk("%s() on cpu%d\n", __func__, arch_curr_cpu()->id);
/* arm_arch_timer_set_compare(arm_arch_timer_count() + CYC_PER_TICK); */ arm_arch_timer_set_compare(arm_arch_timer_count() + CYC_PER_TICK);
/* arm_arch_timer_enable(true); */ arm_arch_timer_enable(true);
/* irq_enable(ARM_ARCH_TIMER_IRQ); */ irq_enable(ARM_ARCH_TIMER_IRQ);
} }
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment