2012-04-09 2 views
9

Я рассматриваю различные проекты ОС в надежде написать простую многозадачную ОС для DCPU-16. Однако все, что я прочитал о реализации превентивной многозадачности, сосредоточено вокруг прерываний. Похоже, что в эпоху 16-битного аппаратного и программного обеспечения совместная многозадачность была более распространенной, но для этого требуется, чтобы каждая программа была написана с учетом многозадачности.Возможна ли упреждающая многозадачная ОС на без прерывания DCPU-16?

Есть ли способ реализовать превентивную многозадачность на архитектуре без прерывания? Все, что я могу придумать, - это интерпретатор, который динамически переключает задачи, но это может привести к огромному результату (возможно, порядка 10-20x +, если бы ему пришлось анализировать каждую операцию и не позволяло чему-либо запускать изначально, я воображая).

+0

Обратите внимание, что в настоящее время DCPU-16 имеют прерывания , – blueshift

+0

Не так ли? По состоянию на 4 мая 2014 года версия документации, доступной на веб-сайте (http://0x10c.com/doc/dcpu-16.txt), по-прежнему равна 1.1 и не имеет прерываний. Есть ли какая-либо документация по новым функциям? –

+0

Я предполагаю, что вы не reddit или не используете форум. Проверьте [этот плохой мальчик (spec 1.7)] (http://pastebin.com/raw.php?i=Q4JvQvnM)! Мы общаемся об этом на freenode IRC# 0x10c-dev, если вы хотите зайти. – blueshift

ответ

4

Упреждающая многозадачность обычно реализуется путем выполнения процедур прерывания для отправки изменений статуса/интересных событий планировщику, который решает, какие задачи приостанавливать и какие новые задачи запускать/продолжать на основе приоритета. Тем не менее, другие интересные события могут возникать, когда выполняемая задача выполняет вызов подпрограммы ОС, которая может иметь такой же эффект.

Но все, что имеет значение, - это то, что какое-то событие отмечено где-то, и планировщик решает, кого запустить. Таким образом, вы можете сделать так, чтобы вся такая сигнализация/планирование событий происходили только по вызовам ОС.

Вы можете добавить вопиющие вызовы планировщику в «удобных» точках в различных командах приложения задач, чтобы чаще переключаться с вашей системы. Независимо от того, просто ли он переключается или использует какую-то справочную информацию, такую ​​как истекшее время, поскольку последний вызов является деталью планировщика.

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

+1

Таким образом, это имеет недостаток совместной многозадачности в том, что нет строгой верхней границы того, как долго процессор может работать без удара планировщика (например, если процесс переходит в цикл, который не связан с вызовами ОС), но поскольку он hijacks OS призывает к планированию, он будет работать на любой программе, которая делает вызовы ОС? –

+2

@AndrewG. в точку. И вот как классическая Mac OS добавила многозадачность, первоначально как расширение в Системе 5. Соответствующие вызовы в ОС рассматривались как совместные многозадачные возможности. Как вы говорите, нет строгой верхней границы - например,процесс, который, предположительно, ошибкой в ​​дизайне, входит в бесконечный цикл без вызовов ОС, повесит всю систему. – Tommy

+0

@Tommy - это то, что аппаратный сторожевой таймер, который утверждает перезагрузку CPU и процедуру сброса в RAM, которая отключает стек до точки входа в программу. Смотрите мои объяснения, почему это не невероятно сумасшедший. –

2

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

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

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

В конце концов вы перейдете к интерпретатору, но только для прыжков.

4

Собственно, да. Наиболее эффективным методом является простое исправление времени выполнения в загрузчике. Материалы ядра/демона могут иметь пользовательские исправления для лучшей отзывчивости. Еще лучше, если у вас есть доступ ко всему источнику, вы можете установить патч в компиляторе.

Патч может состоять из распределенного планировщика.Каждая программа может быть исправлена ​​с таймером с малой задержкой; при загрузке он установит таймер, и при каждом возврате из планировщика он сбросит его. Простейший метод позволил бы просто сделать код

if (timer - start_timer) yield to scheduler; 

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

Это не идеальный вариант, но он будет работать.

Основная проблема заключается в том, чтобы вернуть таймер с низкой задержкой; таким образом это просто сравнение и ветвь. Кроме того, обработка исключений - ошибки в коде, вызывающие, скажем, бесконечные петли, - каким-то образом. Вы можете технически использовать довольно простой аппаратный сторожевой таймер и утверждать сброс на ЦП без очистки любой из ОЗУ; в режиме ОЗУ будет отображаться векторная точка RESET, которая будет проверять и разматывать стек обратно на вызов программы (таким образом, сбой программы, но сохраняя все остальное). Это похоже на сбойную команду if-all-else-crash-the-program. Или вы можете ПОТЕНЦИАЛЬНО изменить его на многозадачность таким образом, RESET как прерывание, но это намного сложнее.

Итак ... да. Это возможно, но сложно; используя методы из JIT-компиляторов и динамических переводчиков (ими пользуются эмуляторы).

Это немного путаное объяснение, я знаю, но я очень устал. Если это не ясно, я могу вернуться и прояснить это завтра.

Кстати, утверждение сброса на центральную часть процессора звучит безумно, но это проверенная временем и проверенная техника. Ранние версии Windows даже сделали это для запуска режима совместимости, я думаю, 386, правильно, потому что не было возможности вернуться к 32-разрядному из 16-разрядного режима. Другие процессоры и ОС сделали это тоже.

EDIT: Итак, я провел некоторое исследование того, что такое DCPU, ха-ха. Это не настоящий процессор. Я понятия не имею, можете ли вы утвердить сброс в эмуляторе Notch, я бы спросил его. Удобная техника.

+0

Было бы точнее суммировать ваше предложение как автоматическую совместную многозадачность? – Tommy

+1

Краткая сводка да :-P –

0

другой способ держать в небольших задач, основанных на очереди событий (например, текущих приложений GUI)

это также кооператив, но имеет эффект не нуждаясь OS звонки вы просто вернуться с задания, а затем она будет перейти к следующей задаче

если вы затем должны продолжить задачу, которую необходимо пройти следующую «функцию» и указатель на данные, которые вы должны очереди задач

+0

Не требует ли это, чтобы все программы в системе разбивали свою обработку на небольшие задачи, заканчивающиеся вызовом ОС (в основном совместная многозадачность)? Или бы вы динамически проверяли и переписывали задания? –

+0

@AndrewG. разве я не говорил это в своем втором предложении? но да, да, было бы, хотя больше возврата в очередь, когда вы закончите –

+0

Вы правы, я неправильно понял. Хорошо спасибо. –

 Смежные вопросы

  • Нет связанных вопросов^_^