EN JA
OSD(9)
OSD(9) FreeBSD Kernel Developer's Manual OSD(9)

名称

osd, osd_register, osd_deregister, osd_set, osd_get, osd_del, osd_call, osd_exitオブジェクト特有のデータ

書式

#include < sys/osd.h>

typedef void
(*osd_destructor_t)( void *value);

typedef int
(*osd_method_t)( void *obj, void *data);

int
osd_register( u_int type, osd_destructor_t destructor, osd_method_t *methods);

void
osd_deregister( u_int type, u_int slot);

int
osd_set( u_int type, struct osd *osd, u_int slot, void *value);

void *
osd_get( u_int type, struct osd *osd, u_int slot);

void
osd_del( u_int type, struct osd *osd, u_int slot);

int
osd_call( u_int type, u_int method, void *obj, void *data);

void
osd_exit( u_int type, struct osd *osd);

解説

osd フレームワークは、 osd で使用するために適切に変更された任意のカーネルデータ構造に任意のデータを実行時に動的に結びつけるメカニズムを提供します。要求された一回限りの変更は、カーネルデータ構造内に struct osd を埋め込みます。

追加の利点は、構造への初期の変更が行われた後に、構造がある osd のすべてのその後の使用が構造のレイアウトへの変更を含まないことです。拡張として、データ構造が ABI の一部であるなら、 osd は、ABI の保存方法で構造を拡張する方法を提供します。

組み込まれた struct osd の詳細は、 osd フレームワークの消費者に関連されていなくて、直接操作するべきではありません。

構造に関連しているデータは、タイプ/スロット識別子のペアを使用して osd フレームワークによって参照されます。タイプは、 < sys/osd.h> で静的に定義され、登録されるスロットのためのハイレベルなグループ分けを提供します。スロット識別子は、データタイプが osd_register() を使用して登録されるとき、フレームワークによって動的に割り当てられ、 osd_deregister() への対応する呼び出しまで有効なままとなります。

関数

osd_register() 関数は、新しいデータタイプとともに使用するために osd フレームワークでタイプ/スロット識別子のペアを登録します。関数は、スリープするもしれず、そのために、スリープ可能でないコンテキストから呼び出すことができません。 type 引数は、割り付けられるべきであるスロット識別子である、 < sys/osd.h> からグループ化されるハイレベルなタイプを指定します。 destructor 引数は、後で osd_del() 関数によって破壊される登録されているタイプのオブジェクトのために呼び出されるオプションの osd_destructor_t 関数ポインタを指定します。デストラクタが必要でないなら、NULL が渡されます。 methods 引数は、後で osd_call() 関数によって呼び出すことができる osd_method_t 関数ポインタのオプションの配列を指定します。メソッドが必要でないなら、NULL が渡されます。 methods 引数は、現在、OSD_JAIL タイプ識別子でのみ役に立ちます。

osd_deregister() 関数は、以前に登録されたタイプ/スロット識別子のペアを登録解除します。関数は、スリープするもしれず、そのために、スリープ可能でないコンテキストから呼び出すことができません。 type 引数は、割り付けられるスロット識別子である、 < sys/osd.h> からグループ化されるハイレベルなタイプを指定します。 slot 引数は、登録解除されているスロット識別子を指定します、そしてデータタイプが登録されたとき、 osd_register() によって返された値であるべきです。

osd_set() 関数は、データオブジェクトポインタをカーネルデータ構造の struct osd メンバに関連付けます。 type 引数は、割り付けられるスロット識別子である、 < sys/osd.h> からグループ化されるハイレベルなタイプを指定します。 osd 引数は、 value ポインタを持っているカーネルデータ構造の struct osd に関連しているそれへのポインタです。 slot 引数は、 value ポインタを割り当てるスロット識別子を指定します。 value 引数は、 osd に関連しているデータオブジェクトを指します。

osd_get() 関数は、指定されたタイプ/スロット識別子のペアからカーネルデータ構造の struct osd メンバに関連しているデータポインタを返します。 type 引数は、割り付けられるスロット識別子である、 < sys/osd.h> からグループ化されるハイレベルなタイプを指定します。 osd 引数は、データポインタを検索するためのカーネルデータ構造の struct osd へのポインタです。 slot 引数は、データポインタを検索するためのスロット識別子を指定します。

osd_del() 関数は、指定されたタイプ/スロット識別子のペアからカーネルデータ構造の struct osd メンバに関連しているデータポインタを削除します。 type 引数は、割り付けられるスロット識別子である、 < sys/osd.h> からグループ化されるハイレベルなタイプを指定します。 osd 引数は、データポインタを削除するためのカーネルデータ構造の struct osd へのポインタです。 slot 引数は、データポインタを削除するためのスロット識別子を指定します。 osd_destructor_t 関数ポインタが登録時に指定されたなら、デストラクタ関数が呼び出され、削除されているタイプ/スロット識別子のペアのためのデータポインタを渡されます。

