Немного о TSS Доброе время суток! У меня вопрос – если я использую модель памяти – флет, то как мне нужно переключать задачи? Если я не ошибаюсь – то есть два вариант (хотя могу ошибаться): 1) С помощу TSS 2) Всё руками Кто может подсказать в этом не легком вопросе? Заранее всём спасибо!
Great а где можно найти доки по второму варианту? (если такие имеются) хорошо било б если на русском. Заранее спасибо! Или может кто-то сможет описать "в двух словах" как это сделать?
в двух словах нужно сохранить контекст старый и восстановить новый. смотри исходники виндового планировщика потоков если интересно. поиск по ключевому слову SwapContext
не факт, что медленнее можешь начать отсюда макрос switch_to - переключение контекста в Linux для x86
AntiB Используй ТОЛЬКО второй вариант. Хотя бы потому, что "аппаратную многозадачность" с переключением посредством смены TSS в 64-расширениях IA-32 (х86-64 по-народному) отменили. Переключение задачи в общем случае сводится к тому, что ты должен: а) сохранить все регистры процессора, доступные для задачи, в блоке управления снимаемой с процессора задачей (сюда входят регистры общего назначения, сегментные, регистры FPU, EFLAGS, EIP... может, ещё что забыл); б) восстановить те же самые регистры из блока управления той задачей, которую ты ставишь на процессор. Само же переключение задач требуется в двух случаях: либо выполнявшаяся задача приостанавливается (например, собирается ждать окончания операции ввода-вывода) или завершается, либо для неё истёк выделенный системой квант времени (время выделяется небольшими дольками -- квантами, чтобы никакая задача не могла монополизировать процессор).
да ему имхо просто стоит посмотреть как это сделано в винде, я, помнится, сам смотрел от нечего делать в иде. соответственно там так и есть.. вызовы Sleep, WaitForSingleObject, etc.. сводятся к тому, что текущему ETHREAD ставится состояние ожидания и идет поиск нового подходяего потока, обеспечивающийся вызывами KiFindReadyThread/KiSwapContext(=>SwapContext). Как только он найден, выполняется SwapContext(), сохраняющая контекст старого потока и восстанавливающая контекст нового. По прерыванию таймера выполняется hal.dll!HalpClockInterrupt, обновляющая счетчики производительности, делающая HalBeginSystemInterrupt и все такое. В конечном итоге она заканчивается на джампе в KeUpdateSystemTime. Она, если нужно, выполняет APC, производит манипуляции с дебуггером, если он активен, и вызывает HalEndSystemInterrupt, а потом Kei386EoiHelper. Тут вся малина и заканчивается. HalEndSystemInterrupt восстанавливает значение TPR таким, каким оно было до входа в прерывание (значение IRQL, сохраненное в HalBeginSystemInterrupt), и, если IRQL был соответствующим, то вызывает KiDispatchInterrupt, которая шаманит со списоком потоков, находя подходящий, и переключается на него.
господа, а почему обязательно Windows? чем Linux хуже? FPU регистры восстанавливать в большинстве случаев не надо обычно хватает CR0.TS = 1 (хотя если процесс активно использует FPU/SSE/MMX, то во избежании вероятного в таком случае #NM FPU-контекст можно восстановить при переключении контекста)
rei3er Речь про то, что вообще должно сохраняться, а как это реализовано технически -- другой вопрос.
Great, "пример" плохой, потому как воды много, часть не верно, часть не в тему. Вопрос был о переключении задачи, а не о том как, по вашему мнению, винда обрабатывает clock interrupt. SII все вроде рассказал как нужно, стоит только добавить, что кроме ухода в ожидание и истечения кванта "некоторые" ОС также переключают задачу при: вытеснении потока, измении Priority, изменении Affinity.
Zufyxe там же можно посмотреть и про переключение либо в сорсах. это не по моему мнению, а по дизасму