Пример использования слябового распределителя памяти
Пример использования слябового распределителя памяти
Давайте рассмотрим пример из реальной жизни, связанный с работой со структурами task_struct (дескрипторы процессов). Показанный ниже код в несколько более сложной форме приведен в файле kernel/fork.c.
В ядре определена глобальная переменная, в которой хранится указатель на кэш объектов task_struct:
kmem_cache_t *task_struct_cachep;
Во время инициализации ядра, в функции fork_init(), этот кэш создается следующим образом.
task_struct_cachep = kmem_cache_create("task_struct",
sizeof(struct task_struct), ARCH_MIN_TASKALIGN,
SLAB_PANIC, NULL, NULL);
Данный вызов создает кэш с именем "task_struct", который предназначен для хранения объектов тина struct task_struct. Объекты создаются с начальным смещением в слябе, равным ARCH_MIN_TASKALIGN байт, и положение всех объектов выравнивается по границам строк системного кэша, значение этого выравнивания зависит от аппаратной платформы. Обычно значение выравнивания задается для каждой аппаратной платформы с помощью определения препроцессора L1_CACHE_BYTES, которое равно размеру процессорного кэша первого уровня в байтах. Конструктор и деструктор отсутствуют. Следует обратить внимание, что возвращаемое значение не проверяется на равенство NULL, поскольку указан флаг SLAB_PANIC. В случае, когда при выделении памяти произошла ошибка, слябовый распределитель памяти вызовет функцию panic(). Если этот флаг не указан, то нужно проверять возвращаемое значение на равенство NULL, что сигнализирует об ошибке. Флаг SLAB_PANIC здесь используется потому, что этот каш является необходимым для работы системы (без дескрипторов процессов работать как-то не хорошо).
Каждый раз, когда процесс вызывает функцию fork(), должен создаваться новый дескриптор процесса (вспомните главу 3, "Управление процессами"). Это выполняется следующим образом в функции dup_task_struct(), которая вызывается из функции do_fork().
struct task_struct *tsk;
tsk = kmem_cache_alloc(task struct_cachep, GFP_KERNEL);
if (!tsk)
return NULL;
Когда процесс завершается, если нет порожденных процессов, которые ожидают на завершение родительского процесса, то дескриптор освобождается и возвращается обратно в кэш task_struct_cachep. Эти действия выполняются в функции free_task_struct(), как показано ниже (где параметр tsk указывает на удаляемый дескриптор).
kmem_cache_free(task_struct_cachep, tsk);
Так как дескрипторы процессов принадлежат к основным компонентам ядра и всегда необходимы, то кэш task_struct_cachep никогда не ликвидируется. Если бы он ликвидировался, то делать это необходимо было бы следующим образом.
int err;
err = kmem_cache_destroy(task_struct_cachep);
if (err)
/* ошибка ликвидации кэша */
Достаточно просто, не так ли? Уровень слябового распределения памяти скрывает все низкоуровневые операции, связанные с выравниванием, "раскрашиванием", выделением и освобождением памяти, "сборкой мусора" в случае нехватки памяти. Коли часто необходимо создавать много объектов одного типа, то следует подумать об использовании слябового кэша. И уж точно не нужно писать свою реализацию списка свободных ресурсов!
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Пример использования
Пример использования Данный раздел не является частью GPL. Здесь мы показываем комментарий с заявлением об авторских правах из программы GNU env:/* env - run a program in a modified environmentCopyright (C) 1986, 1991-2002 Free Software Foundation, Inc.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as
Уровень слябового распределителя памяти
Уровень слябового распределителя памяти Выделение и освобождение структур данных — это одна из наиболее частых операций, которые выполняются в любом ядре. Для того чтобы облегчить процедуру частого выделения и освобождения данных при программировании, вводятся списки
Устройство слябового распределителя памяти
Устройство слябового распределителя памяти Уровень слябового распределения памяти делит объекты на группы, которые называются кэшами (cache). Разные кэши используются для хранения объектов различных типов. Для каждого типа объектов существует свой уникальный кэш.
Интерфейс слябового распределителя памяти
Интерфейс слябового распределителя памяти Новый кэш можно создать с помощью вызова следующей функции.kmem_cache_t * kmem_cache_create(const char *name, size_t size, size_t offset, unsigned long flags,void (*ctor)(void*, kmem_cache_t*, unsigned long),void (*dtor)(void*, kmem_cache_t*, unsigned long));Первый параметр — это строка, которая содержит имя кэша.
Пример использования
Пример использования В следующем примере сервер уведомляет Internet Explorer, что содержание документа не будет меняться в течение 1 часа (pre-check=3600) и что его можно загружать прямо из локального кэша. В случае же изменения страницы, если пользователь запросит ее по истечении 15
Глава 7 Средства отладки использования памяти
Глава 7 Средства отладки использования памяти Несмотря на то что С бесспорно является стандартным языком программирования в системах Linux, он имеет ряд особенностей, не дающих программистам возможности писать код, не содержащий тонких ошибок, которые впоследствии очень
4.6. Пример построения диаграммы вариантов использования
4.6. Пример построения диаграммы вариантов использования В качестве примера рассмотрим процесс моделирования системы продажи товаров по каталогу, которая может быть использована при создании соответствующих информационных систем.В качестве актеров данной системы
Пример использования рецептов
Пример использования рецептов Приведенные выше сведения были необходимы для создания общего представления о работе Procmail. В листинге приведен чрезвычайно простой пример файла Procmail, предназначенного для фильтрации сообщений. Содержащиеся в нем рецепты пригодны для
Пример использования Go To
Пример использования Go To В следующем примере оператор Go To направляет поток программы из главной части процедуры к метке Special Value, если встречается необычное значение: Function GoToExample (ItemNumber As Integer ) Dim intR As Integer Select Case ItemNumber Case 2412 Go To SpecialValue Case Is < CutOffValue DoSomething
7.2.6. Статистика использования процессом памяти
7.2.6. Статистика использования процессом памяти Файл statm содержит список из семи чисел, разделенных пробелами. Каждое число — это счетчик числа страниц памяти, используемых процессом и попадающих в определенную категорию. Соответствующие категории перечислены ниже (в
1.7.1. Пример использования команды chown
1.7.1. Пример использования команды chown Вот как можно поменять владельца файла с помощью команды chown:$ ls -l-rwxrwxrwx 1 louise admin 345 Sep 20 14:33 project$ chown pauline project $ ls -l-rwxrwxrwx 1 pauline admin 345 Sep 20 14:33 projectПраво владения файлом project переходит от пользователя louise к
1.7.2. Пример использования команды chgrp
1.7.2. Пример использования команды chgrp Следующий пример демонстрирует, как поменять группу, которой принадлежит файл:$ ls -1-rwxrwxrwx 1 pauline admin 345 Sep 20 14:33 project$ chgrp sysadmin project $ ls -1-rwxrwxrwx 1 pauline sysadmin 345 Sep 20 14:33 projectПользователь pauline передал группе sysadmin право владения файлом project, которое до
Пример использования таймера
Пример использования таймера Данная программа выводит 1 каждые 100 миллисекунд в течение 3 секунд:uses Timers;procedure TimerProc;beginwrite(1);end;begin var t := new Timer(100,TimerProc);t.Start;Sleep(3000);end.Вызов Sleep здесь обязателен, иначе программа после создания таймера сразу закончится, и обработчик таймера ни