Linux Kernel (Ядро линукса) (часть 1)


Поиск области, пересекающейся с данным интервалом: функция find_vma_intersection

Функция find_vma_intersection ищет первую область памяти, которая пересекается с данным интервалом линейных адресов. Параметр mm указывает
на дескриптор памяти процесса, а линейные адреса start addr и end addr задают интервал:vma = find_vma (mm, start_addr) ; if (vma && end_addr vm_start) vma = NULL; return vma;
Если область не будет найдена, функция возвратит указатель null. Точнее говоря, если функция f ind vma () возвратила корректный адрес, но найденная область памяти начинается после окончания интервала линейных адресов, переменная vma получает значение null.
Поиск свободного интервала: функция get_unmapped__area
Функция get unmapped area просматривает адресное пространство процесса с целью найти свободный интервал линейных адресов. Параметр len задает длину интервала, а ненулевой параметр addr, когда он не равен 0, указывает адрес, с которого должен начаться поиск. Если поиск увенчается успехом, функция возвратит начальный адрес нового интервала; в противном случае КОД ошибки -ENOMEM.

Проверив, что параметр addr не равен null, функция убеждается, что указанный адрес находится в адресном пространстве режима пользователя и что он выровнен по границе страницы. Затем она вызывает один из двух методов, в зависимости от цели использования интервала адресов: для отображения файла в память или для анонимного отображения. В первом случае функция выполняет файловую операцию get unmapped area
Во втором случае функция выполняет метод get unmapped area дескриптора памяти. Этот метод реализован либо функцией arch_get_unmapped_area , либо arch get unmapped area topdown , В соответствии СО схемой области памяти. у любого процесса может быть две разных схемы расположения областей памяти, выделенных системным вызовом mmap : либо они начинаются с линейного адреса 0x40000000 и растут вверх, либо они начинаются выше стека режима пользователя и растут в направлении меньших адресов.

Рассмотрим функцию arch get unmapped area , которая используется, когда области памяти выделяются в направлении от нижних адресов к верхним. Она эквивалентна следующему фрагменту кода:
if (len > TASK_SIZE) return -ENOMEM;
addr = (addr + Oxfff) & OxfffffOOO; if (addr && addr + len mm, addr); if (!vma I I addr + len vm_start) return addr;}
start_addr = addr = mm->free_area_cache;
for (vma = find_vma (current->mm, addr); ; vma = vma->vm_next) { if (addr + len > TASK_SIZE) {if (start_addr == (TASK_SIZE/3+0xfff)&0xfffff000) return -ENOMEM; start_addr = addr = (TASK_SIZE/3+0xfff)&0xfffffOOO; vma = find_vma (current->mm, addr);}
if (!vma I I addr + len vm_start) { mm->free_area_cache = addr + len; return addr;}
addr = vma-> vm_end;}
Функция начинается с проверки, не превышает ли длина интервала число task size, являющееся максимальным значением для линейных адресов режима пользователя (как правило, 3 Гбайт). Если значение addr отлично от нуля, функция пытается выделить интервал, начиная с адреса addr. На всякий случай, функция округляет значение addr до числа, кратного 4 Кбайт.

Если параметр addr равен О, или предыдущий поиск закончился неудачей, функция arch get unmapped area просматривает пространство линейных адресов режима пользователя в поисках диапазона линейных адресов, не входящего ни в одну область памяти и достаточно большого, чтобы содержать новую область. Для ускорения поиска его начальная точка обычно устанавливается на линейный адрес, следующий за последней выделенной областью памяти. Поле mm->free_area_cache дескриптора памяти инициализируется значением, равным одной трети от пространства линейных адресов режима пользователя (как правило, 1 Гбайт), а затем обновляется по мере создания новых областей памяти. Если функции не удается найти подходящий интервал линейных адресов, поиск возобновляется с начала, т. е. с одной трети пространства линейных адресов режима пользователя. Дело в том, что первая треть этого пространства зарезервирована под области памяти с предопределенными линейными адресами; обычно туда входят текст, данные и bss-сегменты исполняемого файла Функция вызывает функцию f ind vma для обнаружения первой области памяти, которая заканчивается после начальной точки поиска. Затем она повторно просматривает все последующие области памяти.

Здесь возможны три случая:

- запрошенный интервал больше, чем еще не просмотренная часть пространства линейных адресов (addr + len > task size). Тогда функция либо возобновляет поиск с одной трети адресного пространства режима пользователя, либо, если повторный поиск уже производился, возвращает -enomem (недостаточно линейных адресов для удовлетворения запроса);
- свободного места за последней просмотренной областью не хватает
(vma ! = null && vma->vm_start mm_rb, в которую должен быть вставлен объект vma. Затем функция insert vm struct о вызывает функцию vma_link, КОТО- рая выполняет следующие действия:
1. Заносит область памяти в связный список, на который указывает поле
mm->mmap.
2. Заносит область памяти в красно-черное дерево mm->mm_rb.
3. Если область памяти является анонимной, функция заносит область в список, голова которого находится в соответствующей структуре anon vma
4. Увеличивает СЧеТЧИК mm->map_count.
Если область содержит файл, отображенный в память, функция vma iinko выполняет дополнительные операции
Функция vma uniinko принимает в качестве параметров адрес дескриптора памяти mm и два адреса объектов-областей памяти — vma и prev. Обе области памяти должны принадлежать дескриптору mm, и область prev должна предшествовать области vma. Функция удаляет объект vma из списка и красно-черного дерева дескриптора памяти. Она также обновляет поле
mm->mmap_cache, содержащее адрес области памяти, к которой процесс обращался последний раз, если это поле указывает на только что удаленную область.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть...

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...