89 выпуск новостей проекта ReactOS

Доступен перевод 89 выпуска новостей проекта ReactOS, операционной системы с открытым исходным кодом, нацеленной на обеспечение совместимости с программами и драйверами Microsoft Windows семейства NT (XP/2003).

RPC

Вызов удалённых процедур (Remote Procedure Call) затрагивает множество различных компонентов Windows, в особенности службы. Таким образом динамическая библиотека вызова удалённых процедур (rpcrt4) имеет довольно важное значение для обеспечения непрерывного функционирования и стабильности ReactOS. Кроме того, она является компонентом, в котором проект крайне зависим от Wine. К сожалению то, что код Wine работает в Linux, ещё не означает, что он будет работать в ReactOS, и все предыдущие попытки синхронизировать rpcrt4 приводили к множеству проблем и сбоев в ReactOS.

Томас Фабер (Thomas Faber), студент, участвовавший в Google Summer of Code с проектом по реализации новой системы для тестирования компонентов ядра, обнаружил, как он полагает, основную причину возникновения критических сбоев RPC в ReactOS. Когда процесс совершает вызов удалённой процедуры, он получает дескриптор этого вызова. Этот дескриптор должен представлять собой уникальный идентификатор для каждой операции RPC, а его уникальность должна был быть гарантирована генератором случайных чисел. Wine для этих целей использует генератор случайных чисел Linux, расположенный в /dev/urandom, которого в ReactOS, разумеется, нет.

В дополнение ко всему прочему, оказалось что в коде ReactOS отсутствует функция NT, которую Wine использует для генерации случайных чисел, поэтому при запросе на получение уникальных идентификаторов для разных операций RPC могли выдаваться одинаковые значения. Это приводило операционную систему в замешательство и ломало функциональность всего, что зависело от RPC. Томас занимается этой проблемой, и, мы надеемся, что в будущем попытки синхронизировать rpcrt4 с кодом Wine не будут приводить к катастрофическим последствиям для операционной системы.

Диспетчер памяти

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

Уже третья команда разработчиков попробовала свои силы в устранении этой проблемы, и все они приходили к одинаковому выводу: переписывание диспетчера памяти, начатое в ARM3, должно быть завершено. Томас был одним из участников команды по устранению этой проблемы, и вначале решил, что ошибка вызвана компонентом setupapi, который производит установку драйверов, библиотек, и связанных файлов. Это было обусловлено довольно захламлённым состоянием и сложностью кода setupapi, поэтому Томас предположил, что ошибка возникает из-за переполнения памяти и тому подобных проблем. Для проверки этой теории Томас создал свой собственный диспетчер кучи и запустил setupapi поверх него. В результате setupapi был реабилитирован, поскольку начали появляться сбои, не связанные с setupapi. Это означало, что проблема находится куда гораздо глубже в диспетчере памяти. Ещё большим разочарованием стало то, что сбои, похоже, зависели от тайминга, что само по себе предполагало вероятный конфликт ресурсов в результате эффекта гонки (race condition).

В битве за MSHTML принимал участие и Кэмерон Гутман (Cameron Gutman), однако ему пришлось отвлечься на патч, предоставленный Николаем Мыльцевым и связанный с работой подкачки. Вообще, объём виртуальной памяти, затребованный приложением, и объём этой памяти, в действительности находящейся в физической памяти, это две разные вещи. В Windows, рабочий набор представляет собой страницы виртуальной памяти процесса, с которыми недавно происходила работа, и для всех процессов имеются максимальный и минимальный размеры рабочего набора. Windows попытается сохранить рабочий набор страниц в физической памяти, предполагая, что для этого имеется достаточно свободного места. Предназначением рабочего набора является предотвращение поглощения всей физической памяти одним приложением, и диспетчер памяти балансирует потребление памяти каждого из процессов путем изъятия страниц из рабочих наборов разных процессов, если в этом возникает необходимость.

Страницы, содержимое которых было изменено в оперативной памяти, должны быть записаны обратно на диск до того, как занимаемый ими блок памяти может быть использован повторно. Когда приходит время для изъятия страниц из рабочего набора, операционная система будет искать достаточное количество чистых, немодифицированных страниц, которые она могла бы повторно использовать, получая тем самым необходимое ей количество свободной памяти. Система должна также постараться записать изменения в занятых страницах, если в её распоряжении имеется недостаточное для удовлетворения запроса на выделение памяти количество свободных страниц, однако как раз этого в ReactOS и не происходило.

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

