ガイドUnderstanding The Linux Kernel, 3rd Editionの章8.2.12。Linuxでのポインタ計算カーネル割り当ての実装
void * kmem_cache_alloc(kmem_cache_t *cachep, int flags)
{
unsigned long save_flags;
void *objp;
struct array_cache *ac;
local_irq_save(save_flags);
ac = cache_p->array[smp_processor_id()];
if (ac->avail)
{
ac->touched = 1;
objp = ((void**)(ac+1))[--ac->avail];
} else
objp = cache_alloc_refill(cachep, flags);
local_irq_restore(save_flags); return objp;
}
ガイドによると、ライン((void**)(ac+1))[--ac->avail]
を見て、今すぐ:
をローカルキャッシュアレイは直後に格納されるためスラブオブジェクトを割り当て、以下のコードがあります ((void **)(ac + 1))[ - ac-> avail]は空きオブジェクトのアドレスを取得し、 はac-> availの値を減らします。
しかし、ac
(この順で)次のフィールドが含まれていstruct array_cache
を型へのポインタであるので -
[タイプ] unsigned int型
[名前]
役に立ちます[説明]ローカルキャッシュ内の使用可能なオブジェクトへのポインタの数。 フィールドは、キャッシュ内の最初の空きスロットのインデックスとしても機能します。
[タイプ] unsigned int型
[名]は、ローカルキャッシュ内のポインタの最大数であるローカルキャッシュの
[説明]サイズを制限します。
[タイプ]ローカルキャッシュリフィルまたは空にするためunsigned int型
[名前] batch_count
[説明]チャンクサイズ。ローカルキャッシュが、最近使用されている場合
[タイプ] unsigned int型
[名前]は1に
[説明]旗セットに触れました。
のでac+1
はまったく意味をなさないavail
値(又は逆のエンディアンの場合に3バイト目)の第2バイトを指します。
私はこれを間違った方法で受け取りますか?
このタイプのコーディングのより一般的な使用法と例を教えてください。私はこのデータをラップする別の構造体の使用を期待していたでしょう、そして、このラッパー構造体は、他の構造体へのポインタのフィールドと、他のデータを指す別のフィールドを持ちます。この方法はきれいで明確です。なぜこのようなコードを使用するのですか?それは何のために良いですか? – user2162550