Может ли кто-нибудь объяснить этот код?Linux: свободная память
page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1);
page_to_pfn() уже возвращает page_idx, так что делает '&' использовать для? Или page_to_pfn() вернуть что-то еще?
Может ли кто-нибудь объяснить этот код?Linux: свободная память
page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1);
page_to_pfn() уже возвращает page_idx, так что делает '&' использовать для? Или page_to_pfn() вернуть что-то еще?
Вы должны знать, что x & ((1 << n) - 1)
- это трюк, означающий x % ((int) pow(2, n))
. Часто это быстрее (но лучше оставить такие оптимизации для компилятора).
Таким образом, в этом случае это делает по модулю pow(2, MAX_ORDER)
. Это вызывает обертку; если page_idx больше pow(2, MAX_ORDER)
будет вернуться к 0. Здесь эквивалентно, но более читаемый код:
const int MAX_ORDER_N = (int) pow(2, MAX_ORDER);
page_idx = page_to_pfn(page);
/* wraparound */
while (page_idx > MAX_ORDER_N) {
page_idx -= MAX_ORDER_N;
}
Это битовая маска, которая гарантирует, что page_idx не превышает определенное значение (2^MAX_ORDER).
# define MAX_ORDER (8)
(1 << MAX_ORDER) /* 100000000 */
- 1 /* flip bits, same as ~(…) due to two-complement: 11111111 */
Так у вас есть только восемь младших бит влево
1010010101001
& 0000011111111
= 0000010101001
Но почему page_idx не может превышать 2^MAX_ORDER? Что это значит для системы друзей? – tolearn
Он не может превышать 2^MAX_ORDER, потому что применяется битовая маска и очищает все биты, превышающие это. – knittl
Я имею в виду, почему система друзей должна ограничивать page_idx в 2^MAX_ORDER. – tolearn
Но почему система дружище нужно обернуть вокруг? Более того, как этот код может вернуть правильный номер кадра страницы? Я имею в виду, page_to_pfn() вернули правильный, и последующее обертывание превратится в неправильное. – tolearn