Главная » Ядро Linux » Счетчики ссылок

0

Одно  из  главных  свойств,  которое реализуется с  помощью объектов kobject , — это  унифицированная  система поддержки счетчиков ссылок. После  инициализации количество ссылок на объект  устанавливается равным единице. Пока значение счетчика  ссылок на объект  не равно  нулю, объект  существует в памяти, и говорят, что он захвачен  (pinned,  буквально, пришпилен). Любой  код, который работает  с объектом, вначале должен  увеличить значение  счетчика ссылок.  После  того  как  код  закончил работу  с  объектом,  он  должен  уменьшить значение  счетчика  ссылок.  Увеличение значения счетчика называют захватом  (getting), уменьшение — освобождением (putting) ссылки на объект. Когда значение счетчика становится равным нулю, объект может быть уничтожен, а занимаемая им память освобождена.

Увеличение значения  счетчика ссылок выполняется  с  помощью функции kobject_get() .

struct kobject * kobject_get(struct kobject *kobj);

Эта функция возвращает указатель на объект kobjec t в случае успеха и значение

NULL в случае ошибки.

Уменьшение значения счетчика ссылок выполняется с  помощью функции

kobject_put().

void kobject put(struct kobject *kobj);

Если  значение  счетчика ссылок объекта,  который передается в качестве параметра, становится равным нулю, то  вызывается функция, на  которую указывает указатель  releas e  поля   ktyp e  этого   объекта.

Структуры kre f

Внутреннее представление счетчика ссылок выполнено с  помощью структуры kref, которая определена в  файле <linux/kref . h> следующим образом.

struct kref{

atomic_trefcount;

};

Единственное поле  этой  структуры — атомарная переменная, в которой хранится значение  счетчика ссылок.  Структура используется просто   для  того,  чтобы  выполнять  проверку типов.  Чтобы   воспользоваться  структурой  kref , необходимо ее  инициализировать с помощью функции kref_ini t ()  .

void kref_init(struct kref *krcf)

{

atomic_set(&kref->refcount, 1);

}

Как  видно  из определения, эта функция просто  инициализирует атомарную переменную тина  atomic_ t  в значение, равное единице.

Следовательно,  структура kre f является захваченной сразу  же  после  инициализации, так  же  ведут  себя  и  объекты kobject.

Для  того  чтобы   захватить   ссылку   на  структуру   kref ,  необходимо использовать функцию  kref_ge t  () .

void kref_get(struct kref *kref)

{

WARN_ON(!atomic_read(&kref->refcount));

atomic_inc(&kref->refcount);

}

Эта функция увеличивает значение счетчика ссылок на единицу. Она не возвращает никаких значений.  Чтобы освободить ссылку на структуру kref, необходимо использовать функцию kref_put ().

void kref_put(struct kref *kref, void (*release) (struct kref *kref))

{

WARN_ON(release == NULL);

WARN_ON(release== (void (*)(struct kref *))kfree);

if (atomicdec_and_test(&kref->refcount))

release (kref);

}

Эта  функция  уменьшает значение счетчика ссылок на  единицу и  вызывает функцию   releas e () ,  которая передастся ей  в  качестве параметра,  когда  значение счетчика  ссылок становится равным нулю.   Как  видно   из  использованного выражения WARM_ON () , функция releas e ()   не  может  просто  совпадать с  функцией  kfrе е  () ,

а  должна быть специальной функцией,  которая принимает указатель на структуру struc t   kre f  в  качестве своего единственного параметра и не возвращает никаких значений.

Вместо того чтобы разрабатывать свои функции управления счетчиками ссылок на основании типа данных atomic_t , настоятельно рекомендуется использовать тип данных kre f и соответствующие функции, которые обеспечивают общий и правильно работающий механизм поддержки счетчиков ссылок в  ядре.

Все эти  функции  определены  в  файле   lib/kref. c   и  объявлены в  файле

<linux/kref.h> .

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии