スレッドアナライザは、OpenMP 指令、POSIX スレッド、および Solaris スレッドの提供する大半の標準同期化 API および構造を認識できます。ただし、ユーザー定義の同期化機構は認識できず、コードにそうした同期化機構が含まれていると、誤検出データ競合を報告することがあります。たとえばスレッドアナライザは、手動コーディングされたアセンブリ言語コードで実装されたスピンロックを認識できません。
コードにユーザー定義の同期化機構が含まれる場合は、そうした同期化機構を特定できるよう、スレッドアナライザがサポートするユーザー API をプログラムに挿入してください。特定することによって、スレッドアナライザは同期化機構であることを認識し、誤検出の数を減らすことができます。次は、ユーザー API の一覧です。
|
tha_notify_acquire_lock(id)() |
プログラムがユーザー定義のロックの取得を試みる直前に挿入します。 |
|
tha_notify_lock_acquired(id)() |
ユーザー定義のロックが正常に取得された直後に挿入します。 |
|
tha_notify_writelock_acquired(id)() |
ユーザー定義の読み取り/書き込みロックが書き込みモードで正常に取得された直後に挿入します。 |
|
tha_notify_readlock_acquired(id)() |
ユーザー定義の読み取り/書き込みロックが読み取りモードで正常に取得された直後に挿入します。 |
|
tha_notify_lock_released(id)() |
ユーザー定義のロック (読み取り/書き込みロックを含む) が正常に解除された直後に挿入します。 |
|
tha_notify_sync_post_begin(id)() |
ユーザー定義の同期後の処理を実行する直前に挿入します。 |
|
tha_notify_sync_post_end(id)() |
ユーザー定義の同期後の処理を実行した直後に挿入します。 |
|
tha_notify_sync_wait_begin(id)() |
ユーザー定義の同期待ち処理を実行する直前に挿入します。 |
|
tha_notify_sync_wait_end(id)() |
ユーザー定義の同期待ち処理を実行した直後に挿入します。 |
C/C++ 版と Fortran 版の API が用意されています。 API 呼び出しは どれも 1 つの引数 ID を取ります。この ID 値で、同期化オブジェクトを一意に識別するようにします。
C/C++ 版の API では、この引数の型は uintptr_t であり、32 ビットモードで 4 バイトの長さ、64 ビットモードで 8 バイトの長さです。これら API を呼び出すときは、必ず、 C/C++ ソースファイルに #include <tha_interface.h> のインクルードを追加します。
Fortran 版の API では、引数の型は tha_sobj_kind の整数で、32 ビットおよび 64 ビットのどちらのモードでも長さは 8 バイトです。これら API を呼び出すときは、必ず、 Fortran ソースファイルに "tha_finterface.h" を追加します。同期化オブジェクトを一意に識別するため、引数 ID は同期化オブジェクトごとに異なる値を持つようにします。これを行う 1 つの方法は、同期化オブジェクトのアドレス値を ID に利用することです。次のコード例では、API を用いて誤検出データ報告を回避する方法を示します。
# include <tha_interface.h>
...
/* 初期状態では ready_flag の値は 0 */
...
/* スレッド 1: 生産者 */
100 data = ...
101 pthread_mutex_lock (&mutex);
tha_notify_sync_post_begin ((uintptr_t) &ready_flag);
102 ready_flag = 1;
tha_notify_sync_post_end ((uintptr_t) &ready_flag);
103 pthread_cond_signal (&cond);
104 pthread_mutex_unlock (&mutex);
/* スレッド 2: 消費者 */
200 pthread_mutex_lock (&mutex);
tha_notify_sync_wait_begin ((uintptr_t) &ready_flag);
201 while (!ready_flag) {
202 pthread_cond_wait (&cond, &mutex);
203 }
tha_notify_sync_wait_end ((uintptr_t) &ready_flag);
204 pthread_mutex_unlock (&mutex);
205 ... = data;
ユーザー API の詳細は、libtha.3 のマニュアルページを参照してください。
後述の節では、スレッドアナライザが認識するスレッド API の詳細情報を示します。
|
pthread_mutex_lock() |
|
pthread_mutex_trylock() |
|
pthread_mutex_unlock() |
|
pthread_rwlock_rdlock() |
|
pthread_rwlock_tryrdlock() |
|
pthread_rwlock_wrlock() |
|
pthread_rwlock_trywrlock() |
|
pthread_rwlock_unlock() |
|
pthread_create() |
|
pthread_join() |
|
pthread_cond_signal() |
|
pthread_cond_broadcast() |
|
pthread_cond_wait() |
|
pthread_cond_timedwait() |
|
pthread_cond_reltimedwait_np() |
|
pthread_barrier_init() |
|
pthread_barrier_wait() |
|
pthread_spin_lock() |
|
pthread_spin_unlock() |
|
pthread_spin_trylock() |
|
pthread_mutex_timedlock() |
|
pthread_mutex_reltimedlock_np() |
|
pthread_rwlock_timedrdlock() |
|
pthread_rwlock_reltimedrdlock_np() |
|
pthread_rwlock_timedwrlock() |
|
pthread_rwlock_reltimedwrlock_np() |
|
sem_post() |
|
sem_wait() |
|
sem_trywait() |
|
sem_timedwait() |
|
sem_reltimedwait_np() |
|
mutex_lock() |
|
mutex_trylock() |
|
mutex_unlock() |
|
rw_rdlock() |
|
rw_tryrdlock() |
|
rw_wrlock() |
|
rw_trywrlock() |
|
rw_unlock() |
|
thr_create() |
|
thr_join() |
|
cond_signal() |
|
cond_broadcast() |
|
cond_wait() |
|
cond_timedwait() |
|
cond_reltimedwait() |
|
sema_post() |
|
sema_wait() |
|
sema_trywait() |
|
calloc() |
|
malloc() |
|
realloc() |
|
valloc() |
|
memalign() |
詳細は、『Sun Studio 12: OpenMP API User’s Guide』を参照してください。