User Tag List

Показано с 1 по 10 из 30

Тема: Вытесняющая многозадачность (диспетчер mzkernel)

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #21

    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,089
    Спасибо Благодарностей отдано 
    281
    Спасибо Благодарностей получено 
    70
    Поблагодарили
    49 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Выпустил обновление. Из изменений: небольшая оптимизация при сохранении контекста при прерываниях. Добавлена возможность пуска новых и завершения старых потоков. Для этого используются две новых функции: KeStartThread и KeExitThread.

    Перед пуском нового потока необходимо инициализировать в памяти структуру состояния потока, указать адрес стека потока и разместить на его верхушке точку входа. Адрес структуры нового потока передается функции KeStartThread в регистре IY. Новые потоки находятся в состоянии готовности. Функцию KeStartThread можно вызывать только на IRQL=PASSIVE из какого-нибудь потока. При этом, если приоритет нового потока выше, чем у текущего - то текущий поток будет сразу вытеснен, а управление - отдано новому потоку.

    Поток может завершиться, вызвав функцию KeExitThread по Call или Jp, эта функция не возвращается. Управление передается следующему по приоритету потоку, находящемуся в состоянии готовности. Последний поток с самым низким приоритетом (system idle thread) не должен завершаться или входить в режим ожидания, иначе происходит сбой.

    Изменен способ хранения структур потоков в памяти. Если раньше это был массив структур, длина которого известна во время компиляции, то теперь это односвязный список, элементы которого отсортированы по приоритету в порядке его убывания (это соответствует возрастанию числа, кодирующего приоритет). По-прежнему требуется, чтобы все потоки имели разный приоритет. В сортированном односвязном списке добавление и удаление - дорогие операции, имеющие сложность O(n), однако пуск и завершение потоков происходят редко, поэтому сложность не критична.

    Я не делал любимую многими функцию "TerminateThread" - прибитие одного потока из другого, по той причине, что если прибиваемый поток находится в состоянии ожидания - то его необходимо удалить из списка потоков, ожидающих некий объект. Но поскольку список этот односвязный - то удалить из него элемент невозможно. Надо или хранить в структуре потока указатель на начало списка, или делать двусвязный список. И то, и другое затратно по памяти и по быстродействию операций ожидания и выхода из ожидания, а толку от TerminateThread без защиты памяти мало. Чтобы снять заглючившую задачу, недостаточно прибить поток. Надо еще освободить его ресурсы, а если он перепахал память - то пиши пропало.

    Следующий шаг - динамический приоритет потоков. Здесь опять потребуется изменять структуры данных системы. Чтобы изменить приоритет потока, нужно изменить его положение в списке потоков, отсортированном по приоритетам. Во-первых для списков такое перемещение само по себе затратное - O(n), а с односвязным списком вообще все печально. Фактически придется как бы прибить поток и запустить его заново, и это будет очень тормозно. Возможно, вместе с динамическим приоритетом потоков я добавлю возможность иметь потоки с одинаковым приоритетом и Round-Robin. Для этого придется радикально поменять формат "базы данных" диспетчера, сделав его более похожим на то, что используется в Windows NT.

    Ну а с динамическим приоритетом станут возможными, наконец, мутексы.

    ---------- Post added at 04:25 ---------- Previous post was at 04:16 ----------

    Цитата Сообщение от SfS Посмотреть сообщение
    Может. Но стандартный системный таймер - 10мс, что как бы 100Гц. Оттуда вызывется планировщик.
    Планировщик-то вызывается, но потоки не переключаются каждое прерывание. Quantum для Round-Robin может составлять величину, превышающую интервал между прерываниями.
    Цитата Сообщение от SfS Посмотреть сообщение
    Кроме того - он вызывается из системных вызовов. Ну, скажем, вызвал ты select() или блокирующий read() - если данных нет, то управление будет отдано другим задачам-потокам.
    Внутри системы это приводит к вызову WaitForObject. Все это реализовано в моем диспетчере.
    Цитата Сообщение от SfS Посмотреть сообщение
    "хорошо сказывается на интерактивности системы" то, что для всяких мышек есть аппаратное прерывание.
    Вот как раз аппаратные прерывания от мышек - это по-моему плохая идея. Достаточно опрашивать мышку с частотой обновления экрана, как это сделано на Spectrum и Amiga. Все равно курсор мыши на экране нельзя сдвинуть быстрее, чем отобразится следующий кадр. В качестве бонуса получаем очень плавное перемещение курсора. Кто видел живую Амигу - не даст соврать.
    Последний раз редактировалось Barmaley_m; 22.07.2014 в 05:19.

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Диспетчер памяти в KAY-1024...
    от SoftFelix в разделе KAY
    Ответов: 16
    Последнее: 30.08.2010, 12:07
  2. диспетчер ROM памяти
    от p@lex в разделе Память
    Ответов: 5
    Последнее: 29.03.2010, 22:58
  3. Многозадачность
    от captain cobalt в разделе Оси
    Ответов: 23
    Последнее: 23.04.2005, 19:04

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •