C言語で0から作るOSを開発について説明していきます。このシリーズではカーネルの開発について説明しています。
今回は動的メモリー確保を行うkmallocとその基盤となるスラブアロケーターについて説明していきます。
[第3版改訂]
プログラムソースのフォーマットを変更しました。
[第4版改訂]
表紙の変更、誤記修正、kmem_cach_allocの不具合修正
[目次]
前回までの内容
ヒープ(Heap)
固定長メモリーブロック
バディ(相棒)システム
スラブアロケーター(Slab Allocator)
オブジェクトとスラブとキャッシュ
スラブアロケーターのインターフェイス
スラブアロケーターのフロントエンド
スラブアロケーターのバックエンド
スラブアロケーターのインターフェイス関数
”キャッシュ”の生成 kmem_cache_create
”キャッシュ”の割り当て kmem_cache_alloc
”キャッシュ”の解放 kmem_cache_free
”キャッシュ”の破壊 kmem_cache_destroy
”キャッシュ”の拡大 kmem_cache_grow
”キャッシュ”の刈り取り kmem_cache_reap
スラブアロケーターのインターフェース使用例
スラブ
kmem_bufctlの定義
スラブのレイアウト(小さなサイズのオブジェクトの場合)
スラブのレイアウト(大きなサイズのオブジェクトの場合)
スラブの管理
スラブの定義
キャッシュ
キャッシュ kmem_cacheの定義
スラブアロケーターの実装
キャッシュの生成 kmem_cache_create関数の実装 (フロントエンド)
1.kmem_cacheの生成 allocKmemCache関数
2.kmem_cacheの初期化 initKmemCache関数
3.スラブの計算 calcSlabSize
4.キャッシュをキャッシュリストに追加
5.初期化したキャッシュ構造体を返す
キャッシュの割り当て kmem_cache_alloc関数の実装 (フロントエンド)
1.”一部割り当て済み”のスラブがあればそこからオブジェクトを割り当てる
2. 1.以外の場合で、”全部が解放済み”のスラブがない場合
3. 1.以外の場合、”全部が解放済み”のスラブがあればそこからオブジェクトを割り当てる
キャッシュの解放 kmem_cache_free関数の実装 (フロントエンド)
1.オンスラブであれば、そのままスラブ構造体のアドレスを取得する
2.オフスラブの場合、”一部が割り当て済み”、”全部が割り当て済み”リストのスラブからスラブ構造体のアドレスを取得する。
3.解放するオブジェクトが所属するスラブのkmem_bufctlを更新する
キャッシュの破壊 kmem_cache_destory関数の実装 (フロントエンド)
キャッシュの拡大 kmem_cache_grow関数の実装 (バックエンド)
1.オフスラブの場合、スラブとkmem_bufctlのメモリーはkmallocから割り当て、オブジェクト専用のページを別途割りてます。
2.オンスラブの場合1ページ丸ごとスラブに割りてます。
3.スラブ構造体とキャッシュの一部を初期化します。
キャッシュの刈り取り kmem_cache_reap関数の実装 (バックエンド)
1.スラブ構造体のアドレスを取得します。
2.オンスラブの場合、スラブに割り当てていた1ページを解放します。
3.オフスラブの場合、オブジェクトに割り当てていたページとkfreeでスラブ管理情報を解放します。
kmallocとkfree
スラブアロケーターの活用
汎用オブジェクトの作成とスラブアロケーターの初期化
kmem_cacheキャッシュの確保
汎用オブジェクトの確保
スラブアロケーターの初期化
kmallocの実装
kfreeの実装
ここまでで実装してきたスラブアロケーターの改良
ページとの対応付け
オブジェクトのアライメント
カラーリング
ハードウェアキャッシュの概略
スラブアロケーターのカラーリング
不要となったスラブの解放
今回は動的メモリー確保を行うkmallocとその基盤となるスラブアロケーターについて説明していきます。
[第3版改訂]
プログラムソースのフォーマットを変更しました。
[第4版改訂]
表紙の変更、誤記修正、kmem_cach_allocの不具合修正
[目次]
前回までの内容
ヒープ(Heap)
固定長メモリーブロック
バディ(相棒)システム
スラブアロケーター(Slab Allocator)
オブジェクトとスラブとキャッシュ
スラブアロケーターのインターフェイス
スラブアロケーターのフロントエンド
スラブアロケーターのバックエンド
スラブアロケーターのインターフェイス関数
”キャッシュ”の生成 kmem_cache_create
”キャッシュ”の割り当て kmem_cache_alloc
”キャッシュ”の解放 kmem_cache_free
”キャッシュ”の破壊 kmem_cache_destroy
”キャッシュ”の拡大 kmem_cache_grow
”キャッシュ”の刈り取り kmem_cache_reap
スラブアロケーターのインターフェース使用例
スラブ
kmem_bufctlの定義
スラブのレイアウト(小さなサイズのオブジェクトの場合)
スラブのレイアウト(大きなサイズのオブジェクトの場合)
スラブの管理
スラブの定義
キャッシュ
キャッシュ kmem_cacheの定義
スラブアロケーターの実装
キャッシュの生成 kmem_cache_create関数の実装 (フロントエンド)
1.kmem_cacheの生成 allocKmemCache関数
2.kmem_cacheの初期化 initKmemCache関数
3.スラブの計算 calcSlabSize
4.キャッシュをキャッシュリストに追加
5.初期化したキャッシュ構造体を返す
キャッシュの割り当て kmem_cache_alloc関数の実装 (フロントエンド)
1.”一部割り当て済み”のスラブがあればそこからオブジェクトを割り当てる
2. 1.以外の場合で、”全部が解放済み”のスラブがない場合
3. 1.以外の場合、”全部が解放済み”のスラブがあればそこからオブジェクトを割り当てる
キャッシュの解放 kmem_cache_free関数の実装 (フロントエンド)
1.オンスラブであれば、そのままスラブ構造体のアドレスを取得する
2.オフスラブの場合、”一部が割り当て済み”、”全部が割り当て済み”リストのスラブからスラブ構造体のアドレスを取得する。
3.解放するオブジェクトが所属するスラブのkmem_bufctlを更新する
キャッシュの破壊 kmem_cache_destory関数の実装 (フロントエンド)
キャッシュの拡大 kmem_cache_grow関数の実装 (バックエンド)
1.オフスラブの場合、スラブとkmem_bufctlのメモリーはkmallocから割り当て、オブジェクト専用のページを別途割りてます。
2.オンスラブの場合1ページ丸ごとスラブに割りてます。
3.スラブ構造体とキャッシュの一部を初期化します。
キャッシュの刈り取り kmem_cache_reap関数の実装 (バックエンド)
1.スラブ構造体のアドレスを取得します。
2.オンスラブの場合、スラブに割り当てていた1ページを解放します。
3.オフスラブの場合、オブジェクトに割り当てていたページとkfreeでスラブ管理情報を解放します。
kmallocとkfree
スラブアロケーターの活用
汎用オブジェクトの作成とスラブアロケーターの初期化
kmem_cacheキャッシュの確保
汎用オブジェクトの確保
スラブアロケーターの初期化
kmallocの実装
kfreeの実装
ここまでで実装してきたスラブアロケーターの改良
ページとの対応付け
オブジェクトのアライメント
カラーリング
ハードウェアキャッシュの概略
スラブアロケーターのカラーリング
不要となったスラブの解放