Возвращают 0 при успешном завершении или -1 при ошибке
Системный вызов mlockall() блокирует все страницы в виртуальном адресном пространстве процесса, уже отображенные или являющиеся таковыми в будущем — это зависит от битовой маски flags, в которой побитовое ИЛИ применяется к одной или нескольким константам, представленным ниже.
• MCL_CURRENT — блокирует все страницы, отображенные на виртуальное адресное пространство процесса. Это относится к страницам, выделенным для отображений, стека и сегментов с текстом и данными. После успешного вызова с указанием данного флага все страницы вызывающего процесса гарантированно запираются в физической памяти. Флаг MCL_CURRENT не влияет на страницы, которые впоследствии будут выделены в виртуальном адресном пространстве процесса; для них следует использовать флаг MCL_FUTURE.
• MCL_FUTURE — блокирует все страницы, которые впоследствии будут отображены на виртуальное адресное пространство процесса. Это, например, могут быть страницы разделяемого участка памяти, отображенные с помощью вызовов mmap() или shmat(), часть кучи, растущей снизу вверх, или стека, который растет сверху вниз. В результате применения флага MCL_FUTURE последующие операции выделения памяти (например, mmap(), sbrk() или malloc()) могут завершиться неудачей, или же расширение стека может привести к получению сигнала SIGSEGV. Это происходит, когда в системе не хватает памяти, которую можно было бы выделить процессу, или когда исчерпывается мягкое ограничение на ресурсы RLIMIT_MEMLOCK.
Все правила относительно ограничений, жизненного цикла и наследования блокировок памяти, действующих для вызова mlock(), относятся и к mlockall().
Системный вызов munlockall() разблокирует все страницы вызывающего процесса и отменяет последствия от любых ранее выполненных вызовов mlockall(MCL_FUTURE). Как и в случае с munlock(), удаление разблокированных страниц из физической памяти не гарантируется.
Системный вызов mincore() дополняет операции блокировки памяти. Он сообщает, какие страницы в диапазоне виртуальных адресов находятся в физической памяти и в случае доступа к ним не приведут к отказу.
Вызов mincore() не входит в стандарт SUSv3. Он доступен во многих реализациях UNIX, но не во всех. В Linux он поддерживается, начиная с ядра версии 2.4.
#define _BSD_SOURCE /* Или: #define _SVID_SOURCE */
#include
int mincore(void *
Возвращает 0 при успешном завершении или -1 при ошибке
Системный вызов mincore() возвращает сведения о местоположении страниц виртуального адресного пространства длиной length байт, которое начинается с адреса addr. Адрес, указанный в аргументе addr, должен быть выровнен по странице, а значение length на практике округляется до следующего кратного размеру страницы памяти в системе, поскольку информация относится к целым страницам.
Сведения о местонахождении памяти возвращается в аргументе vec, который должен представлять собой массив размером (length + PAGE_SIZE — 1) / PAGE_SIZE байт (в Linux vec имеет тип unsigned char *; в ряде других реализаций UNIX вместо этого используется тип char *). Если соответствующая страница находится в физической памяти, то устанавливается младший бит в каждом байте. Установка остальных битов не предусмотрена в некоторых UNIX-системах, в связи с чем портируемые приложения должны проверять только этот единственный бит.
Информация, возвращаемая mincore(), может измениться после выполнения вызова и проверки элементов vec. Только страницы, заблокированные вызовами mlock() или mlockall(), гарантированно остаются в физической памяти.
Применение вызовов mlock() и mincore() демонстрируется в листинге 46.2. Выделив и отобразив участок памяти с помощью mmap(), эта программа вызывает mlock() для блокирки либо всего участка, либо групп страниц с постоянными интервалами (каждый аргумент командной строки программы выражается в виде страниц; программа переводит их в байты, как того требуют вызовы mmap(), mlock() и mincore()). Перед и после mlock() она вызывает mincore(), чтобы получить сведения о местоположении страниц заданного участка памяти, и отображает эту информацию в графическом виде.
Листинг 46.2. Использование вызовов mlock() и mincore()
vmem/memlock.c
#define _BSD_SOURCE /* Получаем объявление mincore() и определение
MAP_ANONYMOUS из
#include
#include "tlpi_hdr.h"
/* Выводим местоположение страниц в диапазоне [addr.. (addr + length — 1)] */
static void
displayMincore(char *addr, size_t length)
{
unsigned char *vec;
long pageSize, numPages, j;
pageSize = sysconf(_SC_PAGESIZE);
numPages = (length + pageSize — 1) / pageSize;
vec = malloc(numPages);
if (vec == NULL)
errExit("malloc");
if (mincore(addr, length, vec) == -1)
errExit("mincore");
for (j = 0; j < numPages; j++) {
if (j % 64 == 0)
printf("%s%10p: ", (j == 0)? "": "\n", addr + (j * pageSize));
printf("%c", (vec[j] & 1)? '*': '.');