3.14. Группа тестов, проверяющих часы и таймеры POSIX.. 2

3.14.2. Функции группы тестов. 2

3.14.3. Алгоритм примера 1 проверки обработки прерываний от таймера процессом при назначении непериодического временного интервала с использованием функции sigaction() для присоединения сигнала, соответствующего таймеру, к функции обработки сигнала. 3

3.14.4. Алгоритм примера 2 проверки обработки прерываний от таймера программой задачи при назначении периодического временного интервала. 8

3.14.5. Алгоритм примера 3 проверки принудительного завершения таймера посредством функции timer_settime(). 10

3.14.6. Алгоритм примера 4 проверки постановки сигналов от таймера в очередь к процессу. 11

3.14.7. Алгоритм примера 5 проверки отсутствия посылки сигнала процессу при истечении временного интервала, если таймер создается с установкой признака извещения SIGEV_NONE. 14

3.14.8. Алгоритм примера 6 ошибочных ситуаций, возникающих при использовании часов и таймеров POSIX.. 14

3.14.9. Алгоритм примера 7 измерения временного отклонения при выполнении функции nanosleep() 17


 

3.14. Группа тестов, проверяющих часы и таймеры POSIX

3.14.1. Состав группы тестов

3.14.1.2. Группа тестов состоит из следующих тестов:

1) теста часов и таймеров POSIX;

2) теста ошибочных ситуаций, возникающих при использовании часов и таймеров POSIX.

3.14.1.3. Тест часов и таймеров POSIX состоит из следующих примеров:

1)проверка обработки прерываний от таймера программой задачи при назначении непериодического временного интервала с использованием функции sigaction() для присоединения таймера к функции обработки сигнала ;

2) проверка обработки прерываний от таймера программой задачи при назначении периодического временного интервала;

3) проверка принудительного завершения таймера посредством функции timer_settime();

4) проверка постановки сигналов от таймера в очередь к процессу;

5) проверка отсутствия посылки сигнала процессу при истечении временного интервала, если таймер создается с установкой признака извещения SIGEV_NONE;

6) проверка ошибочных ситуаций.

3.14.2. Функции группы тестов

3.14.2.1. Тест часов и таймеров POSIX проверяет следующие функции:

1) поддержку текущего времени в секундах и наносекундах;

2) информирование процесса о завершении временного интервала, соответствующего определенному таймеру;

3) создание, уничтожение и запуск таймеров;

4) присоединение программы пользователя к сигналу, соответствующему таймеру;

5) запуск программы, присоединенной к таймеру, при завершении временного интервала на запущенном таймере;

6) принудительное завершение запущенного таймера;

7) получение времени, остающегося до завершения временного интервала запущенного таймера;

8) получение времени превышения временного интервала при подключении программы пользователя;

9) приостанов текущей задачи на определенный временной интервал;

10) возможность задания абсолютного и относительного временного интервала при запуске таймера;

11) постановка сигналов от таймера в очередь к процессу.

3.14.2.2. Тест ошибочных ситуаций проверяет реакцию операционной системы на неправильную работу с часами и таймерами POSIX. Ошибочные ситуации фиксируются в следующих случаях:

1) при попытке работать с часами с указанием идентификатора часов, не равного CLOCK_REALTIME;

2) при получении текущего времени с неправильным указанием адреса области, куда должно быть помещено текущее время;

3) при попытке работать с таймером с указанием недействительного идентификатора;

4) при запуске таймера с указанием неправильного временного интервала;

5) при запуске таймера, когда нет соответствующего таймеру обработчика прерываний;

6) при запуске таймера с указанием временного интервала, который завершается в тот момент, когда процесс, обрабатывающий сигнал завершения временного интервала, уже завершился.

3.14.3. Алгоритм примера 1 проверки обработки прерываний от таймера процессом при назначении непериодического временного интервала с использованием функции sigaction() для присоединения сигнала, соответствующего таймеру, к функции обработки сигнала

3.14.3.1. Таблица параметров примера содержит следующие данные:

- приоритет основного процесса k;

- счетчик запусков таймера n.

3.14.3.2. Пример состоит из шести функций и двух процессов.