Микрокоды процессора

Эта тема требует небольшого экскурса в проектирование и изготовление CPU. Большинство программистов понимает, что каждое из семейств процессоров подчинено своей архитектуре набора команд (Instruction Set Architecture), определяющей, какие инструкции и операции процессор может выполнить. Однако многие люди не знают или не задумываются, что большинство процессоров на самом деле не выполняют инструкции, определённые ISA, напрямую. В действительности существует более низкий уровень команд, это так называемые микрокоды, которые управляют работой процессора таким образом, чтобы результат соответствовал требованиям ISA. Эти микрокоды по большей части абсолютно недокументированы, поскольку и у AMD и у Intel они представляют собой коммерческую тайну.

Архитектура современных CPU чрезвычайно сложна, и в ней могут существовать аппаратные ошибки, приводящие к неправильной обработке микрокода. Устранение такой проблемы в аппаратных средствах потребовало бы изменения архитектуры, но в современных CPU возможно исправить эти ошибки, обновив микрокод. AMD и Intel предоставляют эти патчи разработчикам операционных системы в виде двоичных файлов, но процесс, в котором Windows применяет эти патчи, недокументирован. Пьер Швейцер (Pierre Schweitzer) занялся этим вопросом и у него возникли некоторые мысли относительно того, как ReactOS может обновлять микрокод, но на данный момент проблема имеет довольно низкий приоритет. В любом случае, это довольно интересная проблема, выделяющаяся рядом сложностей, с которыми можно встретиться на самых низких уровнях аппаратных/программных интерфейсов.

Установка

Давным-давно принятое архитектурное решение, позволяющее устанавливать ReactOS на системы с малым количеством оперативной памяти, может значительно увеличивать время, необходимое для копирования файлов ReactOS. Сжатый cab-файл, в котором содержатся файлы системы, извлекается во время первого этапа установки. Первоначальный разработчик кода для извлечения файлов из cab-архива не предполагал возможность того, что cab-файл может иметь больший объём, чем количество имеющейся свободной физической памяти.

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

S/G DMA

В традиционных операциях прямого доступа к памяти (DMA) необходим единый непрерывный блок памяти, в который будут передаваться данные. К сожалению, не всегда в распоряжении системы имеется достаточно большой блок памяти. Прямой доступ к памяти по механизму "Scatter/Gather" призван исправить эту проблему путём использования кусков меньшего размера, сохраняя данные об их размещении и записывая данные в них. Основная часть кода поддержки S/G DMA уже имелась в ReactOS, однако API, который представлял бы её функциональность, отсутствовал. Кэмерон взялся и разработал этот API, что позволило работать в ReactOS драйверам, использующим механизм S/G DMA, по большей части это драйверы сетевых карт.

Оптимизации потребления памяти во FreeLoader

Недавно Тимо Кройцер (Timo Kreuzer) заметил, что freeldr довольно неэффективно использует память. Фактически существует два типа данных, для которых freeldr требуется память: данные, которые передаются им ядру, и данные, которые необходимы лишь самому freeldr для завершения загрузки операционной системы. Первоначально freeldr выделял единый блок размером 4 Мб и использовал его для обоих типов данных, при этом ядру приходилось читать все 4 Мб данных. Посчитав это несколько расточительным, Тимо разбил единый кусок на две разные кучи, по одной для каждого типа данных. Это позволяет freeldr освобождать всю память, не имеющую отношения к ядру, что приводит к существенному уменьшению количества занятой памяти. Вроде бы небольшое изменение, однако такие небольшие изменения, как это, могут многое изменить в долгосрочной перспективе.

Исправления файловых путей

Множество регрессий, вызванных новым загрузчиком, были связаны с не совсем верным поведением некоторых функций, имеющих дело с путями. Поскольку загрузчик во время своей работы совершает множество операций доступа к файлам, необходимым для загрузки исполняемых файлов и библиотек, он активно использует функции обработки путей. Алекс Ионеску (Alex Ionescu) недавно уделил время переписыванию большой части основных функций, связанных с различиями кодировки строк и их преобразованием, парсингом сокращений и исправлением кодов ошибок при критических сбоях. Всё это вместе взятое вылилось в устранении значительного количества регрессий, связанных с загрузчиком, и, надеемся, позволит ещё большему количеству приложений функционировать корректно.

Полный текст статьи читайте на OpenNet