トランザクションは、共有メモリー位置のセットを更新し、ロックによって制御されます。一般に、2 つのトランザクションが同じメモリー位置にアクセスする場合、同時に実行しないようにする必要があります。ロックをトランザクションに関連付ける最も適切な方法について、以下の例を使用して考えてみます。
// トランザクション 1
if (a > b) { a -= b; b = b / 2; }
...
// トランザクション 2
if (c > d) { c -= d; d = d / 2; }
...
// トランザクション 3
if (a > c) { a -= c; c = c / 2; }
...
// トランザクション 4
temp = x;
x = y;
y = temp;2 つのトランザクションが同じメモリー位置にアクセスする場合、それらは同じロックを使用して制御される必要があります。これを実現する最も簡単な方法は、メモリー位置のセットにロックを割り当てて、トランザクションが 2 つ以上のメモリー位置をアクセスする場合に、トランザクションでアクセスされるすべてのメモリー位置が同じロックを持つようにすることです。そして、アクセスするすべての変数に割り当てられたロックを使用して、トランザクションを制御する必要があります。
上記の例では、変数 a と b は、両方ともトランザクション 1 でアクセスされるため、同じロックを持つ必要があります。変数 c と d は、トランザクション 2 でアクセスされ、これも同じロックを持つ必要があります。トランザクション 3 では変数 a と c をアクセスするため、それらにも同じロックを使用する必要があり、それは b と d のロックと同じである必要があります。トランザクション 4 は x と y にアクセスするため、a、b、c、および d のロックとは異なる同じロックが必要です。
int abcd_lock;
int xy_lock;
// ...
ANNOTATE_LOCK_ACQUIRE(&abcd_lock);
if (a > b) { a -= b; b = b / 2; }
ANNOTATE_LOCK_RELEASE(&abcd_lock);
ANNOTATE_LOCK_ACQUIRE(&abcd_lock);
if (c > d) { c -= d; d = d / 2; }
ANNOTATE_LOCK_RELEASE(&abcd_lock);
ANNOTATE_LOCK_ACQUIRE(&abcd_lock );
if (a > c) { a -= c; c = c / 2; }
ANNOTATE_LOCK_RELEASE(&abcd_lock);
ANNOTATE_LOCK_ACQUIRE(&xy_lock);
temp = x;
x = y;
y = temp;
ANNOTATE_LOCK_RELEASE(&xy_lock);