Функция 1 представляет собой основную программу примера и получает управление от диспетчера тестов. Функция 2 является программой обработки прерываний от таймера 1. Функция 3 является программой обработки прерываний от таймера 2. Функция 4 представляет собой программу процесса-потомка основного процесса. Функция 5 является программой обработки прерываний от таймера 3. Функция 6 запускается в результате выполнения команды exec().

Пример состоит из следующих процессов:

- основного процесса, который получает управление из Диспетчера тестов;

- процесса-потомка, который запускает таймер 3. Процесс-потомок планируется основным процессом.

Основной процесс подключается Диспетчером тестов, при этом выполняется функция 1. Указанная функция планирует выполнение остальных функций 2 и 3 и процесса - потомка. Процесс-потомок планирует выполнение функций 5 и 6.

НЕ нашли? Не то? Что вы ищете?

3.14.3.3. В начале основного процесса выполняются следующие действия:

-  запоминается текущий приоритет посредством функции sched_getparam(), запоминается политика планирования посредством функции sched_getsheduler(), устанавливается политика планирования FIFO посредством функции sched_setssheduler() и устанавливает приоритет k посредством функции sched_setparam();

-  запоминается разрешающая способность часов в наносекундах посредством функции clock_getres(). Разрешающая способность используется в дальнейшем для округления значения текущего времени, получаемого посредством функции clock_gettime();

-  создается таймер1 , идентификатор tr1, посредством функции timer_create (CLOCK_REALTIME, evp,&tr1) с указанием адреса структуры sigevent evp!=0 (evp->sigev_notify=SIGEV_SIGNAL,

evp->sigev_signo=SIGUSR1,evp->sigev_value=1) ;

-  проверяется, что при создании таймер tr1 сбрасывается. Проверка осуществляется посредством функции timer_gettime(tr1,value). Возвращаемое время должно быть нулевым;

-  создается таймер 2, идентификатор tr2, посредством функции timer_create () с указанием нулевого адреса структуры sigevent;

-  функция 2 примера присоединяется к таймеру 1 для обработки сигнала SIGUSR1 от таймера 1. Присоединение выполняется посредством функции sigaction () с указанием флага SA_SIGINFO;

-  функция 3 примера присоединяется к таймеру 2 для обработки сигнала SIGALRM от таймера 2. Присоединение выполняется посредством функции sigaction ()с указанием флага SA_SIGINFO;

-  обнуляются общие переменные m1 и m2;

-  счетчик n устанавливается равным количеству запусков таймера, указанному в параметрах примера;

-  организуется цикл, в каждой фазе которого запускаются таймеры 1 и 2.

3.14.3.4. Функция 2 примера обрабатывает прерывания, которые возникают при завершении временного интервала, на который запускается таймер 1. Указанная программа имеет следующий алгоритм:

1) анализируются входные параметры (si_signo=SIGUSR1, si_code=SI_TIMER, si_value=1);

2) формируется массив 1.

Формируемый массив состоит из элементов. Номер элемента массива соответствует номеру подключения программы 1 и фиксируется переменной m1. Элемент массива содержит время подключения функции 2, которое выполняется посредством функции clock_gettime().

3.14.3.5. Функция 3 примера обрабатывает прерывания, которые возникают при завершении временного интервала, на который запускается таймер 2. Указанная программа имеет алгоритм, аналогичный алгоритму функции 2. Исключением являются следующие моменты:

- при анализе входных параметров si_signo=SIGALRM, si_code=SI_TIMER, si_value=идентификатору таймера;

- формируется массив 2;

-  номер элемента массива соответствует номеру подключения функции 3 и фиксируется переменной m2.

Элемент массива содержит время подключения функции 2, которое выполняется посредством функции clock_gettime().

3.14.3.6. В каждой фазе цикла примера выполняются различные действия в зависимости от значения счетчика запуска таймеров n.

3.14.3.7. При n>1 выполняются следующие действия:

1) устанавливается таймер 1 посредством функции timer_settime() с указанием абсолютного временного интервала а1 и нулевого периодического интервала;

2) основной процесс задерживается на временной интервал b1, меньший, чем интервал, заданный при выдаче функции timer_settime() для запуска таймера 1. Задержка выполняется посредством функции nanosleep(), при этом должен быть указан параметр rmtp;

