socket APIの内部で利用されるmbuf
mbufはsocket APIの内部で行われるメモリ管理で利用されるデータ構造(構造体?)。256bytesの固定長で、線形リストを形成する。mbufの連鎖をチェインと呼び、またチェインの連鎖をキューと呼ぶ。
データの冒頭にヘッダがあり、そこで次のmbufへのポインタやデータの情報を格納する。ヘッダはさらに第二のヘッダが存在する場合もあり、その場合はデータ本体の領域が減少する。mbuf全体は変わらない。また外部領域にデータ本体を置く事も可能で、その場合もmbufのデータ部分に拡張情報が格納される。
mbufのデータ構造:
m_next | 次のmbufへ。mbufの連結でチェインを作る |
m_nextpkt | 次のチェインへ。チェインの連鎖をキューと呼ぶ |
m_data | たぶん、データ本体のオフセット |
m_len | たぶん、データ本体のbytesサイズ |
m_flags | たぶん、フラグ |
m_type | たぶん、型 |
m_dat | データ本体(234bytes) |
フラグ:
M_EXT | そのmbufが外部記憶を参照している |
M_PKTHDR | 第二のヘッダ フィールドが存在する |
M_EOR | そのmbufがレコードを構成している |
M_BCAST | このチェーンはブロード キャストである |
M_MCAST | このチェーンはマルチ キャストである |
etc. |
第二のヘッダが付く場合(チェーンの先頭):
m_next | |
m_nextpkt | |
m_data | |
m_len | |
m_flags | (M_PKTHDRをセット) |
m_type | |
pkt.len | |
pkt.rcvif | |
pkt.header | |
pkt.csum_flags | |
pkt.csum_data | |
pkt.tags | |
m_dat | データ本体(210bytes) |
外部領域を使用する場合:
m_next | |
m_nextpkt | |
m_data | |
m_len | |
m_flags | (M_EXTをセット) |
m_type | |
ext.size | |
ext.buf | |
ext.free | |
ext.args | |
ext.refcnt | |
ext.type | |
m_dat | データ本体(使用しない) |
mbufが固定長である理由:
- フラグメンテーションの最小化
- 通信プロトコル処理のため頻発する操作を、メモリの再配置やコピーを出来る限り行わずに実施できる
- dtom()で可変長データを扱うと、極めて重くなる
参考:
- BSDカーネルの設計と実装 -FreeBSD詳解- isbn:4756146791
11.3 メモリ管理