バッファ操作 - rb_handle_head_page()
概要
バッファのヘッダを更新する
詳細
この関数では以下の引数を受け取る
- CPUごとのバッファへのポインタ : cpu_buffer
- バッファの最後のページへのポインタ : tail_page
- バッファの次のページへのポインタ : next_page
rb_head_page_set_update()にRB_PAGE_HEADを渡してnext_pageのフラグ_RB_PAGE_UPDATEに変更するが、この返り値によって以下のように処理が異なる
- 返り値がRB_PAGE_HEADの場合
- 元のフラグがRB_PAGE_HEADであるため変更に成功しており、local_add()でcpu_bufferのoverrunメンバにrb_page_entries()で取得したnext_pageのエントリ数を加算し、cpu_bufferのentries_bytesメンバからBUF_PAGE_SIZEの値を減算する
- 返り値がRB_PAGE_UPDATEの場合
- 元のフラグがRB_PAGE_UPDATEであるため変更に失敗しており、特に処理を行わない
- 返り値がRB_PAGE_NORMALの場合
- 元のフラグがRB_PAGE_NORMALであるため変更に失敗しており、1を返して処理を中断する
- 返り値がRB_PAGE_MOVEDの場合
- 実行中に他のスレッドにより処理されているため、1を返して処理を中断する
- 上記以外の場合
- 予期せぬフラグが設定されているため、RB_WARN_ON()にcpu_bufferと1を渡すことで必ずエラーを出力し、-1を返して処理を中断する
ここまでの処理はnext_pageのフラグをRB_PAGE_HEADからRB_PAGE_UPDATEに変更する処理のため変更に成功するか既にRB_PAGE_UPDATE_である場合は処理を継続する
next_pageをローカル変数であるnew_headに代入しrb_inc_page()を実行することでnew_headの参照先をnext_pageの次のバッファに変更する
その後rb_head_page_set_head()にRB_PAGE_NORMALを渡してnew_headのフラグをBR_PAGE_HEADに変更するため、変更に成功するか既にBR_PAGE_HEADがセットされている場合は処理を継続するが、それ以外の場合は予期せぬフラグが設定されているため、RB_WARN_ON()にcpu_bufferと1を渡すことで必ずエラーを出力し、-1を返して処理を中断する
処理を継続する場合は変更に成功した場合と、既にセット済みであった場合で以下のように処理が異なる
- 変更に成功した場合
- rb_head_page_set_normal()にRB_PAGE_UPDATEを渡してnext_pageのフラグをRB_PAGE_NORMALに変更する
- 変更に失敗した場合はRB_WARN_ON()でエラーを表示し、-1を返して処理を中断する
- 既にセット済みの場合
- READ_ONCE()でcpu_bufferのtail_pageメンバを取得し、取得した値がtail_page、next_pageのいずれにも一致しない場合はnew_headは通常のバッファであると判断しrb_head_page_set_normal()にRB_PAGE_HEADを渡してnew_headのフラグをRB_PAGE_NORMALに変更する
途中で処理が中断されなかった場合は0を返して処理を終了する
以上の内容から返り値によって以下の状態が判別できる
- 返り値 1
- next_pageのフラグがRB_PAGE_NORMALかリストの入れ替え後に他のスレッドで移動された場合
- 返り値 0
- next_pageのフラグをRB_PAGE_UPDATEに変更(既にセットしている場合も含む)し、new_headのフラグが既にRB_PAGE_HEADがセットされていた場合
- next_pageのフラグをRB_PAGE_UPDATEに変更(既にセットしている場合も含む)し、new_headのフラグにRB_PAGE_HEADをセットした後にnext_pageのフラグをRB_PAGE_NORMALに変更できた場合
- 返り値 -1
- エラー
となる