3) после завершения временного интервала b1, управление возвращается основному процессу, при этом код возврата функции nanosleep() также должен быть нулевым, а оставшееся время, вычисленное посредством функции nanosleep() также должно быть нулевым;

4) вычисляется время, оставшееся до завершения временного интервала, на который запущен таймер 1. Время вычисляется посредством функции timer_gettime(). Вычисленное время должно быть меньше или равно (в зависимости от разрешающей способности таймера) разности временных интервалов а1 и b1;

5) основной процесс задерживается на временной интервал с1, больший, чем временной интервал а1. Задержка выполняется посредством функции nanosleep();

6) после завершения временного интервала а1 и обработки его функцией 2 примера, управление возвращается программе примера. При этом код завершения программы nanosleep() будет равен -1 с номером ошибки EINTR, что свидетельствует о том, что возврат управления в программу примера произошел до завершения временного интервала с1, заданного при выдаче функции nanosleep(). Оставшееся время, вычисленное функцией nanosleep(), должно быть меньше временного интервала с1;

7) устанавливается таймер 2 посредством функции timer_settime() с указанием относительного временного интервала а2 и нулевого периодического временного интервала;

8) основной процесс задерживается на временной интервал с2, больший, чем временной интервал а2. Задержка задачи на временной интервал выполняется посредством функции nanosleep();

9) после завершения временного интервала а2 и обработки его функцией 3 примера, управление возвращается программе примера. При этом код завершения программы nanosleep() будет равен -1 с номером ошибки EINTR, что свидетельствует о том, что возврат управления в программу примера произошел до завершения временного интервала с2, заданного при выдаче функции nanosleep(). Оставшееся время, вычисленное функцией nanosleep(), должно быть меньше временного интервала с2;

10) счетчик n уменьшается на единицу.

Далее при описании алгоритма примера имеется ввиду, что при запуске таймера 1 посредством функции timer_settime() указывается абсолютный временной интервал и нулевой периодический интервал, а при запуске таймера 2 посредством функции timer_settime(), указывается относительный временной интервал и нулевой периодический интервал.

3.14.3.8. При n=1 выполняются следующие действия:

1) выполняются шаги с 1 по 4, перечисленные в п.3.14.3.7.;

2) устанавливается новый интервал d1 (d1>a1) в таймере 1 посредством функции timer_settime(), при этом вычисляется предыдущий временной интервал, как если бы была использована функции timer_gettime();

3) сравниваются интервалы, вычисленные посредством функций timer_gettime() и timer_settime();

4) основной процесс задерживается на временной интервал е1, больший, чем временной интервал d1, посредством функции nanosleep();

5) после завершения временного интервала d1 и обработки его
функцией 2 примера, управление возвращается программе примера. При этом код завершения программы nanosleep() будет равен -1 с номером ошибки EINTR, что свидетельствует о том, что возврат управления в программу примера произошел до завершения временного интервала е1, заданного при выдаче функции nanosleep(). Оставшееся время, вычисленное функцией nanosleep(), должно быть меньше временного интервала е1;

6) выполняются шаги с 7 по 10, перечисленные в п.3.14.3.7.

3.14.3.9. При n=0 выполняются следующие действия:

1)  анализируются массив 1 и массив 2. Они должны содержать п элементов, и временные интервалы, зафиксированные в элементах массива, должны соответствовать временным интервалам, устанавливаемым при запуске соответственно таймера 1 и таймера 2;

2)  планируется потомок основного процесса посредством функции fork().

3.14.3.10. Далее основной процесс имеет следующий алгоритм:

1)  основной процесс переходит в ожидание завершения процесса-потомка посредством функции wait() или waitpid();

2)  после завершения процесса-потомка уничтожается таймер 1 посредством функции timer_delete(), и уничтожается таймер 2 посредством функции timer_delete();.

3)  Восстанавливается политика планирования и приоритет и происходит завершение основного процесса.

3.14.3.11. Процесс-потомок имеет следующий алгоритм:

1)  выполняется установка таймера 1 посредством функции timer_settime(). Код завершения должен быть равен -1, так как таймер 1 не наследуется.;

2)  выполняется установка таймера 2 посредством функции timer_settime(). Код завершения должен быть равен -1, так как таймер 2 не наследуется.;

3)  создается таймер 3 посредством функции timer_create(), сигнал SIGUSR1;

4)  обнуляется константа к;

