Приветствую всех посетителей.
Данная тема является продолжением темы "Эмулятор ядра OS Windows" http://board.kolibrios.org/viewtopic.ph ... 14fc509ce6
Здесь будут выкладываться посты связанные с предложениями по правке ядра Колибри:
- для повышения функциональности ядра.
- для обеспечения запуска и функционирования программного обеспечения, разработанного на основе платформы OS Windows.
Итак продолжим ....
Эмулятор ядра OS Windows и правки ядра Колибри
Этот пост будет про приоритеты потоков
Винда интенсивно применяет политику приоритетов потоков при своей работе. Эти приоритеты мной игнорировались при разработке эмулятора, что не мешало работе компонентов Винды. Однако, когда я заметил, что число созданных потоков приближается к двустам (а будет еще больше), то резонно задуматься о внедрении в ядро Колибри поддержки системы приоритетов пользовательских потоков.
Нашел тему в форуме "Приоритеты в планировщике задач"
http://board.kolibrios.org/viewtopic.php?t=2316
В последнем сообщении этого форума CleverMouse сообщает о логике работы планировщика.
В эту логику планировщика я предлагаю добавить один пункт (выделено жирным шрифтом):
1) Если пользовательский поток A упорно работал и был прерван по таймеру, то следующим пользовательским потоком будет B, следующий в кольце после A;
2) Если у потока В снижен локальный приоритет и счетчик локального приоритета не обнулен, то переход к следующему потоку этого кольца.
3) Если тот же пользовательский поток A упорно работал и был прерван по другому прерыванию, то следующим пользовательским потоком останется A - возможно, после того, как вмешавшийся ядерный поток что-нибудь сделает.
Предлагаю следующие изменения в ядре Колибри:
1.) Добавить в структуру TASKDATA в файле const.inc два поля в свободные ячейки:
Примечание:
Я пытался просто добавить поля в структуре TASKDATA, но в итоге перестает работать кнопка "ПУСК" у Колибри. Видимо происходит затирание других данных если увеличить размер структуры.
2.) Внедрить код проверки ядром локальных приоритетов пользовательских потоков в файл sched.inc после метки .task_found:
3.) В процедуре set_app_params в файле taskman.inc внедрить код установки начального приоритета потока:
Уровень локальных приоритетов пользовательских потоков может быть установлен от 0 до 255 (максимально возможное значение в байте).
0 - самый высокий локальный приоритет. Этот приоритет установлен по умолчанию при запуске потока.
Продолжение следует......
Винда интенсивно применяет политику приоритетов потоков при своей работе. Эти приоритеты мной игнорировались при разработке эмулятора, что не мешало работе компонентов Винды. Однако, когда я заметил, что число созданных потоков приближается к двустам (а будет еще больше), то резонно задуматься о внедрении в ядро Колибри поддержки системы приоритетов пользовательских потоков.
Нашел тему в форуме "Приоритеты в планировщике задач"
http://board.kolibrios.org/viewtopic.php?t=2316
В последнем сообщении этого форума CleverMouse сообщает о логике работы планировщика.
CleverMouse wrote: ↑Fri Jun 07, 2013 8:09 pm r3615+r3617 вносят дополнение: теперь при поступлении IRQ, отличного от таймера, также вызывается планировщик, но со специальным флагом "смотри только на потоки, которые строго более приоритетны, чем текущий". Флаг также меняет логику продвижения очереди: если пользовательский поток A упорно работал и был прерван по таймеру, то следующим пользовательским потоком будет B, следующий в кольце после A; если тот же пользовательский поток A упорно работал и был прерван по другому прерыванию, то следующим пользовательским потоком останется A - возможно, после того, как вмешавшийся ядерный поток что-нибудь сделает.
В эту логику планировщика я предлагаю добавить один пункт (выделено жирным шрифтом):
1) Если пользовательский поток A упорно работал и был прерван по таймеру, то следующим пользовательским потоком будет B, следующий в кольце после A;
2) Если у потока В снижен локальный приоритет и счетчик локального приоритета не обнулен, то переход к следующему потоку этого кольца.
3) Если тот же пользовательский поток A упорно работал и был прерван по другому прерыванию, то следующим пользовательским потоком останется A - возможно, после того, как вмешавшийся ядерный поток что-нибудь сделает.
Предлагаю следующие изменения в ядре Колибри:
1.) Добавить в структуру TASKDATA в файле const.inc два поля в свободные ячейки:
Примечание:
Я пытался просто добавить поля в структуре TASKDATA, но в итоге перестает работать кнопка "ПУСК" у Колибри. Видимо происходит затирание других данных если увеличить размер структуры.
2.) Внедрить код проверки ядром локальных приоритетов пользовательских потоков в файл sched.inc после метки .task_found:
3.) В процедуре set_app_params в файле taskman.inc внедрить код установки начального приоритета потока:
Уровень локальных приоритетов пользовательских потоков может быть установлен от 0 до 255 (максимально возможное значение в байте).
0 - самый высокий локальный приоритет. Этот приоритет установлен по умолчанию при запуске потока.
Продолжение следует......
Продолжение поста ....
Для регулировки приложением локальных приоритетов запущенных потоков созданы новые функции:
51,3 - получить приоритет потока
51,4 - установить приоритет потока.
Заодно я создал функцию 51,2 - получить pid текущего потока чтобы не обращаться к функции 9 только для того, чтобы получить потоком свой pid.
Если не будет возражений или замечаний то, приблизительно через месяц, я внесу код в SVN и пояснения в справочник по функциям 51,2 - 51,4
Для регулировки приложением локальных приоритетов запущенных потоков созданы новые функции:
51,3 - получить приоритет потока
51,4 - установить приоритет потока.
Заодно я создал функцию 51,2 - получить pid текущего потока чтобы не обращаться к функции 9 только для того, чтобы получить потоком свой pid.
Если не будет возражений или замечаний то, приблизительно через месяц, я внесу код в SVN и пояснения в справочник по функциям 51,2 - 51,4
Этот пост будет про обработку "контролируемых исключений" в ядре Kолибри
Предлагаю для повышения отказоустойчивости ядра Колибри, а также приложений разработанных для Колибри, внедрить механизм обработки "контролируемых исключений" page_fault, вызванных в ходе обработки данных при обращении к памяти для записи/чтения .
Если разработчик ядра, драйвера или приложения желает обезопасить механизм обработки данных при обращении к памяти для записи/чтения (например, к памяти полученной от пользователя), то он может сделать следующие действия:
1.) Перед обращением к памяти, установить следующие данные для обработчика "контролируемых исключений" ядра:
- В регистр edi занести сигнатуру - текст 'EXPT'
- В регистр esi занести адрес, куда должен передать управление обработчик "контролируемых исключений".
2.) По адресу, указанном в регистре esi разработчик прописывает необходимые действия в случае получения некорректных данных.
В итоге:
1. Значительно повышается стабильность (отказоустойчивость) ядра Колибри или приложения при обработке данных.
2. Упрощается алгоритм проверки данных на их корректность.
3. Этот алгоритм могут использовать разработчики приложений без обращения к функции 68,24.
Ниже показан пример применения механизма обработки некорректных данных.
Когда нам в ядро приходят непроверенные данные от пользователя, то мы устанавливаем данные для обработчика "контролируемых исключений" (строка 5593-5594).
Теперь если произойдет исключение из-за обращениия к несуществующей памяти (в строке 5596), то исполнение кода начнется с метки .err_exit: (строка 5619) с корректным завершением обработки запроса от пользователя.
В заключение предлагаю внедрить в файл sys32.inc в процедуре page_fault_exc: код обработчика "контролируемых исключений":
Если не будет возражений или замечаний, то приблизительно через месяц я внесу код в SVN, а также внесу пояснения в справочник по функции 68,24.
Предлагаю для повышения отказоустойчивости ядра Колибри, а также приложений разработанных для Колибри, внедрить механизм обработки "контролируемых исключений" page_fault, вызванных в ходе обработки данных при обращении к памяти для записи/чтения .
Если разработчик ядра, драйвера или приложения желает обезопасить механизм обработки данных при обращении к памяти для записи/чтения (например, к памяти полученной от пользователя), то он может сделать следующие действия:
1.) Перед обращением к памяти, установить следующие данные для обработчика "контролируемых исключений" ядра:
- В регистр edi занести сигнатуру - текст 'EXPT'
- В регистр esi занести адрес, куда должен передать управление обработчик "контролируемых исключений".
2.) По адресу, указанном в регистре esi разработчик прописывает необходимые действия в случае получения некорректных данных.
В итоге:
1. Значительно повышается стабильность (отказоустойчивость) ядра Колибри или приложения при обработке данных.
2. Упрощается алгоритм проверки данных на их корректность.
3. Этот алгоритм могут использовать разработчики приложений без обращения к функции 68,24.
Ниже показан пример применения механизма обработки некорректных данных.
Когда нам в ядро приходят непроверенные данные от пользователя, то мы устанавливаем данные для обработчика "контролируемых исключений" (строка 5593-5594).
Теперь если произойдет исключение из-за обращениия к несуществующей памяти (в строке 5596), то исполнение кода начнется с метки .err_exit: (строка 5619) с корректным завершением обработки запроса от пользователя.
В заключение предлагаю внедрить в файл sys32.inc в процедуре page_fault_exc: код обработчика "контролируемых исключений":
Если не будет возражений или замечаний, то приблизительно через месяц я внесу код в SVN, а также внесу пояснения в справочник по функции 68,24.
Этот пост будет про обработку исключений переполнения стека
В ходе разработки эмулятора обнаружилось, что некоторые сервисы и модули Винды намеренно выделяют недостаточный размер стека при создании потока и при возникновении исключения в этом потоке (из-за переполнении стека), Винда должна на лету автоматически изменить стек на другой стек большего размера.
Ниже предлагаются варианты (алгоритмы) действий для пользователя и для ядра системы Колибри, при обработке исключений переполнения стека.
Эти предлагаемые изменения не должны конфликтовать с текущей версией обработчика исключений.
Действие пользователя
""""""""""""""""""""""""""""""""""""""
Если пользователь (приложение) желает обрабатывать исключения переполнения стека, то он должен сделать следующее:
1. Выделяет область памяти для аварийного\резервного стека с размером, достаточным для обработки данного исключения.
2. При вызове функции 68,24 передает стартовый адрес резервного стека в регистр ESI.
3. Ставит флаг 12 в маске обработки исключений в функции 68,24
4. При возникновении исключения с кодом 12 в аварийном стеке будет представлена нижеследующая инфа (см. структуру EXCEPT_STACK)
5. Обработчик приложения делает то, что нужно и при завершении обработки этого исключения сбрасывает (обнуляет) бит занятости аварийного стека. (структура EXCEPT_STACK.LockAccess)
структура EXCEPT_STACK
Алгоритм действий системы ядра Колибри
"""""""""""""""""""""""""""""""""""""""""""""""""""""
При возникновении исключения со стеком, по логике должно генерироваться исключение 12. Однако, из-за настроек (системы или процессора), при переполнении стека чаще всего генерируется исключение 14 (page fault).
У меня генерируется исключение 14 даже при явном применении команд типа push pushad со стеком.![Shocked :shock:](./images/smilies/icon_eek.gif)
Поэтому, при возникновении исключения 14, предлагаю сделать в ядре дополнительные проверки для корректного определения причины исключения.
Принцип проверки:
Перед базовым адресом стека всегда будет незанятая область памяти в 1000h и поэтому, если обращение к памяти было в пределах этого размера, то значит была попытка обратиться к несуществующей памяти стека.
Ниже предлагается:
1. Внедрить в файл sys32.inc (после метки IRetToUserHook:) код дополнительной проверки причины исключения. (см ниже)
2. Внести изменение в структуре APPDATA (добавить дополнительное поле - exc_reserve_stack) в const.inc (см ниже)
Изменение в структуре APPDATA
Код дополнительной проверки после метки IRetToUserHook:
Продолжение следует .......
В ходе разработки эмулятора обнаружилось, что некоторые сервисы и модули Винды намеренно выделяют недостаточный размер стека при создании потока и при возникновении исключения в этом потоке (из-за переполнении стека), Винда должна на лету автоматически изменить стек на другой стек большего размера.
Ниже предлагаются варианты (алгоритмы) действий для пользователя и для ядра системы Колибри, при обработке исключений переполнения стека.
Эти предлагаемые изменения не должны конфликтовать с текущей версией обработчика исключений.
Действие пользователя
""""""""""""""""""""""""""""""""""""""
Если пользователь (приложение) желает обрабатывать исключения переполнения стека, то он должен сделать следующее:
1. Выделяет область памяти для аварийного\резервного стека с размером, достаточным для обработки данного исключения.
2. При вызове функции 68,24 передает стартовый адрес резервного стека в регистр ESI.
3. Ставит флаг 12 в маске обработки исключений в функции 68,24
4. При возникновении исключения с кодом 12 в аварийном стеке будет представлена нижеследующая инфа (см. структуру EXCEPT_STACK)
5. Обработчик приложения делает то, что нужно и при завершении обработки этого исключения сбрасывает (обнуляет) бит занятости аварийного стека. (структура EXCEPT_STACK.LockAccess)
структура EXCEPT_STACK
Алгоритм действий системы ядра Колибри
"""""""""""""""""""""""""""""""""""""""""""""""""""""
При возникновении исключения со стеком, по логике должно генерироваться исключение 12. Однако, из-за настроек (системы или процессора), при переполнении стека чаще всего генерируется исключение 14 (page fault).
У меня генерируется исключение 14 даже при явном применении команд типа push pushad со стеком.
![Shocked :shock:](./images/smilies/icon_eek.gif)
Поэтому, при возникновении исключения 14, предлагаю сделать в ядре дополнительные проверки для корректного определения причины исключения.
Принцип проверки:
Перед базовым адресом стека всегда будет незанятая область памяти в 1000h и поэтому, если обращение к памяти было в пределах этого размера, то значит была попытка обратиться к несуществующей памяти стека.
Ниже предлагается:
1. Внедрить в файл sys32.inc (после метки IRetToUserHook:) код дополнительной проверки причины исключения. (см ниже)
2. Внести изменение в структуре APPDATA (добавить дополнительное поле - exc_reserve_stack) в const.inc (см ниже)
Изменение в структуре APPDATA
Код дополнительной проверки после метки IRetToUserHook:
Продолжение следует .......
Продолжение поста .......
В заключение предлагается добавить код в функцию 68,24 в файле memory.inc:
Если не будет возражений, то я планирую через месяц внести этот код в SVN, а также прописать в справочнике по функциям sysfuncr.txt у функции 68,24 дополнительную инфу по исключениям.
№№№№№№№№№№№№№
Примечание по коду проверки исключения 14
Библиотеки Винды используют два варианта увеличения стека через исключение:
1. Простое переполнение в ходе использования стека
2. Динамическое выделение области памяти в стеке размером более чем в 1000h
Ниже показан пример процедуры динамического выделения памяти в стеке в модуле dmserver.dll
Так вот, при выделения памяти в стеке размером более чем 1000h, мой код может не определить это исключение, так как разница между адресом в регистре esp и адресом в регистре cr2 может составить более 1000h.
Для 100% определения исключений в стеке, нужно дополнительно определить по адресу в ESP базовый адрес памяти стека. И уже по базе памяти стека вычислять разницу с регистром cr2.
Я пока не нашел в ядре Колибри функцию определения базы памяти по его адресу. Видимо потом придется прописывать дополнительный код.
№№№№№№№№№№№
В заключение предлагается добавить код в функцию 68,24 в файле memory.inc:
Если не будет возражений, то я планирую через месяц внести этот код в SVN, а также прописать в справочнике по функциям sysfuncr.txt у функции 68,24 дополнительную инфу по исключениям.
№№№№№№№№№№№№№
Примечание по коду проверки исключения 14
Библиотеки Винды используют два варианта увеличения стека через исключение:
1. Простое переполнение в ходе использования стека
2. Динамическое выделение области памяти в стеке размером более чем в 1000h
Ниже показан пример процедуры динамического выделения памяти в стеке в модуле dmserver.dll
Так вот, при выделения памяти в стеке размером более чем 1000h, мой код может не определить это исключение, так как разница между адресом в регистре esp и адресом в регистре cr2 может составить более 1000h.
Для 100% определения исключений в стеке, нужно дополнительно определить по адресу в ESP базовый адрес памяти стека. И уже по базе памяти стека вычислять разницу с регистром cr2.
Я пока не нашел в ядре Колибри функцию определения базы памяти по его адресу. Видимо потом придется прописывать дополнительный код.
№№№№№№№№№№№
Приветствую, Jurgen !
Интересно следить за тем, что вы делаете, спасибо за описание некоторых процессов.
Есть несколько моментов, на которые хотел бы обратить внимание:
1) Присылайте, пожалуйста, код примеров и исправлений в виде кода, а не скриншотов, т.к. не очень удобно смотреть на изменения и использовать их для сверки/проверки.
2) Также вместо написания фразы "Если не будет возражений, то я планирую через месяц внести этот код в SVN..." можете обратиться в группу Телеграм https://t.me/kolibri_os и спросить мнение там, а не только тут на форуме.
Интересно следить за тем, что вы делаете, спасибо за описание некоторых процессов.
Есть несколько моментов, на которые хотел бы обратить внимание:
1) Присылайте, пожалуйста, код примеров и исправлений в виде кода, а не скриншотов, т.к. не очень удобно смотреть на изменения и использовать их для сверки/проверки.
2) Также вместо написания фразы "Если не будет возражений, то я планирую через месяц внести этот код в SVN..." можете обратиться в группу Телеграм https://t.me/kolibri_os и спросить мнение там, а не только тут на форуме.
1. I generally agree on your design of thread priorities, why not. It would be nice to see a patch though. Same for other changes.
2.1. Maybe '*_local_priority' names are a bit too long. Something like 'niceness' is shorter and refers to POSIX.
2.2. Also, variable names starting with the words 'check' and 'set' look misleading. These words usually name functions. Please, consider using other prefixes like 'current' and 'default' or 'cur' and 'def'.
I didn't get into the other your changes yet.
You don't have to repost to telegram.
2.1. Maybe '*_local_priority' names are a bit too long. Something like 'niceness' is shorter and refers to POSIX.
2.2. Also, variable names starting with the words 'check' and 'set' look misleading. These words usually name functions. Please, consider using other prefixes like 'current' and 'default' or 'cur' and 'def'.
I didn't get into the other your changes yet.
You don't have to repost to telegram.
Здравствуйте, не могу не отметить что в так называемом "патче" виднеется использование структуры TASKDATA, что лично для меня, говорит что вы используете достаточно старую версию ядра и это неприемлемо.
Что касается внедрения новых приоритетов потоков, то возникает вопрос в необходимости этого: сейчас уже есть достаточно хорошо работающий планировщик у которого насколько помню 3-5 видов приоритета, и их вполне можно использовать для добавления регулировки приоритетов пользовательских потоков.
По поводу API хотелось бы не на словах читать, а видеть интерфейс того, как это будет выглядеть(подробное описание сисфункций НЕ в виде кода)
Ну и чисто своё мнение: Перед любым патчем проверяйте всё ли работает и всё ли после него будет нормально (хорошая аналитика должна быть), про то как надо патч оформлять уже выше писали
Что касается внедрения новых приоритетов потоков, то возникает вопрос в необходимости этого: сейчас уже есть достаточно хорошо работающий планировщик у которого насколько помню 3-5 видов приоритета, и их вполне можно использовать для добавления регулировки приоритетов пользовательских потоков.
По поводу API хотелось бы не на словах читать, а видеть интерфейс того, как это будет выглядеть(подробное описание сисфункций НЕ в виде кода)
Ну и чисто своё мнение: Перед любым патчем проверяйте всё ли работает и всё ли после него будет нормально (хорошая аналитика должна быть), про то как надо патч оформлять уже выше писали
1) Если вам так будет удобнее и другие не против, то могу вместо скриншотов постить измененный файл с кодом - и мне так будет проще.XenOn wrote: ↑Wed Feb 21, 2024 9:40 pm Приветствую, Jurgen !
Интересно следить за тем, что вы делаете, спасибо за описание некоторых процессов.
Есть несколько моментов, на которые хотел бы обратить внимание:
1) Присылайте, пожалуйста, код примеров и исправлений в виде кода, а не скриншотов, т.к. не очень удобно смотреть на изменения и использовать их для сверки/проверки.
2) Также вместо написания фразы "Если не будет возражений, то я планирую через месяц внести этот код в SVN..." можете обратиться в группу Телеграм https://t.me/kolibri_os и спросить мнение там, а не только тут на форуме.
Позже выложу здесь все измененные файлы ядра.
2) По поводу телеги - в моем регионе заблокирована регистрация по телефону в телеге.
Если не ошибаюсь, http://board.kolibrios.org является самой главной площадкой для сообщений.
Поэтому мной и назначен срок в один месяц, чтобы заинтересованное лицо (посещающий другие форумы, телегу и прочие сервисы) имел возможность в удобное ему дату и время посетить форумы по ядру Колибри, ознакомиться, в том числе и с моими сообщениями и, при желании, оставить здесь сообщение (пожелание, замечание, возражение) до правки ядра Колибри.
1. Later I will post all the changed kernel files here.dunkaist wrote: ↑Thu Feb 22, 2024 5:17 am 1. I generally agree on your design of thread priorities, why not. It would be nice to see a patch though. Same for other changes.
2.1. Maybe '*_local_priority' names are a bit too long. Something like 'niceness' is shorter and refers to POSIX.
2.2. Also, variable names starting with the words 'check' and 'set' look misleading. These words usually name functions. Please, consider using other prefixes like 'current' and 'default' or 'cur' and 'def'.
I didn't get into the other your changes yet.
You don't have to repost to telegram.
2.1. For aesthetics, I can shorten it. I added a "local" to different between global kernel priorities and application local thread priorities.
2.2. Ok
Интересненько. Ранее, в 2021 году я скачал ядро Колибри версии 0.7.7.0 себе, чтобы делать необходимые изменения в ядре для обеспечения работы эмулятора.
Теперь структура TASKDATA оказыватся перенесена в файлы kernel32.inc.
Поисковик нашел у меня несколько местоположений kernel32.inc (не считая branches):
kolibrios.org\kernel\tags\kolibri0.6.0.0
kolibrios.org\kernel\tags\kolibri0.6.3.0
kolibrios.org\kernel\tags\kolibri0.6.5.0
kolibrios.org\kernel\tags\kolibri0.7.0.0
kolibrios.org\kernel\tags\kolibri0.7.5.0
kolibrios.org\kernel\tags\kolibri0.7.7.0
Не будем задавать вопрос, зачем убрали файл const.inc со структурой TASKDATA, у инициаторов наверно были свои резоны. Однако теперь возникает другой вопрос:
Чтобы эмулятор работал у любого пользователя со стандартной Колибри (независимо от версии), в частности по приоритетам потоков, нужно ли менять структуру TASKDATA только в одном kernel32.inc (в папке kolibri0.7.7.0) или во всех вышеуказанных папках?
Согласно сообщению CleverMouse (см. выше первый пост) в ядре Колибри только три глобальных приоритета потоковDoczom wrote: ↑Thu Feb 22, 2024 6:02 am ....
Что касается внедрения новых приоритетов потоков, то возникает вопрос в необходимости этого: сейчас уже есть достаточно хорошо работающий планировщик у которого насколько помню 3-5 видов приоритета, и их вполне можно использовать для добавления регулировки приоритетов пользовательских потоков.
....
1. Потоки работающие напрямую с железом (устройствами) периферии компа
2. Пользовательские потоки
3. Спящий режим
И вы не можете влиять извне ядра на логику этих приоритетов
Здесь предлагается внедрение системы приоритетов только для пользовательских потоков.
В небольших проектах до 50-ти потоков, нет смысла заморачиваться какими-то приоритетами потоков.
Однако, если проект предусматривает запуск несколько сотен или тысяч пользовательских потоков, то приоритеты этих потоков имеют значение для эффективной работы приложения в целом.
У меня в посте по потокам и написано:
Заранее писать справку по интерфейсу, до согласованной правки ядра Колибри, считаю не разумным.Если не будет возражений или замечаний то, приблизительно через месяц, я внесу код в SVN и пояснения в справочник по функциям 51,2 - 51,4
До публикаций всех предложений по изменению ядра Колибри, эти изменения уже внесены в ядро Колибри и уже работают у меня - иначе не будет работать эмулятор.
Про публикацию изменений пожалуй не буду высказываться, это выскажут и без меня
Структура TASKDATA не просто перенесена, а удалена полностью и безвозвратно(удалял я - читайте другие темя форума). Чтобы не возникало такого следует использовать или git или svn репозиторий, который периодически надо сверять с основным репозиторием проекта. Ядро хоть и не каждый день, но раз в месяц изменения точно происходят и они могут у вас всё сломать (ещё раз призываю вас обратить внимание на использование системной функции 18.11, которую не стоит использовать).
Касательно этого я уже сказал, можно расширить уже существующую систему потоков без внедрения дополнительных усложнений, так как количество колец приоритетов потоков почти не ограничено сложностями, а написать api для этого всегда можно. Ну и небольшой совет - прежде чем лезть в ядро(и уж точно в систему потоков), ознакомьтесь как она работает сейчас по взаимодействию с другими подсистемами и почему число потоков ограничено и это ограничение невозможно снять без изменения половины ядра.Jurgen wrote: ↑Fri Feb 23, 2024 8:38 pm
Согласно сообщению CleverMouse (см. выше первый пост) в ядре Колибри только три глобальных приоритета потоков
1. Потоки работающие напрямую с железом (устройствами) периферии компа
2. Пользовательские потоки
3. Спящий режим
И вы не можете влиять извне ядра на логику этих приоритетов
Здесь предлагается внедрение системы приоритетов только для пользовательских потоков.
В небольших проектах до 50-ти потоков, нет смысла заморачиваться какими-то приоритетами потоков.
Однако, если проект предусматривает запуск несколько сотен или тысяч пользовательских потоков, то приоритеты этих потоков имеют значение для эффективной работы приложения в целом.
А я считаю это то что должно быть, чтобы избежать лишних обсуждений и изменений этого самого api после того, как оно окажется на сервере
Ваш эмулятор не является полной проверкой всего функционала ядра, а учитывая то, что потоки влияют почти на всё, надо проверять всё и по отдельности. И сеть, и окна, и работу с файлами, и даже банально драйвера.
Увы, У меня нет времени на ф. 18.11. У меня только две руки, одна голова и другие более важные дела.Doczom wrote: ↑Fri Feb 23, 2024 10:00 pm ...
Структура TASKDATA не просто перенесена, а удалена полностью и безвозвратно(удалял я - читайте другие темя форума). Чтобы не возникало такого следует использовать или git или svn репозиторий, который периодически надо сверять с основным репозиторием проекта. Ядро хоть и не каждый день, но раз в месяц изменения точно происходят и они могут у вас всё сломать (ещё раз призываю вас обратить внимание на использование системной функции 18.11, которую не стоит использовать).
Вы можете лично помочь убрать у эмулятора применение функции 18.11 - там вам только надо понять логику и принципы хранения данных от функции 18.11 и переписать код применения функции 18.11 на применение функции 70.5 и выложить здесь итоговый код.
Сделаете доброе дело - будут довольны все.
![Smile :)](./images/smilies/icon_smile.gif)
Также хочу выразить свое мнение по поводу TASKDATA
Вы правильно сделали, что провели работу по оптимизации и унификации стуктур в ядре, убрав лишние структуры. В результате упростился анализ кода в ядре Колибри.
Отличная работа!
![Smile :)](./images/smilies/icon_smile.gif)
Винда и приложения для Винды используют функции для управления приоритетами своих потоков - SetThreadPriority и GetThreadPriority.Doczom wrote: ↑Fri Feb 23, 2024 10:00 pm Касательно этого я уже сказал, можно расширить уже существующую систему потоков без внедрения дополнительных усложнений, так как количество колец приоритетов потоков почти не ограничено сложностями, а написать api для этого всегда можно. Ну и небольшой совет - прежде чем лезть в ядро(и уж точно в систему потоков), ознакомьтесь как она работает сейчас по взаимодействию с другими подсистемами и почему число потоков ограничено и это ограничение невозможно снять без изменения половины ядра.
Предложен вариант кода для поддержки ядром Колибри вышеназванных функции Винды, который у меня в ядре Колибри работает.
Вы считаете что можно сделать лучше или по другому? Замечательно!
![Very Happy :D](./images/smilies/icon_biggrin.gif)
Выложите здесь для обсуждения свой вариант кода, поддерживающий вышеназванные функции Винды.
Если ваш вариант окажется лучше - можете удалять мой код. Я не расстроюсь - мне будет меньше работы, которая не оплачивается...
![Smile :)](./images/smilies/icon_smile.gif)
Мне известно про ограничение числа потоков.
Когда эмулятор столкнется с этой проблемой, то придется и его решать.
А еще, для работы эмулятора, придется решать проблему поддержки ядром Колибри мультипроцессорности.
И еще вдобавок - решать проблему поддержки ядром Колибри режима совместимости с 64 бит.
А я считаю, что не нужно делать, пока не внесен в ядро итоговый интерфейс функций.
Вот и проверим....
![Very Happy :D](./images/smilies/icon_biggrin.gif)
У меня ядро Колибри и приложения к нему работают.
Если что, всегда можно откатить изменения.
Как и обещал ранее - Выкладываю ниже файлы ядра с иправлениями (в скобках - номер строки).
1) Режим "контролируемого исключения":
sys32 (118), kernel (4312) , const (597)
2) Обработка исключений стека:
const (514), sys32 (237), memory (1180), taskman (31)
3) Приоритеты потоков:
sсhed (311), taskman (1011), const (531), kernel (4285)
Прошу обратить внимание:
1.) По режиму "контролируемого исключения" сделан второй вариант без применения регистров ESI EDI. Во втором варианте применен стек.
Также в ядре добавлена проверка адреса возврата от юзера из пользовательского режима.
Напишите мне, какой вариант применения "контролируемого исключения" вам предпочтительнее - с применением регистров или с применением стека?
2.) По ф.51,2-51,4 изменено применение типа идентификатора потока для определения\установки приоритета потока, так как для эмулятора выбор типа идентификатора потока имеет критическую значимость!
Пример:
а) Приложение Винды создает 10 потоков.
б) Еще один поток постоянно создается\удаляется в бесконечном цикле.
Так как tid монотонно растет, то, через некоторое время, в системе появятся клоны потоков с одинаковым tid для первых 10-ти потоков!
Исходя из примера выше, логичнее чтобы tid был номером слота потока\процесса или tid = номер слота.
Наверно ранее, этот tid был внедрен разработчиками ядра для идентификации пакетов данных.
Однако, логичнее идентификацию пакетов данных делать комбинацией из номера слота и уникального имени (метки) пакета данных и, перед освобождением памяти с пакетом данных, удалить имя (метку) этого пакета.
Ниже предлагается сделать изменения связанные с tid, котоые не критичны для работы эмулятора (но упрощают алгоритм), поэтому на ваше усмотрение:
Чтобы не было конфликтов у приложений с изменением в ядре Колибри, предлагается сделать изменение логики одновременно в следующих функциях:
1. В ф. 9 в поле pid\tid - возврат номера слота, а не номера идентификатора.
2. В ф. 51,1 - возврат номера слота потока, а не номера идентификатора.
3. В ф. 18,18 - завершение процесс/поток по номеру слота, а не по номеру идентификатора
4. В ф. 18,21 - возврат номера слота вместо номера идентификатора
Если вы сообщите мне о согласии на эти изменения, то я займусь этим и выложу здесь правки в ядре у этих функций для обсуждения.
1) Режим "контролируемого исключения":
sys32 (118), kernel (4312) , const (597)
2) Обработка исключений стека:
const (514), sys32 (237), memory (1180), taskman (31)
3) Приоритеты потоков:
sсhed (311), taskman (1011), const (531), kernel (4285)
Прошу обратить внимание:
1.) По режиму "контролируемого исключения" сделан второй вариант без применения регистров ESI EDI. Во втором варианте применен стек.
Также в ядре добавлена проверка адреса возврата от юзера из пользовательского режима.
Напишите мне, какой вариант применения "контролируемого исключения" вам предпочтительнее - с применением регистров или с применением стека?
2.) По ф.51,2-51,4 изменено применение типа идентификатора потока для определения\установки приоритета потока, так как для эмулятора выбор типа идентификатора потока имеет критическую значимость!
![Exclamation :!:](./images/smilies/icon_exclaim.gif)
Пример:
а) Приложение Винды создает 10 потоков.
б) Еще один поток постоянно создается\удаляется в бесконечном цикле.
Так как tid монотонно растет, то, через некоторое время, в системе появятся клоны потоков с одинаковым tid для первых 10-ти потоков!
Исходя из примера выше, логичнее чтобы tid был номером слота потока\процесса или tid = номер слота.
Наверно ранее, этот tid был внедрен разработчиками ядра для идентификации пакетов данных.
Однако, логичнее идентификацию пакетов данных делать комбинацией из номера слота и уникального имени (метки) пакета данных и, перед освобождением памяти с пакетом данных, удалить имя (метку) этого пакета.
Ниже предлагается сделать изменения связанные с tid, котоые не критичны для работы эмулятора (но упрощают алгоритм), поэтому на ваше усмотрение:
Чтобы не было конфликтов у приложений с изменением в ядре Колибри, предлагается сделать изменение логики одновременно в следующих функциях:
1. В ф. 9 в поле pid\tid - возврат номера слота, а не номера идентификатора.
2. В ф. 51,1 - возврат номера слота потока, а не номера идентификатора.
3. В ф. 18,18 - завершение процесс/поток по номеру слота, а не по номеру идентификатора
4. В ф. 18,21 - возврат номера слота вместо номера идентификатора
Если вы сообщите мне о согласии на эти изменения, то я займусь этим и выложу здесь правки в ядре у этих функций для обсуждения.
Sockets were broken in 9976 revision. Open webview and try to open some site e.g. kolibrios.org. In 9975 it works ok, in 9976 it does not work. Please check whether all works good before commiting something.
The best way to predict the future is to create it.
Извините, но у меня тоже есть более важные дела и задачи даже в рамках Колибри, и денег я с этого проекта не получаю, а только трачу. Так что я просто в какой-то момент удалю эту системную функцию и всё, предупреждение весит уже давно(если по форуму глянуть её должны были удалить ещё 10 лет назад).
мда, очень хороший патч, а "удобный" то какой
Ну и зачем это? если поток постоянно создаётся и удаляется, то это по мне так ошибка проектирования программы с этим потоком а не системы. Что касается TID, то его спокойно хватит на примерно 5-10 дней постоянного запуска и завершения потоков(проверял это примерно год назад), причём система всё это время будет грузить процессор на 100%. То что переполнение этого счётчика возможно известно давно, но оно исправляется добавлением проверки существования потока с таким tid.
Я категорически против данных изменений, это СЛОМАЕТ МНОГИЕ МЕХАНИЗМЫ ЯДРА . Номер слота не является уникальным объектом для чёткого определения потока, из за чего может произойти ошибка при отправке сообщений(в том числе и событий) между потоками.Jurgen wrote: ↑Sat Mar 02, 2024 9:30 pm
Ниже предлагается сделать изменения связанные с tid, котоые не критичны для работы эмулятора (но упрощают алгоритм), поэтому на ваше усмотрение:
Чтобы не было конфликтов у приложений с изменением в ядре Колибри, предлагается сделать изменение логики одновременно в следующих функциях:
1. В ф. 9 в поле pid\tid - возврат номера слота, а не номера идентификатора.
2. В ф. 51,1 - возврат номера слота потока, а не номера идентификатора.
3. В ф. 18,18 - завершение процесс/поток по номеру слота, а не по номеру идентификатора
4. В ф. 18,21 - возврат номера слота вместо номера идентификатора
Если вы сообщите мне о согласии на эти изменения, то я займусь этим и выложу здесь правки в ядре у этих функций для обсуждения.
Пример возможной ошибки:
Поток 1 занимает слот 7
Поток 1 завершается, слот 7 освобождается
Создаётся поток 2, он занимает слот 7
Поток 3 отправляет сообщение потоку 1(на слот 7)
Сообщение от потока 3 получает поток 2 (это уже является ошибкой).
Tid хоть и не даёт гарантии о том что одновременно не будет существовать 2 объекта, но он позволяет точно идентифицировать поток получатель сообщения. Кроме этого за счёт этого идентификатора работает логика сетевого стека, проверяющая как минимум существование потока-получателя. tid также используется и в других частях ядра(система отладки, система библиотек, система объектов ядра, много где для семофоров, система курсоров и тд).
Изменение на ненадёжный номер слота приведёт к поломке всей системы, так что я против и в случае если такой патч будет заливаться на сервер, я буду его откатывать.
Who is online
Users browsing this forum: Bing [Bot] and 1 guest