Книга: Разработка ядра Linux
Абсолютное время
Абсолютное время
Текущее значение абсолютного времени (time of day, wall time, время дня) определено в файле kernel/timer.c
следующим образом.
struct timespec xtime;
Структура данных timespec
определена в файле <linux/time.h>
в следующем виде.
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
Поле xtime.tv_sec
содержит количество секунд, которые прошли с 1 января 1970 года (UTC, Universal Coordinated Time, всеобщее скоординированное время). Указанная дата называется epoch (начало эпохи). В большинстве Unix-подобных операционных систем счет времени ведется с начала эпохи. В поле xtime.tv_nsec
хранится количество наносекунд, которые прошли в последней секунде.
Чтение или запись переменной xtime
требует захвата блокировки xtime_lock
. Это блокировка — не обычная спин-блокировка, а секвентная блокировка, которая рассматривается в главе 9, "Средства синхронизации в ядре".
Для обновления значения переменной xtime
необходимо захватить секвентную блокировку на запись следующим образом.
write_seqlock(&xtime_lock);
/* обновить значение переменной xtime ... */
write_sequnlock(&xtime_lock);
Считывание значения переменной xtime
требует применения функций read_seqbegin()
и read_seqretry()
следующим образом.
do {
unsigned long lost;
seq = read_seqbegin(&xtime_lock);
usec = timer->get_offset();
lost = jiffies — wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
} while (read_seqretry(&xtime_lock, seq));
Этот цикл повторяется до тех пор, пока не будет гарантии того, что во время считывания данных не было записи. Если во время выполнения цикла приходит прерывание таймера и переменная xtime
обновляется во время выполнения цикла, возвращаемый номер последовательности будет неправильным и цикл повторится снова.
Главный пользовательский интерфейс для получения значения абсолютного времени — это системный вызов gettimeofday()
, который реализован как функция sys_gettimeofday()
следующим образом.
asmlinkage long sys_gettimeofday(struct timeval *tv,
struct timezone *tz) {
if (likely(tv !=NULL)) {
struct timeval_ktv;
do_gettimeofday(&ktv);
if (copy_to_userftv, &ktv, sizeof(ktv))
return -EFAULT;
}
if (unlikely(tz != NULL)) {
if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
return -EFAULT;
}
return 0;
}
Если из пространства пользователя передано ненулевое значение параметра tv
, то вызывается аппаратно-зависимая функция do_gettimeofday()
. Эта функция главным образом выполняет цикл считывания переменной xtime
, который был только что рассмотрен. Аналогично, если параметр tz
не равен нулю, пользователю возвращается значение часового пояса (time zone), в котором находится операционная система. Этот параметр хранится в переменной sys_tz
. Если при копировании в пространство пользователя значения абсолютного времени или часового пояса возникли ошибки, то функция возвращает значение -EFAULT
. В случае успеха возвращается нулевое значение.
Ядро предоставляет системный вызов time()
[58], однако системный вызов gettimeofday()
полностью перекрывает его возможности. Библиотека функций языка С также предоставляет другие функции, связанные с абсолютным временем, такие как ftime()
и ctime()
.
Системный вызов settimeofday()
позволяет установить абсолютное время в указанное значение. Для того чтобы его выполнить, процесс должен иметь возможность использования CAP_SYS_TIME
.
Если не считать обновления переменной xtime
, то ядро не так часто использует абсолютное время, как пространство пользователя. Одно важное исключение— это код файловых систем, который хранят в индексах файлов значения моментов времени доступа к файлам.
- Улучшенное время отклика для версии SuperServer
- Часы в Windows показывают неправильное время
- Глава 7. Дата и время
- Глава 18 Время
- 1.4.1. Кодирование во время выполнения
- Время и дата
- Время
- Не допускайте того, чтобы поток пользовательского интерфейса блокировался на длительное время
- Время показывается в 12-часовом формате, а мне привычнее 24-часовой. Как это изменить?
- Когда я не работаю за компьютером, через некоторое время он отключается. Можно ли это исправить?
- Новый винчестер издает странный звук во время работы. Он не похож на тот, с которым работал старый диск. Это нормально и...
- Время от времени оптическая мышь начинает мигать. Она сломалась?