5)  функция 5 присоединяется к таймеру 3 посредством функции sigaction(). Функция 5 увеличивает константу к на 1;

6)  устанавливается таймер 3 посредством функции timer_settime(), временной интервал а4;

7)  процесс задерживается на интервал в4, больший а4 посредством функции nanosleep(). Код завершения функции должен быть нулевым, и значение константы к должно быть равно 1;

8)  происходит обращение к функции exec() c указанием в качестве параметра фукции 6, в которой происходит установка таймера 3 посредством функции timer_settime(), код завершения указанной функции должен быть равен -1, так как таймер в этом случае будет сброшен и уничтожен;

9)  процесс-потомок завершает свою работу.

3.14.4. Алгоритм примера 2 проверки обработки прерываний от таймера программой задачи при назначении периодического временного интервала

3.14.4.1. Таблица параметров примера содержит следующие данные:

- приоритет основного процесса k;

- количество запусков таймера n.

3.14.4.2. В начале программы примера выполняются следующие действия:

-  запоминается текущий приоритет посредством функции sched_getparam(), запоминается политика планирования посредством функции sched_getsheduler(), устанавливается политика планирования FIFO посредством функции sched_setssheduler() и устанавливает приоритет k посредством функции sched_setparam();

-  запоминается разрешающая способность часов в наносекундах посредством функции clock_getres(). Разрешающая способность используется в дальнейшем для округления значения текущего времени, получаемого посредством функции clock_gettime();

- создается таймер посредством функции timer_create(), с указанием ненулевого значения адреса структуры sigevent() (sigev_signo= SIGUSR1, sigev_value=2, sigev_nitify=SIGEV_SIGNAL) ;

- присоединяется программа Proc2 основного процесса, обрабатывающая прерывания от таймера, к сигналу SIGUSR1 посредством функции sigaction() c установкой флага SA_SIGINFO ;

-  устанавливается общая переменная n, значение которой равно количеству запусков таймера;

-  обнуляется общая переменная к;

- устанавливается счетчик m, первоначальное значение которого равно количеству запусков таймера n;

- запускается таймер посредством функции timer_settime() с указанием относительного временного интервала а1 и периодического временного интервала в2 (указанные интервалы должны быть равны друг другу);

- организуется цикл.

3.14.4.3. Программа Proc2, обрабатывающая прерывания от таймера, подключается периодически через указанный при запуске таймера периодический временной интервал. Указанная программа имеет следующий алгоритм:

- счетчик п уменьшается на единицу;

- в случае ненулевого значения n, формируется текущий элемент массива. Номер элемента массива соответствует номеру подключения программы обработки прерывания от таймера. Первый элемент массива содержит время подключения указанной программы, которое вычисляется посредством функции clock_gettime(). Второй элемент массива содержит число срабатываний указанного таймера, которое вычисляется посредством функции timer_getoverrun();

- в случае нулевого значения счетчика n, выполняется принудительное завершение периодических запусков таймера посредством функции timer_settime() с указанием нулевого интервала запуска таймера и нулевого периодического интервала;

- программа завершает свою работу.

3.14.4.4. В каждой фазе цикла программы примера выполняются следующие действия:

- основной процесс задерживается на временной интервал, больший, чем интервал периодического запуска таймера;

- после завершения периодического временного интервала и обработки его программой Proc2, основной процесс получает управление получает управление. При этом код завершения функции nanosleep() будет равен -1 с номером ошибки EINTR, что свидетельствует о том, что возврат управления в основной процесс произошел до завершения временного интервала, заданного при выдаче функции nanosleep();

- счетчик m уменьшается на единицу.

3.14.4.5. Выход из цикла происходит при нулевом значении
счетчика m.

После выхода из цикла анализируется массив, сформированный программой обработки прерываний от таймера. Массив должен содержать количество элементов, равное количеству запусков таймера. Времена запусков программы обработки прерываний, зафиксированные в элементах массива, должны соответствовать заданному периодическому временному интервалу.

3.14.4.6. Программа завершается, выполняя следующие действия:

- уничтожается таймер посредством функции timer_delete();

- восстанавливается приоритет и политика планирования посредством функций shed_setsheduler() и sched_setparam(), и происходит выход в Диспетчер тестов.

