3. Программирование в ядре FreeBSD

3.1. Выделение памяти

Прочитайте malloc(9) -- выделение памяти лишь немного отличается от своего эквивалента, используемого в пространстве пользовательских процессов (userland). Наиболее приметно то, что malloc() и free() принимают дополнительные параметры, которые описаны в странице справочника.

Тип ''malloc_type'' необходимо объявить в секции деклараций файла с исходным кодом, например:

  static MALLOC_DEFINE(M_GJOURNAL, "gjournal data", "GEOM_JOURNAL Data");

Для того, чтобы можно было использовать этот макрос, необходимо включить следующие заголовочные файлы: sys/param.h, sys/kernel.h и sys/malloc.h

Существует еще один механизм выделения памяти -- UMA (Universal Memory Allocator), описанный в uma(9). Это специфический метод, преимущественно предназначенный для быстрого выделения памяти под списки, состоящие из элементов одинакового размера (например, динамические массивы структур).

3.2. Очереди и списки

Ознакомьтесь с queue(3) Во множестве случаев вам необходимо будет организовывать и управлять такой структурой данных, как списки. К счастью, эта структура данных реализована несколькими способами в виде макросов на Си, а также включена в систему. Наиболее гибкий и часто употребляемый тип списка -- TAILQ. Этот тип списка также один из наиболее требовательных к памяти (его элементы - с двойными связями), а также -- наиболее медленный (однако счет идет на несколько инструкций ЦПУ, поэтому последнее утверждение не следует воспринимать в всерьез).

Если важна скорость получения данных, то возьмите на вооружение tree(3) и hashinit(9).

3.3. BIOs

Структура bio используется для всех операций ввода/вывода, касающихся GEOM. Она содержит информацию о том, какое устройство ('поставщик geom') должно ответить на запрос, тип запроса, смещение, длину и указатель на буфер, а также набор ''определенных пользователем'' флагов и полей .

Важным моментом является то, что bio обрабатываются асинхронно. Это значит, что во многих частях кода нет аналога к read(2) и write(2) функциям из пространства пользовательских процессов, которые не возвращают управление пока не выполнится системный вызов. Скорее, по завершении обработки запроса (или в случае ошибки при обработке) как извещение вызывается определенная пользователем функция.

Асинхронная модель программирования в чем-то сложней, нежели чаще используемая императивная модель, используемая в пространстве пользовательских процессов; в любом случае, привыкание займет некоторое время. В некоторых случаях могут быть использованы вспомогательные функции g_write_data() и g_read_data(), но далеко не всегда. В частности, эти функции не могут использоваться когда захвачен мьютекс; например, мьютекс GEOM-топологии или внутренний мьютекс, удерживаемый в ходе выполнения .start() или .stop().

Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.