Вход/Регистрация
Разработка ядра Linux
вернуться

Лав Роберт

Шрифт:

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
  • ...
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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