summaryrefslogtreecommitdiff
path: root/arch/um/os-Linux/time.c
diff options
context:
space:
mode:
authorTiwei Bie <tiwei.btw@antgroup.com>2025-10-27 08:18:11 +0800
committerJohannes Berg <johannes.berg@intel.com>2025-10-27 16:41:15 +0100
commit9c82de55d4783e906f18219f833ad97fd8d9c5df (patch)
treeea9428edb6dd080e20e1a0508f5b5797dabf0b45 /arch/um/os-Linux/time.c
parent2670917c2fc8902558f3aba4f41e5cc5bf6e18fa (diff)
um: Define timers on a per-CPU basis
Define timers on a per-CPU basis to enable each CPU to have its own timer. This is a preparation for adding SMP support. Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com> Link: https://patch.msgid.link/20251027001815.1666872-5-tiwei.bie@linux.dev Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'arch/um/os-Linux/time.c')
-rw-r--r--arch/um/os-Linux/time.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index f3d4547e5227..e0197bfe4ac9 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -17,7 +17,7 @@
#include <string.h>
#include "internal.h"
-static timer_t event_high_res_timer = 0;
+static timer_t event_high_res_timer[CONFIG_NR_CPUS] = { 0 };
static inline long long timespec_to_ns(const struct timespec *ts)
{
@@ -32,20 +32,30 @@ long long os_persistent_clock_emulation(void)
return timespec_to_ns(&realtime_tp);
}
+#ifndef sigev_notify_thread_id
+#define sigev_notify_thread_id _sigev_un._tid
+#endif
+
/**
* os_timer_create() - create an new posix (interval) timer
*/
int os_timer_create(void)
{
- timer_t *t = &event_high_res_timer;
+ timer_t *t = &event_high_res_timer[0];
+ struct sigevent sev = {
+ .sigev_notify = SIGEV_THREAD_ID,
+ .sigev_signo = SIGALRM,
+ .sigev_value.sival_ptr = t,
+ .sigev_notify_thread_id = gettid(),
+ };
- if (timer_create(CLOCK_MONOTONIC, NULL, t) == -1)
+ if (timer_create(CLOCK_MONOTONIC, &sev, t) == -1)
return -1;
return 0;
}
-int os_timer_set_interval(unsigned long long nsecs)
+int os_timer_set_interval(int cpu, unsigned long long nsecs)
{
struct itimerspec its;
@@ -55,13 +65,13 @@ int os_timer_set_interval(unsigned long long nsecs)
its.it_interval.tv_sec = nsecs / UM_NSEC_PER_SEC;
its.it_interval.tv_nsec = nsecs % UM_NSEC_PER_SEC;
- if (timer_settime(event_high_res_timer, 0, &its, NULL) == -1)
+ if (timer_settime(event_high_res_timer[cpu], 0, &its, NULL) == -1)
return -errno;
return 0;
}
-int os_timer_one_shot(unsigned long long nsecs)
+int os_timer_one_shot(int cpu, unsigned long long nsecs)
{
struct itimerspec its = {
.it_value.tv_sec = nsecs / UM_NSEC_PER_SEC,
@@ -71,19 +81,20 @@ int os_timer_one_shot(unsigned long long nsecs)
.it_interval.tv_nsec = 0, // we cheat here
};
- timer_settime(event_high_res_timer, 0, &its, NULL);
+ timer_settime(event_high_res_timer[cpu], 0, &its, NULL);
return 0;
}
/**
* os_timer_disable() - disable the posix (interval) timer
+ * @cpu: the CPU for which the timer is to be disabled
*/
-void os_timer_disable(void)
+void os_timer_disable(int cpu)
{
struct itimerspec its;
memset(&its, 0, sizeof(struct itimerspec));
- timer_settime(event_high_res_timer, 0, &its, NULL);
+ timer_settime(event_high_res_timer[cpu], 0, &its, NULL);
}
long long os_nsecs(void)