3.14.5. Алгоритм примера 3 проверки принудительного завершения таймера посредством функции timer_settime().

3.14.5.1. Программа примера имеет следующий алгоритм:

-  создается таймер посредством функции timer_create(), номер сигнала SIGUSR2;

-  устанавливается счетчик п, значение которого равно любому целому числу;

-  устанавливается программа обработки прерываний от таймера посредством функции sigaction(). В функции указанной программы входит уменьшение счетчика п на единицу;

-  запускается таймер посредством функции timer_settime() с указанием относительного временного интервала а1 и периодического временного интервала в1 ;

-  программа примера приостанавливается на временной интервал посредством функции nanosleep(), с указанием временного интервала t, меньшего, чем временной интервал, заданный при запуске таймера;

-  после завершения временного интервала t управление возвращается программе примера. При этом код завершения функции nanosleep() должен быть нулевым, что свидетельствует о том, что временной интервал запуска таймера не завершился и сигнал от таймера не вырабатывался;

-  принудительно завершается таймер посредством функции timer_settimel() с указанием нулевого интервала запуска и нулевого периодического интервала и ненулевого значения параметра ovalue;

-  анализируется предыдущий временной интервал из величины ovalue, интервал запуска должен быть равен величине а1, а периодический временной интервал должен быть равен в1;.

-  основной процесс задерживается на временной интервал посредством функции nanosleep(), с указанием временного интервала t2 большего, чем временной интервал запуска таймера;

-  после завершения временного интервала t2 управление возвращается основному процессу. При этом код завершения функции nanosleep() должен быть нулевым, так как таймер был принудительно завершен и выработка сигнала таймера не происходит;

-  анализируется значение счетчика п, оно должно быть равно максимальному значению, так как программа обработки прерываний от таймера не подключалась;

-  уничтожается таймер посредством функции timer_delete();

-  выполняется возврат управления в Диспетчер тестов.

3.14.6. Алгоритм примера 4 проверки постановки сигналов от таймера в очередь к процессу.

3.14.6.1. Таблица параметров примера содержит следующие данные:

- приоритет основного процесса k;

- счетчик для организации цикла n, время цикла должно быть больше по крайней мере утроенного интервала запуска таймера.

3.14.6.2. В начале программы примера выполняются следующие действия:

1)  запоминается текущий приоритет посредством функции sched_getparam(), запоминается политика планирования посредством функции sched_getsheduler(), устанавливается политика планирования FIFO посредством функции sched_setssheduler() и устанавливается приоритет k посредством функции sched_setparam();

2)  создается таймер 1 посредством функции timer_create(), с указанием ненулевого значения адреса структуры sigevent() (sigev_signo= SIGRTMIN, sigev_value=указатель на структуру str1 sigev_nitify=SIGEV_SIGNAL). Структура str содержит следующие данные: текущее время перед циклом, текущее время после цикла ;

3)  присоединяется программа Proc2 основного процесса, обрабатывающая прерывания от таймера, к сигналу SIGКRTMIN посредством функции sigaction() c установкой флага SA_SIGINFO ;

4)  присоединяется программа Proc2 основного процесса к сигналу SIGRTMIN+1 посредством функции sigaction() c установкой флага SA_SIGINFO ;

5)  блокируется сигналы SIGRTMIN, SIGRTMIN+1 с использованием функций sigemptyset(), sigaddset(), sigprocmask();

6)  переменной i присваивается нулевое значение;

7)  запускается таймер посредством функции timer_settime() с указанием относительного временного интервала а1 и периодического временного интервала в1 , а1=в1;

8)  вычисляется текущее время посредством функции clock_gettime() и выполняется запись его в структуру str в поле "текущее время перед циклом";

9)  организуется цикл со счетчиком n (длительность цикла должна быть по крайней мере больше 3*а1). В первой, пятой и седьмой фазе цикла вызывающий процесс вычисляет текущее время посредством функции clock_gettime() и посылает самому себе сигнал SIGRTMIN+1 посредством функции sigqueue(), при этом параметр value должен быть указателем на структуру timespec, в которой содержится вычисленное текущее время ;

10)  вычисляется текущее время посредством функции clock_gettime() и выполняется запись его в структуру str в поле "текущее время после цикла";

