一群のスレッドが check_bad_array() を同時に呼び出し、配列 data_array に壊れている要素がないかどうかをチェックします。各スレッドはそれぞれ配列の異なる部分をチェックします。スレッドは要素が壊れれていることを発見すると、大域共有変数 is_bad の値を true に設定します。
20 volatile int is_bad = 0;
...
100 /*
102 * それぞれのスレッドは、割り当てられた data_array の一部をチェックし、
102 * 不正なデータ要素が見つかったら大域フラグ is_bad に 1 を代入します。
103 */
104 void check_bad_array(volatile data_t *data_array, unsigned int thread_id)
105 {
106 int i;
107 for (i=my_start(thread_id); i<my_end(thread_id); i++) {
108 if (is_bad)
109 return;
110 else {
111 if (is_bad_element(data_array[i])) {
112 is_bad = 1;
113 return;
114 }
115 }
116 }
117 }
行 108 の is_bad の read と行 112 の is_bad への write との間にデータ競合があります。ただし、このデータ競合が最終結果の正確さに影響することはありません。
is_bad の初期値はゼロです。スレッドは is_bad の更新時に、この変数に値 1 を代入します。すなわち、スレッドは is_bad 用の同じメモリーバイト内の同じビットに 1 をストアします。現在のアーキテクチャーでは、そうしたストアは不可分 (アトミック) とみなして差し支えありません。このため、スレッドによる is_bad の読み取り時、読み取られる値は 1 かゼロのいずれかです。is_bad に値 1 が代入される前に 、is_bad のチェックが行われる (行 108) と 、スレッドは for ループの実行を継続します。その間、別のスレッドが is_bad に 1 を代入しても (行 112)、最終結果は変わりません。このことは、スレッドが必要以上に長い時間 for ループを実行したことを意味するだけです。