Чтение онлайн

на главную

Жанры

Разработка ядра Linux
Шрифт:

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
.

58

ля некоторых аппаратных платформ функция

sys_time
не реализована, а вместо этого она эмулируется библиотекой функций языка С на основании вызова
gettimeofday
.

Если не считать обновления переменной

xtime
, то ядро не так часто использует абсолютное время, как пространство пользователя. Одно важное исключение— это код файловых систем, который хранят в индексах файлов значения моментов времени доступа к файлам.

Таймеры

Таймеры (timers), или, как их еще иногда называют, динамические таймеры, или таймеры ядра, необходимы для управления ходом времени в ядре. Коду ядра часто необходимо откладывать выполнение некоторых функций на более позднее время. Здесь намеренно выбрано не очень четкое понятие "позже". Назначение механизма нижних половин — это не задерживать выполнение, а не выполнять работу прямо сейчас. В связи с этим необходим инструмент, который позволяет задержать выполнение работы на некоторый интервал времени. Если этот интервал времени не очень маленький, но и не очень большой, то решение проблемы — таймеры ядра.

Таймеры очень легко использовать. Необходимо выполнить некоторые начальные действия, указать момент времени окончания ожидания, указать функцию, которая будет выполнена, когда закончится интервал времени ожидания, и активизировать таймер. Указанная функция будет выполнена, когда закончится интервал времени таймера. Таймеры не являются циклическими. Когда заканчивается интервал времени ожидания, таймер ликвидируется. Это одна из причин, почему таймеры называют динамическими [59] . Таймеры постоянно создаются и ликвидируются, на количество таймеров не существует ограничений. Использование таймеров очень популярно во всех частях ядра.

59

Другая причина состоит в том, что в ядрах старых версий (до 2.3) существовали статические таймеры. Такие таймеры создавались во время компиляции, а не во время выполнения. Они имели ограниченные возможности и из-за их отсутствия сейчас никто не огорчается.

Использование таймеров

Таймеры представлены с помощью структур

timer_list
, которая определена в файле
<linux/timer.h>
следующим образом.

struct timer_list {

 struct list_head entry; /* таймеры хранятся в связанном списке */

 unsigned long expires; /* время окончание срока ожидания в

импульсах системного таймера (jiffies) */

 spinlock_t lock; /* блокировка для защиты данного таймера */

Поделиться:
Популярные книги

Безымянный раб [Другая редакция]

Зыков Виталий Валерьевич
1. Дорога домой
Фантастика:
боевая фантастика
9.41
рейтинг книги
Безымянный раб [Другая редакция]

Измена. Свадьба дракона

Белова Екатерина
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Измена. Свадьба дракона

Не грози Дубровскому! Том VIII

Панарин Антон
8. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том VIII

Последняя Арена 7

Греков Сергей
7. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 7

На границе империй. Том 9. Часть 3

INDIGO
16. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 3

Все не так, как кажется

Юнина Наталья
Любовные романы:
современные любовные романы
7.70
рейтинг книги
Все не так, как кажется

Я же бать, или Как найти мать

Юнина Наталья
Любовные романы:
современные любовные романы
6.44
рейтинг книги
Я же бать, или Как найти мать

Боярышня Дуняша

Меллер Юлия Викторовна
1. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боярышня Дуняша

Аромат невинности

Вудворт Франциска
Любовные романы:
любовно-фантастические романы
эро литература
9.23
рейтинг книги
Аромат невинности

Кодекс Крови. Книга IХ

Борзых М.
9. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IХ

Свет во мраке

Михайлов Дем Алексеевич
8. Изгой
Фантастика:
фэнтези
7.30
рейтинг книги
Свет во мраке

Приручитель женщин-монстров. Том 3

Дорничев Дмитрий
3. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 3

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Безродный

Коган Мстислав Константинович
1. Игра не для слабых
Фантастика:
боевая фантастика
альтернативная история
6.67
рейтинг книги
Безродный