11)  разрешается обработка сигналов SIGRTMIN и SIGRTMIN+1 с использованием функций sigdelset() и sigprocmask();

12)  принудительно завершается таймер посредством функции timer_settime() с указанием нулевого интервала запуска и нулевого периодического интервала

13)  анализируется сформированный массив. Времена подключения программы обработки сигнала должны укладываться в диапазон между "текущим временем перед циклом" и "текущим временем после цикла";

14)  уничтожается таймер посредством функции timer_delete();

15)  восстанавливается приоритет и политика планирования посредством функций shed_setsheduler() и sched_setparam(), и происходит выход в Диспетчер тестов.

3.14.6.3. Программа обработки прерываний от таймера имеет следующий алгоритм:

-  анализируются входные параметры. Если si_signo=SIGRTMIN, si_code=SI_TIMER, si_value=указатель на структуру str. Если si_signo=SIGRTMIN+1, si_code=SI_QUEUE, si_value=указатель на структуру timespec;

-  значение переменной i увеличивается на 1;

-  формируется массив. Формируемый массив состоит из элементов. Номер элемента массива соответствует номеру подключения программы 1 и фиксируется переменной i. Если обрабатывается сигнал SIGRTMIN+1, элементы массива содержат номер сигнала, время подключения функции 2, которое выполняется посредством функции clock_gettime(), и время из структуры timespec. Если обрабатывается сигнал SIGRTMIN, элементы массива содержат номер сигнала, время подключения функции 2, которое выполняется посредством функции clock_gettime(), и число срабатываний данного таймера, которое происходит между моментом постановки сигнала SIGRTMIN в очередь и моментом приема этого сигнала, которое вычисляется посредством функции timer_getoverrun(),

3.14.7. Алгоритм примера 5 проверки отсутствия посылки сигнала процессу при истечении временного интервала, если таймер создается с установкой признака извещения SIGEV_NONE.

Алгоритм примера совпадает с алгоритмом примера, описанным в п.3.14.6., исключением является момент создания таймера ( п 3.14.6.2)),

sigev_notify=SIGEV_NONE. В этом случае массив будет содержать члены, которые соответствуют сигналу SIGRTMIN+1, и при анализе массива этот факт должен быть отражен.

3.14.8. Алгоритм примера 6 ошибочных ситуаций, возникающих при использовании часов и таймеров POSIX

3.14.8.1. В начале программы теста проверяется реакция на некорректное обращение к часам POSIX.

При этом выполняются следующие действия:

- выполняется обращение к функции clock_gettime() с указанием идентификатора часов, не равного CLOCK_REALTIME;

- анализируется код завершения (ret) функции clock_gettime(). Код завершения должен быть равен -1 с номером ошибки, равным EINVAL;

- выполняется обращение к функции clock_gettime() с указанием правильного идентификатора часов CLOCK_REALTIME и с нулевым значением указателя tp (указателя на структуру, куда должно быть помещено текущее время);

-  анализируется код завершения функции clock_gettime(), он должен быть равен -1 с номером ошибки EFAULT;

- выполняется обращение к функции clock_getres() с указанием идентификатора часов, не равного CLOCK_REALTIME;

- анализируется код завершения функции clock_getres(). Код завершения должен быть равен -1 с номером ошибки, равным EINVAL;

- выполняется обращение к функции clock_getres() с указанием правильного идентификатора часов CLOCK_REALTIME и с нулевым значением указателя tp (указателя на структуру, куда должно быть помещено текущее время);

- анализируется код завершения функции clock_getres(), он должен быть равен -1 с номером ошибки EFAULT.

3.14.8.2. Проверяется реакция на некорректное обращение к функции timer_create(). Для этого выполняются следующие действия:

- выполняется обращение к функции timer_create() с идентификатором часов, не равным CLOCK_REALTIME. При этом код завершения функции должен быть равен -1 с номером ошибки EINVAL;

-  выполняется обращение к функции timer_create() с указанием номера сигнала больше максимально возможного в данной реализации. При этом код завершения функции должен быть равен -1 с номером ошибки EINVAL;

- выполняется обращение к функции timer_create() с указанием нулевого аргумента timerid. При этом код завершения функции должен быть равен -1 с номером ошибки EINVAL;