osd_call() 関数は、指定された objdata ポインタで与えられたタイプのすべての現在登録されているスロットのために指定された osd_method_t 関数ポインタを呼び出します。関数は、スリープするもしれず、そのために、スリープ可能でないコンテキストから呼び出すことができません。 type 引数は、メソッドを呼び出すために < sys/osd.h> からグループ化されるハイレベルなタイプを指定します。 method 引数は、 osd_register() に渡された osd_method_t 配列へのインデックスを指定します。 objdata 引数は、それぞれのスロットのメソッド関数ポインタに渡されます。

osd_exit() 関数は、指定されたカーネルデータ構造の struct osd メンバのための与えられたタイプのためにすべての現在登録されているスロットからすべてのデータオブジェクトポインタを取り除きます。 type 引数は、テータポインタを取り除くために < sys/osd.h> からグループ化されるハイレベルなタイプを指定します。 osd 引数は、すべての現在登録されているスロットのためのすべてのデータオブジェクトポインタを取り除くためのカーネルデータ構造の struct osd へのポインタです。

実装に関する注

osd は、カーネルデータ構造の struct osd メンバに関連している外部のデータを管理するために、データ構造として二次元のマトリクス (配列の配列) を使用します。タイプ識別子は、インデックスとして外側の配列に使用され、スロット識別子は、インデックスとして内側の配列に使用されます。与えられたタイプ/スロット識別子のペアのためにデータポインタを設定するか、または検索するために、 osd_set() と osd_get() は、一定の時間と速さで array[type][slot] と同様なことを実行します。

osd_set() が、初めて struct osd で呼び出されるなら、データポインタを格納するための配列は、設定されるスロット識別子のための適切なサイズまで M_NOWAIT で malloc(9) を使用して動的に割り付けられます。 osd_set() へのその後の呼び出しが、前の osd_set() 呼び出しで使用されるスロットより数値的に大きなスロット識別子を設定することを試みるなら、 realloc(9) は、スロット識別子を使用できるように適切なサイズまで配列を増大するために使用されます。多くの異なったスロット識別子 (例えば、初期化処理フェーズの間に) で連続して osd_set() を呼び出す任意のコードの効率を最大にするためには、スロット識別子を通して最も高いものから最も低いものに降順でループするべきです。これは、最も大きいスロットサイズの配列を作成するために単一の malloc(9) だけを呼び出すの結果となります、そして、 osd_set() へのすべてのその後の呼び出しは、少しも realloc(9) 呼び出しなしで続きます。

osd API は、与えられた osd のタイプ識別子のために同じ基本的なデータ構造タイプへのポインタを格納するスロット識別子を対象としています。これは、必要条件ではありません、そして、例えば、 khelp(9) は、OSD_KHELP タイプ識別子の下のスロットに完全に異なったデータタイプを格納します。

ロック

osd は、その内部のデータ構造と状態を保護するために内部的に mutex(9), rmlock(9)sx(9) ロックをミックスして使用します。

カーネルデータ構造の struct osd メンバへの同期アクセスのための責任は、データ構造を使用して、 osd API を呼び出すサブシステムに委ねられます。

osd_get() は、読み込みモードで rmlock を獲得するだけです、したがって、ほとんどの高速パスを含むカーネル中でコンテキストの大部分で使用するために安全にします。

戻り値

osd_register() は、新しく登録されたデータタイプのためのスロット識別子を返します。

osd_set() は、成功すれば、0 を返し、指定されたタイプ/スロット識別子のペアが失敗した内部の realloc(9) の引き金となったなら、ENOMEM を返します。

osd_get() は、指定されたタイプ/スロット識別子のペアのためのデータポインタを返し、スロットがまだ初期化されていないなら、NULL を返します。

osd_call() は、メソッドが実行されないか、または各スロットのためのメソッドが成功して実行されたなら、0 を返します。スロットのためのメソッドが 0 以外を返すなら、 osd_call() は、時期を早めて終了し、呼び出し側にメソッドのエラーを返します。

関連項目

khelp(9)

歴史

Object Specific Data (OSD) 機能は、 FreeBSD 8.0 ではじめて登場しました。

作者

osd 機能は、 Pawel Jakub Dawidek <pjd@FreeBSD.org>によって書かれました。

このマニュアルページは、 Lawrence Stewart <lstewart@FreeBSD.org>によって書かれました。

January 5, 2011 FreeBSD