スレッドアナライザは、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』を参照してください。