-  организуется цикл. В каждой фазе цикла создается таймер посредством функции timer_create() с корректными аргументами. Счетчик цикла должен быть равен максимально возможному количеству таймеров для процесса в данной реализации плюс 1. В этом случае в последней фазе цикла код завершения функции timer_create() должен быть равен -1 с кодом ошибки EAGAIN. После выполнения цикла все созданные таймеры необходимо удалить посредством функции timer_delete().

3.14.8.3. Создается таймер посредством функции timer_create() .

3.14.8.4. Проверяется реакция на некорректное обращение к функции timer_settime (). Для этого выполняются следующие действия:

- выполняется обращение к функции timer_settime() с указанием неправильного идентификатора таймера. При этом код завершения функции должен быть равен -1 с номером ошибки EINVAL;

- выполняется обращение к функции timer_settime() с указанием правильного идентификатора и значения наносекунд большего (или равного) 1.000.000.000. При этом код завершения функции должен быть равен -1 с номером ошибки EINVAL;

-  выполняется обращение к функции timer_settime() с указанием значения наносекунд, меньшего нуля. При этом код завершения функции должен быть равен -1 с номером ошибки EINVAL.

3.14.8.5. Назначается обработчик прерываний от таймера посредством функции sigaction(). В функции указанного обработчика входит модификация переменной i, первоначальное значение которой равно нулю, на единицу.

3.14.8.6. Выполняется проверка реакции на установку абсолютного временного интервала, указывающий момент времени, который уже прошел. Для этого выполняются следующие действия:

- вычисляется текущее время t посредством функции clock_gettime();

- запускается таймер посредством функции timer_settime() и с указанием абсолютного временного интервала (TIMER_ABSTIME), значение которого указывает время, которое прошло;

- вычисляется текущее время t1 посредством функции timer_gettime();

- анализируется разность времен t1 и t и величина переменной i. Разность времен t1 и t не должна быть больше заранее вычисленной величины a, а значение переменной i должно быть равно единице.

3.14.8.7. Проверяется реакция на неправильное обращение к функции timer_delete(). Для этого выполняются следующие действия:

-  функция timer_delete() выдается дважды с идентификатором созданного таймера. Первый раз код завершения функции должен быть нулевым, второй раз код завершения функции должен быть равен -1 с номером ошибки EINVAL;

-  создается таймер ( функция timer_create()), для сигнала, указанного в функции, определяется программа обработки сигнала (функция sigaction()) , в алгоритм которой входит модификация переменной i на 1. Запускается таймер на временной интервал в1 посредством функции timer_settime(). Процесс задерживается на временной интервал с1<в1 посредством функции nanosleep(). Далее таймер уничтожается посредством функции timer_delete(), и процесс задерживается на временной интервал d1>в1 посредством функции nanosleep() и проверяется значение переменной i, оно не должно измениться, так как при уничтожении таймера таймер предварительно останавливается.

3.14.8.8. Проверяется реакция на сигнализацию, когда таймер, запущенный процессом, завершается в момент времени, когда процесс уже завершил свою работу. Для этого выполняются следующие действия:

- планируется процесс-потомок посредством функции fork();

- основной процесс переходит в состояние ожидания завершения процесса-потомка.

Процесс-потомок имеет следующий алгоритм:

- создается таймер посредством функции timer_create();

- назначается обработчик прерываний для таймера посредством функции sigaction();

- запускается таймер посредством функции timer_settime();

- задача завершает свою работу посредством функции exit().

Временной интервал, назначенный процессом-потомком, истекает в момент, когда процесс-потомок уже завершился.

3.14.8.9. Проверяется реакция на сигнал SIGALRM, когда для таймера, созданного и запущенного процессом, не назначена программа обработки этого сигнала. Для этого выполняются следующие действия:

- планируется процесс-потомок посредством функции fork();

-  основной процесс назначает программу обработки сигнала SIGCHLD посредством функции sigaction() и задерживается на временной интервал t1 посредством функции nanosleep();

-  функция обработки сигнала анализирует код завершения процесса-потомка, он должен быть завершен аварийно из-за прибытия сигнала SIGALRM, для которого не назначена программа обработки сигнала;

-  код завершения функции nanosleep() должен быть равен -1, так как возникло прерывание по сигналу SIGCHLD. На этом основной процесс завершает свою работу.

