プログラムのパフォーマンス解析

データの保護方法

以下の注釈は、関数定義の外側でも内側でも使用可能です。注釈中で記述される名前はすべて、もあらかじめ宣言されている必要があります。

NOTE(MUTEX_PROTECTS_DATA(Mutex, DataNameList))

NOTE(RWLOCK_PROTECTS_DATA(Rwlock, DataNameList))

NOTE(SCHEME_PROTECTS_DATA("description", DataNameList))

最初の 2 つの注釈は、指定されたデータがアクセスされる場合は、必ずロックが保持されるよう、ロック lint に指示します。

3 番目の注釈 SCHEME_PROTECTS_DATA は、データが相互排他ロックも読み取り書き込みロックのいずれも持たない場合に、データをどのように保護するかを説明します。スキーマに対して提供される description はただのテキストであり、プログラム的には重要ではありません。ロック lint は、指定されたデータを完全に無視することで対応します。description の部分は自由に指定できます。

上記の注釈の使用方法を説明するために、いくつかの例を示します。最初の例はとてもシンプルで、ロックが 2 つの変数を保護することを示しています。


mutex_t lock1;
int a,b;
NOTE(MUTEX_PROTECTS_DATA(lock1, a b))

次の例では、さまざまな可能性が示されています。struct foo のメンバーの一部は静的なロックで保護され、ほかのメンバーは foo 上のロックで保護されています。そして、foo のほかのメンバーは、その利用上の規則によって保護されています。


mutex_t lock1;
struct foo {
    mutex_t lock;
    int mbr1, mbr2;
    struct {
        int mbr1, mbr2;
        char* mbr3;
    } inner;
    int mbr4;
};
NOTE(MUTEX_PROTECTS_DATA(lock1, foo::{mbr1 inner.mbr1}))
NOTE(MUTEX_PROTECTS_DATA(foo::lock, foo::{mbr2 inner.mbr2}))
NOTE(SCHEME_PROTECTS_DATA("convention XYZ", inner.mbr3))

1 つのデータは 1 つの手段においてのみ保護が可能です。1 つのデータに対して、保護に関する複数の注釈が使用されている場合 (前記の 3 つ以外だけでなく、READ_ONLY_DATA も含みます)、後の注釈によって自動的に以前の注釈は上書きされます。これによって、1、2 の例外を除く全メンバーが同じ方法で保護されるという構造記述が容易になります。たとえば、以下の例の struct BAR のメンバーのほとんどは struct foo 上のロックによって保護されますが、ただ 1 つだけはグローバルロックによって保護されます。


mutex_t lock1;
typedef struct {
    int mbr1, mbr2, mbr3, mbr4;
} BAR;
NOTE(MUTEX_PROTECTS_DATA(foo::lock, BAR))
NOTE(MUTEX_PROTECTS_DATA(lock1, BAR::mbr3))