mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-07-08 00:23:23 -04:00
There really is no reason to pass the amount of time we should sleep, especially since it's just hard-coded to one second. Additionally, one second isn't really all that long, and as we are expecting to be woken up by a signal, we can sleep longer and avoid doing some work every second, so replace the current clock_nanosleep() with just an empty select() that can _only_ be woken up by a signal. We can also remove the deliver_alarm() since we don't need to do that when we got e.g. SIGIO that woke us up, and if we got SIGALRM the signal handler will actually (have) run, so it's just unnecessary extra work. Similarly, in time-travel mode, just program the wakeup event from idle to be S64_MAX, which is basically the most you could ever simulate to. Of course, you should already have an event in the list that's earlier and will cause a wakeup, normally that's the regular timer interrupt, though in suspend it may (later) also be an RTC event. Since actually getting to this point would be a bug and you can't ever get out again, panic() on it in the time control code. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Acked-By: Anton Ivanov <anton.ivanov@cambridgegreys.com> Signed-off-by: Richard Weinberger <richard@nod.at>
84 lines
1.8 KiB
C
84 lines
1.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2012 - 2014 Cisco Systems
|
|
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
|
*/
|
|
|
|
#ifndef __TIMER_INTERNAL_H__
|
|
#define __TIMER_INTERNAL_H__
|
|
#include <linux/list.h>
|
|
|
|
#define TIMER_MULTIPLIER 256
|
|
#define TIMER_MIN_DELTA 500
|
|
|
|
enum time_travel_mode {
|
|
TT_MODE_OFF,
|
|
TT_MODE_BASIC,
|
|
TT_MODE_INFCPU,
|
|
TT_MODE_EXTERNAL,
|
|
};
|
|
|
|
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
|
|
struct time_travel_event {
|
|
unsigned long long time;
|
|
void (*fn)(struct time_travel_event *d);
|
|
struct list_head list;
|
|
bool pending, onstack;
|
|
};
|
|
|
|
extern enum time_travel_mode time_travel_mode;
|
|
|
|
void time_travel_sleep(void);
|
|
|
|
static inline void
|
|
time_travel_set_event_fn(struct time_travel_event *e,
|
|
void (*fn)(struct time_travel_event *d))
|
|
{
|
|
e->fn = fn;
|
|
}
|
|
|
|
void __time_travel_propagate_time(void);
|
|
|
|
static inline void time_travel_propagate_time(void)
|
|
{
|
|
if (time_travel_mode == TT_MODE_EXTERNAL)
|
|
__time_travel_propagate_time();
|
|
}
|
|
|
|
void __time_travel_wait_readable(int fd);
|
|
|
|
static inline void time_travel_wait_readable(int fd)
|
|
{
|
|
if (time_travel_mode == TT_MODE_EXTERNAL)
|
|
__time_travel_wait_readable(fd);
|
|
}
|
|
|
|
void time_travel_add_irq_event(struct time_travel_event *e);
|
|
#else
|
|
struct time_travel_event {
|
|
};
|
|
|
|
#define time_travel_mode TT_MODE_OFF
|
|
|
|
static inline void time_travel_sleep(void)
|
|
{
|
|
}
|
|
|
|
/* this is a macro so the event/function need not exist */
|
|
#define time_travel_set_event_fn(e, fn) do {} while (0)
|
|
|
|
static inline void time_travel_propagate_time(void)
|
|
{
|
|
}
|
|
|
|
static inline void time_travel_wait_readable(int fd)
|
|
{
|
|
}
|
|
#endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
|
|
|
|
/*
|
|
* Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used,
|
|
* which is intentional since we really shouldn't link it in that case.
|
|
*/
|
|
void time_travel_ndelay(unsigned long nsec);
|
|
#endif /* __TIMER_INTERNAL_H__ */
|