Процесс-потомок имеет следующий алгоритм:

- создается таймер посредством функции timer_create() с указанием нулевого значения evp;

-  запускается таймер посредством функции timer_settime(). Значение интервала запуска таймера должно быть меньше t1;

-  организуется бесконечный цикл.

3.14.8.10. Тест завершает свою работу выполнением следующих действий:

- происходит выход в Диспетчер Тестов.

3.14.9. Алгоритм примера 7 измерения временного отклонения при выполнении функции nanosleep()

3.14.9.1. Таблица параметров примера содержит следующие данные:

- счетчик цикла для вычисления отклонения.

3.14.9.2. В начале работы программы выполняются следующие действия:

1)  запоминается текущий приоритет посредством функции sched_getparam(), запоминается политика планирования посредством функции sched_getsheduler(), устанавливается политика планирования FIFO посредством функции sched_setssheduler();

2)  вычисляется максимальный приоритет в системе, соответствующий политике планирования FIFO посредством функции sched_get_priority_max(SCHED_FIFO);

3)  чтобы гарантировать, что при вычислении отклонения не было временных задержек, связанных с вытеснением страниц, вся память процесса запирается в оперативной памяти посредством функции mlockall(MCL_FUTURE);

4)  устанавливается приоритет процесса, равный вычисленному максимальному приоритету посредством функции sched_setscheduler(0, SCHED_FIFO, &sp);

5)  организуется цикл, счетчик цикла равен параметру, указанному в параметрах примера.

3.14.9.3. В каждой фазе цикла выполняются следующие действия:

1)  вычисляется случайный промежуток времени dt, используемый для функции nanosleep() по следующему алгоритму:

struct timespec ns;

ns. tv_sec = 0;

if (rand() % 2)

ns. tv_nsec = rand() % 100000;

else if (rand() % 2)

ns. tv_nsec = ((rand() << 16) | rand()) % ;

else

ns. tv_nsec = rand() % ;

if (ns. tv_nsec < 0)

ns. tv_nsec *= -1;

2)  вычисляется текущее время t1 посредством функции clock_gettime(CLOCK_REALTIME, &tp1);

3)  процесс приостанавливается посредством функции ret_val = nanosleep(&ns, 0);

4)  вычисляется текущее время t2 посредством функции clock_gettime(CLOCK_REALTIME, &tp2);

5)  вычисляется отклонение по формуле jt=t2-dt-t1;

6)  отклонение фиксируется в переменной, отражающей текущее отклонение;

7)  текущее отклонение сравнивается с наибольшим отклонением, определенным в предыдущих циклах, если в текущем цикле фиксируется наибольшее отклонение, оно записывается в переменную, отражающую самое большое отклонение.

3.14.9.4. При выходе из цикла в переменной, отражающей самое большое отклонение, хранится результат выполнения теста.

3.14.9.5. Тест завершает свою работу, восстановив запомненный приоритет и политику планирования.

3.14.10. В результате функционирования группа тестов проверяет выполнение функций, перечисленных в следующей таблице:

Название

библиотеки

Название

программы

Параметры

clockLib

clock_gettime

CLOCK_REALTIME,

адрес структуры, где размещается временной интервал

сlock_getres

CLOCK_REALTIME,

адрес структуры, куда помещается разрешающая способность

timer_create

CLOCK_REALTIME,

номер сигнала,

величина таймера

timer_create

CLOCK_REALTIME,

0

timer_delete

timerid

timer_getoverrun

timerid

timer_ gettime

timerid,

адрес памяти, куда записывается оставшееся время

timer_ settime

timerid,

TIMER_ABSTIME,

нулевой периодический интервал

временной интервал запуска таймера,

адрес памяти для предыдущего интервала

timer_settime

Timerid,

0,

0,

адрес памяти для предыдущего интервала

timer_ settime

timerid,

0,

нулевой периодический интервал

временной интервал запуска таймера,

нулевой адрес памяти для предыдущего интервала

timer_ settime

timerid,

0,

периодический временной интервал

временной интервал запуска таймера

timer_ settime

timerid,

TIMER_ABSTIME,

0,

новый интервал,

адрес памяти для предыдущего интервала

nanosleep

время задержки.

адрес ячейки, куда помещается оставшееся время

nanosleep

время задержки,

NULL