フィボナッチ数列を含むパケットを送信するためのPKTGENの変更に取り組んでいます。カーネル開発は初めてなので、メモリ割り当てに利用できる機能についてはあまり詳しくありません。私もCの第一人者ではありません:)
アルゴリズムの反復ステップを配列に格納します。誰かが素晴らしいフィボナッチ数パラメーターを要求した場合に動的になりたいと思います。
Reallocは使用できません。配列サイズを動的に拡大する方法を知っていますか?
ありがとうございました
フィボナッチ数列を含むパケットを送信するためのPKTGENの変更に取り組んでいます。カーネル開発は初めてなので、メモリ割り当てに利用できる機能についてはあまり詳しくありません。私もCの第一人者ではありません:)
アルゴリズムの反復ステップを配列に格納します。誰かが素晴らしいフィボナッチ数パラメーターを要求した場合に動的になりたいと思います。
Reallocは使用できません。配列サイズを動的に拡大する方法を知っていますか?
ありがとうございました
2.6.31-rc5に追加されたDaveHansenフレキシブルアレイを参照してください。
https://lwn.net/Articles/345273/
柔軟な配列の作成は、次の方法で行われます。
#include <linux/flex_array.h>
struct flex_array *flex_array_alloc(int element_size, int total, gfp_t flags);
個々のオブジェクトのサイズはelement_sizeによって提供され、totalは配列に格納できるオブジェクトの最大数です。flags引数は、内部メモリ割り当て呼び出しに直接渡されます。現在のコードでは、フラグを使用して高メモリを要求すると、特に不快な副作用が発生する可能性があります。
柔軟な配列へのデータの格納は、次の呼び出しで実行されます。
int flex_array_put(struct flex_array *array, int element_nr, void *src, gfp_t flags);
この呼び出しは、データをsrcから配列のelement_nrで示される位置にコピーします(配列が作成されたときに指定された最大値よりも小さい必要があります)。メモリ割り当てを実行する必要がある場合は、フラグが使用されます。成功した場合の戻り値はゼロであり、それ以外の場合は負のエラーコードです。
ある種のアトミックコンテキストで実行しているときに、データを柔軟な配列に格納する必要があるかもしれません。この状況では、メモリアロケータで寝ることは悪いことです。これは、フラグ値にGFP_ATOMICを使用することで回避できますが、多くの場合、より良い方法があります。秘訣は、以下を使用して、アトミックコンテキストに入る前に、必要なメモリ割り当てが行われていることを確認することです。
int flex_array_prealloc(struct flex_array *array, int start, int end, gfp_t flags);
この関数は、startとendで定義された範囲でインデックス付けされた要素のメモリが割り当てられていることを確認します。その後、その範囲内の要素に対するflex_array_put()呼び出しは、ブロックされないことが保証されます。
配列からデータを取り戻すには、次の操作を行います。
void *flex_array_get(struct flex_array *fa, int element_nr);
戻り値はデータ要素へのポインタであり、特定の要素が割り当てられたことがない場合はNULLです。
配列に格納されたことのない要素の有効なポインタを取り戻すことができることに注意してください。配列要素のメモリは、一度に1ページずつ割り当てられます。単一の割り当てで、いくつかの隣接する要素にメモリを提供できます。柔軟な配列コードは、特定の要素が書き込まれたかどうかを認識しません。関連するメモリが存在するかどうかのみを認識します。したがって、配列に格納されたことのない要素に対するflex_array_get()呼び出しは、ランダムデータへのポインタを返す可能性があります。呼び出し元が実際に格納された要素を知るための個別の方法がない場合は、少なくとも、すべての要素がゼロになるように、flags引数にGFP_ZEROを追加するのが賢明かもしれません。
配列から単一の要素を削除する方法はありません。ただし、次の呼び出しを使用してすべての要素を削除することは可能です。
void flex_array_free_parts(struct flex_array *array);
この呼び出しはすべての要素を解放しますが、配列自体はそのままにします。アレイ全体の解放は、次の方法で実行されます。
void flex_array_free(struct flex_array *array);
この記事の執筆時点では、メインラインカーネルに柔軟なアレイのユーザーはいません。ここで説明する関数もモジュールにエクスポートされません。誰かがそれの必要性を思いついたとき、それはおそらく修正されるでしょう。
これは、カーネル開発がサポートすることを目的とした種類のものではありません。これをユーザーモードプログラムにする方がはるかに適切です。
ただし、これを行う方法は、独自の動的長さ配列を実装することです。アレイの大きさを追跡します。大きくする必要がある場合は、新しいサイズでkmalloc()
(通常はGFP_KERNEL
パラメーターを使用して)呼び出し、古いデータを新しいデータにコピーして、古い(kfree()
)を破棄します。カーネルヘッダーファイルを参照してください
アレイが約4Kまたは8Kよりも大きくなる場合は、__get_free_pages()
またはのvmalloc()
代わりにを使用することを検討してください。
kmalloc()とkfree()はlinux-2.X.XX.XX/include/linux/slob_def.h
__get_free_pages()にありlinux-2.X.XX.XX/include/linux/gfp.h
ますvmalloc()はにありますlinux-2.X.XX.XX/include/linux/vmalloc.h