EN JA
COUNTER(9)
COUNTER(9) FreeBSD Kernel Developer's Manual COUNTER(9)

名称

counterSMP に適したカーネルカウンタの実装

書式

#include < sys/types.h>
#include < sys/systm.h>
#include < sys/counter.h>

counter_u64_t
counter_u64_alloc( int wait);

void
counter_u64_free( counter_u64_t c);

void
counter_u64_add( counter_u64_t c, int64_t v);

void
counter_enter();

void
counter_exit();

void
counter_u64_add_protected( counter_u64_t c, int64_t v);

uint64_t
counter_u64_fetch( counter_u64_t c);

void
counter_u64_zero( counter_u64_t c);

#include < sys/sysctl.h>

SYSCTL_COUNTER_U64( parent, nbr, name, access, ptr, val, descr);

SYSCTL_ADD_COUNTER_U64( ctx, parent, nbr, name, access, ptr, descr);

解説

counter は、(統計データを集めるような) あらゆる目的のために利用することができる、カウンタを作成する一般的な機能です。 counter は、いくつかのカーネルスレッドが同時に更新するとき、損失がないことが保証されます。しかしながら、 counter は、呼び出しているスレッドをブロックせず、また atomic(9) 操作は、更新のために使用されず、そのため、あらゆるコンテキストに割り込みせずに、カウンタを使用することができます。さらに、 counter を、グローバル変数で単純な演算より速く更新して、 counter には、SMP 環境のための特別な、最適化があります。したがって、 counter は、性能に重大なコードのパスでアカウントするのに適していると考えられます。
counter_u64_alloc( how)
新しい 64 ビットの符号なしカウンタを割り付けます。 wait 引数は、 malloc(9) のウェートフラグで、 M_NOWAIT または M_WAITOK のいずれかであるべきです。 M_WAITOK が指定されるなら、動作が、失敗するかもしれません。
counter_u64_free( c)
以前に割り付けられたカウンタ c を解放します。
counter_u64_add( c, v)
vc に追加します。 KPI は、ラップアラウンド (wraparound) からのあらゆる保護を保証しません。
counter_enter()
enter モードによって、 counter_u64_add_protected() によっていくつかのカウンタを安全に更新することができます。いくつかのマシンにおいて、これは、 critical(9) セクションに拡張し、一方、他のものは、nop です。 「実装の詳細」 を参照してください。
counter_exit()
いくつかのカウンタを更新するための exit モード。
counter_u64_add_protected( c, v)
counter_u64_add() と同じですが、 counter_enter() によって先導されるべきです。
counter_u64_fetch( c)
カウンタ c のスナップショットを取ります。取得されたデータは、いつでも実際の累積された値を反映することは保証されていません。
counter_u64_zero( c)
カウンタ c をクリアし、それを 0 に設定します。
SYSCTL_COUNTER_U64( parent, nbr, name, access, ptr, val, descr)
counter を表わす静的な sysctl oid を宣言します。 ptr 引数は、割り付けられた counter_u64_t へのポインタであるべきです。 oid の読み込みは、 counter_u64_fetch() によって取得された値を返します。 0 にされた oid へのあらゆる書き込み。
SYSCTL_ADD_COUNTER_U64( ctx, parent, nbr, name, access, ptr, descr)
counter を表わす sysctl oid を作成します。 ptr 引数は、割り付けられた counter_u64_t へのポインタであるべきです。 oid の読み込みは、 counter_u64_fetch() によって取得された値を返します。 0 にされた oid へのあらゆる書き込み。

実装の詳細

すべてのアーキテクチャにおいて、 counter は、CPU の間の変数の共有された使用のために CPU 間バストラフィックを回避するために、メモリに特別に整列された CPU ごとのデータフィールドを使用して実装されます。これらは、 UMA_ZONE_PCPU uma(9) ゾーンを使用して割り付けられます。更新操作は、単に、現在の CPU にプライベートであるフィールドにタッチします。取って来ることの操作は、すべての CPU ごとのフィールドを通してループし、すべてのフィールドのスナップショットの合計を取得します。

amd64 において、 counter は、プリエンプション (preemption) と割り込みに対して安全な、現在の CPU のためのプライベートなデータで動作して、ロックのセマンティクスのない単一の命令として実装されます。

i386 アーキテクチャにおいて、マシンがが cmpxchg8 命令をサポートするなら、この命令が使用されます。マウチ命令シーケンスは、amd64 の単一命令の実装として同じ保証を提供します。

カウンタを更新するいくつかのアーキテクチャにおいて、 critical(9) セクションを要求します。

歴史

counter 機能は、 FreeBSD 10.0 ではじめて登場しました。

作者

counter 機能は、 Gleb SmirnoffKonstantin Belousov によって書かれました。
April 3, 2013 FreeBSD