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


Выделение блока

Функция rmqueue служит для поиска свободного блока в зоне. Она принимает два аргумента: адрес дескриптора зоны и order, двоичный логарифм
размера запрошенного блока свободных страниц (0 для блока из одной страницы, для двухстраничного блока и т. д.). Если выделение страничных кадров прошло удачно, функция rmqueueo возвращает адрес дескриптора страницы, соответствующего первому выделенному страничному кадру. В противном случае функция возвращает null.

Функция rmqueue предполагает, что возвращающая ее функция уже отключила локальные прерывания и получила спин-блокировку zone->iock, защищающую структуры buddy-системы. Функция в цикле перебирает элементы каждого списка в поисках свободного блока (то есть элемента, который бы не указывал сам на себя), начиная со списка, имеющего порядок order, и переходя к спискам большего порядка в случае необходимости:
struct free_area area; unsigned int current_order;
for (current_order=order; current_orderfree_area + current_order; if (!list_empty(&area->free_list)) goto block_found;
}
return NULL;
Если цикл завершается естественно, значит, свободный блок не был найден, и функция rmqueue возвращает значение null. В противном случае был
найден подходящий свободный блок, и тогда дескриптор его первого страничного кадра удаляется из списка, а значение поля free pages дескриптора зоны уменьшается:
block_found:
page = list_entry(area->free_list.next, struct page, lru); list_del(&page->lru);
ClearPagePrivate(page); page->private = 0; area->nr_free—;
zone->free_pages -= 1UL « order;
Если найденный блок содержится в списке, порядок которого curr order больше запрошенного порядка order, выполняется цикл while. Смысл этих строчек кода таков: когда необходимо воспользоваться блоком из 2к страничных кадров для удовлетворения запроса на 2Л страничных кадров (h order) { area—; curr_order—; size »= 1; buddy = page + size;
/ insert buddy as first element in the list / list_add(&buddy->lru, &area->free_list); area->nr_free++; buddy->private = curr_order;
SetPagePrivate(buddy);}
return page;
Найдя подходящий свободный блок, функция rmqueue возвращает адрес раде дескриптора страницы, ассоциированного с первым выделенным страничным кадром.

Предыдущая страница | 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...