Глава 12. Использование шлюзов задачи.
В этой главе приводится пример реализации мультизадачной системы, в которой переключение задач происходит через прерывания. Для этого обработчик исключения прерывания таймера (IRQ 0) реализован в виде отдельной задачи и переключение задач производится по прерыванию таймера (примерно 18 раз в секунду).
В дескрипторе TSS прерванной задачи флаг занятости B остаётся установленным и одной из функций задачи "Main", переключающей две другие задачи "2" и "3", является явный сброс это флага в дескрипторе TSS только что прерванной задачи.
Задачи 2 и 3 не "подразумевают" о том, что их прерывают, они не передают управление другим задачам и такой вариант работы ОС является наиболее общим видом мультизадачной системы.
Пример, приведенный в конце главы, использует следующую схему работы:
Определяютcя 4 задачи: Main, 2, 3 и Timer; задача Main производит инициализацию мультизадачности, задачи 2 и 3 являются рабочими задачами, а Timer обеспечивает поочерёдное переключение между задачами 2 и 3.
| Задача Main разрешает прерывание от таймера (которое было запрещено при инициализации примера) и зацикливается. Больше никаких действий эта задача выполнять не будет - как только сработает прерывание таймера, управление в задачу Main уже не вернётся.
| В примере реализована очередь из двух задач Task_list, представляющая собой два далёких адреса перехода на задачу 2 и 3, расположенных последовательно один за другим. Переменная Task_number хранит номер текущей задачи: Task_number = 0/1 - текущей задачей является задача "2" / "3".
| Обработчик прерывания таймера изменён следующим образом:
|
|
Таким образом, схема работы задач в такой системе получается следующей:
Timer_TSS → TSS_1 → Timer_TSS → TSS_2 → Timer_TSS → TSS_1 → Timer_TSS → TSS_2 → ...
или так:
[ [ Timer_TSS -> TSS_i ] = n раз ] = ? раз,
В такой схеме только один "минус" - то, что при каждом переключении задач предварительно запускается задача Timer, что понижает производительность системы, однако, наличие такой интерфейсной задачи позволяет операционной системе не только управлять переключением задач, но и выполнять следующие действия:
Обрабатывать таймер - менять соответствующим образом переменные времени, даты и некоторые системные счётчики, зависящие от времени.
| Использовать простую структуру рабочих задач и простой способ управления ими, что повышает надёжность и защищённость системы (например, в ОС можно реализовать переключение задач только через очередь и только такой интерфейсной задачей (Timer) и тогда можно запретить задачам самостоятельно вызывать другие задачи).
| Менять дополнительный контекст задачи, например, загружать контекст модуля FPU, MMX и/или XMM до того, как задача явно запросит систему об этом (через исключение), что сэкономит время и, соответственно, повысит производительность системы.
| Можно перед запуском следующей в очереди задачи проводить некоторые проверки, позволяющие повысить производительность системы. Так, например, задачи, находящиеся в состоянии "сна" (stand by) можно пропускать; также можно пропускать задачи, ожидающие событий от устройств ввода, но ещё не получивших нужные данные (например, пропустить задачу, ожидающую ввода с клавиатуры, если с клавиатуры ничего не было введено).
| |
Предлагаемый вашему вниманию пример похож на предыдущий, но имеет следующие дополнения:
В GDT добавлен дескриптор "Timer_TSS", описывающий контекст задачи обработчика прерывания таймера.
| Установка дескриптора TSS для Timer_TSS производится вместе с остальными дескрипторами TSS:
|
Установка мультизадачности также немного отличается от предыдущего примера:
|
Вот так задача Main инициализирует в примере мультизадачность с прерыванием по таймеру:
|
Обратите внимание, что рабочие задачи (это "2" и "3") обе работают в бесконечном цикле и не передают управление другим задачам. Переключение задач действительно происходит по таймеру. Вот так выглядит обработчик прерывания от таймера; этот код является кодом задачи Timer:
|
И, наконец, прекращение работы программы произойдёт по нажатию клавиши Esc, для чего ещё в прошлых примерах соответствующем образом изменён обработчик клавиатуры.
| |
Сам пример доступен здесь - файлы examp_11.asm, examp_11.com, pmode_11.lib и init.lib, - в архиве examp_11.zip (20'501 байт).
Оглавление | Вопросы? Замечания? Пишите: sasm@narod.ru |
Copyright © Александр Семенко. |