Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Z
Zephyr RTOS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Luis Gerhorst
Zephyr RTOS
Commits
ac8ee8dc
Commit
ac8ee8dc
authored
4 years ago
by
Luis Gerhorst
Browse files
Options
Downloads
Patches
Plain Diff
per-cpu arm_arch_timer lock and last_cycle
parent
51624cf1
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
drivers/timer/arm_arch_timer.c
+32
-19
32 additions, 19 deletions
drivers/timer/arm_arch_timer.c
with
32 additions
and
19 deletions
drivers/timer/arm_arch_timer.c
+
32
−
19
View file @
ac8ee8dc
...
@@ -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
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment