Добавил в ядро функции для работы с мьютексами. Реализация взята из Linux, ABI gcc fastcall.
void __attribute__ ((fastcall)) mutex_init(struct mutex*);
void __attribute__ ((fastcall)) mutex_lock(struct mutex*);
void __attribute__ ((fastcall)) mutex_unlock(struct mutex*);
структура MUTEX определена в kernel32.inc.
Прежде чем использовать мьютекс его обязательно следует инициализировать вызовом mutex_init и только вызовом mutex_init.
Только один поток может захватывать мьютекс.
Множественные блокировки не допускаются.
Нельзя использовать мьютексы в обработчиках прерываний.
Новая модель ядра
Ядро сейчас целиком влезает в первую 4Мб-страницу, но в init.inc до сих пор висит код дозагрузки "хвоста" в PSE-режиме:
насколько я понимаю, этот рудимент остался от более рыхлой модели памяти, когда sys_pgmap лежала за пределами 4Mb:
Code: Select all
mov eax, 0x400000+PG_SW
mov ecx, [tmp_page_tabs] ;) однако [tmp_page_tabs] < 4M
sub ecx, 0x400000 ;) отрицательное
shr ecx, 12 ;( а теперь еще и знак потерялся
jmp .map_low
.no_PSE:
mov eax, PG_SW
mov ecx, [tmp_page_tabs]
shr ecx, 12
.map_low:
mov edi, [tmp_page_tabs]
@@: ; заносим в таблицу хз сколько ненужных страниц
stosd
add eax, 0x1000
dec ecx
jnz @B
попробовал фиксануть #1451 - у меня вроде работает. Следите за глюкамиdiamond wrote:начальный кусок системных адресов [OS_BASE, OS_BASE + a), где OS_BASE = 0x80000000 (const.inc), маппится на начало физической памяти [0,a) "почти тривиально" - вычитанием OS_BASE; в этот кусок входит само ядро и все системные таблицы (точный список в memmap.inc); длина куска a = 0x47F000 + (некоторая память для таблицы страниц, размер которой зависит от размера имеющейся памяти). Если процессор поддерживает страницы по 4 Мб (page-size extensions), то первые 4 Мб маппятся одной страницей...
Евангелие от Иоанна: стих 1[/size]
Code: Select all
; В начале было Слово:
B32: mov ax, os_stack ; Selector for os
art_zh
Да, ядро сильно ужалось. Ветку .no_PSE: можно выкинуть, на таких процессорах Колибри не работает.
Да, ядро сильно ужалось. Ветку .no_PSE: можно выкинуть, на таких процессорах Колибри не работает.
Я никак не могу разобраться зачем ядру маппинг пустой зоны до HEAP_BASE - ради одного только tss?
Кстати, tss надо бы тоже внести в "большую" страницу: если верить fast_call_test, системные вызовы через int40 в ядре #1451 стали грузиться в полтора раза дольше. На sysenter/syscall вызовах переделка init.inc никак не сказалась.
Кстати, tss надо бы тоже внести в "большую" страницу: если верить fast_call_test, системные вызовы через int40 в ядре #1451 стали грузиться в полтора раза дольше. На sysenter/syscall вызовах переделка init.inc никак не сказалась.
Евангелие от Иоанна: стих 1[/size]
Code: Select all
; В начале было Слово:
B32: mov ax, os_stack ; Selector for os
art_zh
tss нельзя, в крайнем случае в самый хвост большой страницы,
или пометить страницу как глобальную. За tss идут две copy-on-write страницы с картой ввода вывода.
В полтора раза дольше по сравнению с чем ? tss при быстрых вызовах не используется. Так что врядли это связано с ним.
tss нельзя, в крайнем случае в самый хвост большой страницы,
или пометить страницу как глобальную. За tss идут две copy-on-write страницы с картой ввода вывода.
В полтора раза дольше по сравнению с чем ? tss при быстрых вызовах не используется. Так что врядли это связано с ним.
в полтора раза дольше по сравнению с предыдущей версией.
tss используется при вызове через int40, и судя по сумасшедшей скорости вызова (почти также быстро как sysenter/sysexit) раньше постоянно сидела в кеше.
Теперь вызов int40 на моей керосинке занимает 330 тыс тактов вместо 200тыс раньше.
Время вызовов через sysenter и syscall заметно не изменилось (~200тыс тактов).
tss используется при вызове через int40, и судя по сумасшедшей скорости вызова (почти также быстро как sysenter/sysexit) раньше постоянно сидела в кеше.
Теперь вызов int40 на моей керосинке занимает 330 тыс тактов вместо 200тыс раньше.
Время вызовов через sysenter и syscall заметно не изменилось (~200тыс тактов).
art_zh
Странно.
Странно.
oops!
Оказывается на svn://programs/develop/fast_call_test лежит с пустыми циклами (реальные вызовы закомментированы)
сегодня прогнал заново - всё как доктор прописал:
SYSENTER - в среднем 180 тактов на вызов,
SYSCALL ~140 тактов
INT40 около 250.
Новый init.inc (без цикла .noPSE) залил на SVN
Оказывается на svn://programs/develop/fast_call_test лежит с пустыми циклами (реальные вызовы закомментированы)
сегодня прогнал заново - всё как доктор прописал:
SYSENTER - в среднем 180 тактов на вызов,
SYSCALL ~140 тактов
INT40 около 250.
Новый init.inc (без цикла .noPSE) залил на SVN
Евангелие от Иоанна: стих 1[/size]
Code: Select all
; В начале было Слово:
B32: mov ax, os_stack ; Selector for os
А что это за изменения в svn.1454? Цикл в init_page_map вообще-то помечает свободные/занятые физические страницы, а статические физические адреса - это всё до sys_pgmap плюс некоторое количество памяти после (причём, как мне показалось, суммарное количество может и перевалить за 4M - почему я и поставил безопасное значение 0x5FFFF80 для TSS в фиксе svn.1310... хотя, может быть, просто показалось).
И насчёт PSE... DosBox с подходящими настройками может загрузить Колибри, но понятия не имеет про большие страницы. Оно, конечно, понятно, что это явно нецелевое использование dosbox (как следует прямо из названия) и т.д. и т.п., но разве несколько строчек, обрабатывающих случай отсутствия PSE, чем-то мешают?
И насчёт PSE... DosBox с подходящими настройками может загрузить Колибри, но понятия не имеет про большие страницы. Оно, конечно, понятно, что это явно нецелевое использование dosbox (как следует прямо из названия) и т.д. и т.п., но разве несколько строчек, обрабатывающих случай отсутствия PSE, чем-то мешают?
Ушёл к умным, знающим и культурным людям.
diamond
Верхняя граница таблицы страниц (адрес "а") сейчас не определена и действительно может (и будет) вываливаться за линию 4Мб.
ИМХО включение неиспользуемого при инициализации диапазона [a, 4M) в список свободных страниц приводит к ненужному кроссмаппингу и разрыву логически цельной системной области. "Почти тривиальное" страничное преобразование адресов при этом не просто ломается выше "а" - его вообще не существует ни для одной 4К-страницы.
Это, конечно, не смертельно. Только зачем усложнять, когда можно упростить?
Насчет PSE: теперь буду знать что хоть где-то она нужна. Верну назад.
Верхняя граница таблицы страниц (адрес "а") сейчас не определена и действительно может (и будет) вываливаться за линию 4Мб.
ИМХО включение неиспользуемого при инициализации диапазона [a, 4M) в список свободных страниц приводит к ненужному кроссмаппингу и разрыву логически цельной системной области. "Почти тривиальное" страничное преобразование адресов при этом не просто ломается выше "а" - его вообще не существует ни для одной 4К-страницы.
Это, конечно, не смертельно. Только зачем усложнять, когда можно упростить?
Насчет PSE: теперь буду знать что хоть где-то она нужна. Верну назад.
Евангелие от Иоанна: стих 1[/size]
Code: Select all
; В начале было Слово:
B32: mov ax, os_stack ; Selector for os
Подниму тему.
Сейчас окно получает сообщения от мыши независимо от того активно, оно или нет. Это приводит к тому, что окна спамятся потоком ненужных событий. Я предлагаю добавить к маске событий один бит, чтобы окно получало события от мыши только в активном состоянии. Это не повлияет на работу уже существующих программ, новые смогут включать фильтрацию мыши.
Сейчас окно получает сообщения от мыши независимо от того активно, оно или нет. Это приводит к тому, что окна спамятся потоком ненужных событий. Я предлагаю добавить к маске событий один бит, чтобы окно получало события от мыши только в активном состоянии. Это не повлияет на работу уже существующих программ, новые смогут включать фильтрацию мыши.
So you mean a new bit wich can be set using function 40, wich the application can use to receive mouse events only when the window is active?Serge wrote:Подниму тему.
Сейчас окно получает сообщения от мыши независимо от того активно, оно или нет. Это приводит к тому, что окна спамятся потоком ненужных событий. Я предлагаю добавить к маске событий один бит, чтобы окно получало события от мыши только в активном состоянии. Это не повлияет на работу уже существующих программ, новые смогут включать фильтрацию мыши.
I like it, go for it.
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction." Albert Einstein
За.
Только надо будет потихоньку все старые приложения тоже переделать, чтоб не дергались.
Только надо будет потихоньку все старые приложения тоже переделать, чтоб не дергались.
Не все приложения нужно переделывать - некоторым нужна постоянная обработка событий мыши. В целом идею поддерживаю.
Новая функция 68.26
Предварительное описание.
eax=68
ebx=26
ecx= адрес блока, созданного ф. 68.12
edx= смещение от начала блока
esi = размер освобождаемой области в байтах
Функция выравнивает смещение на начало страницы и округляет размер до величины кратной размеру страницы.
Существующие функции heap_alloc(68.12) heap_free(68.13) heap_realloc(68.20) используют примитивный алгоритм управления виртуальной памятью приложения и не предназначены для активного использования. heap_unmap(68.26) возвращает ядру неиспользуемые страницы памяти, не удаляя блок созданный heap_alloc(). Сами страницы помечаются как зарезервированные и снова выделяются ядром при первом обращении к ним. Таким образом heap_unmap(68.26) позволяет организовать гибкое управление виртуальной памятью средствами приложения.
Возможен другой вариант реализации, когда функция будет освобождать любую страницу в пределах адресного пространства приложения.
Предварительное описание.
eax=68
ebx=26
ecx= адрес блока, созданного ф. 68.12
edx= смещение от начала блока
esi = размер освобождаемой области в байтах
Функция выравнивает смещение на начало страницы и округляет размер до величины кратной размеру страницы.
Существующие функции heap_alloc(68.12) heap_free(68.13) heap_realloc(68.20) используют примитивный алгоритм управления виртуальной памятью приложения и не предназначены для активного использования. heap_unmap(68.26) возвращает ядру неиспользуемые страницы памяти, не удаляя блок созданный heap_alloc(). Сами страницы помечаются как зарезервированные и снова выделяются ядром при первом обращении к ним. Таким образом heap_unmap(68.26) позволяет организовать гибкое управление виртуальной памятью средствами приложения.
Возможен другой вариант реализации, когда функция будет освобождать любую страницу в пределах адресного пространства приложения.
Who is online
Users browsing this forum: No registered users and 1 guest