Sun Studio 12: スレッドアナライザユーザーズガイド

付録 A スレッドアナライザのユーザー API

スレッドアナライザは、OpenMP 指令、POSIX スレッド、および Solaris スレッドの提供する大半の標準同期化 API および構造を認識できます。ただし、ユーザー定義の同期化機構は認識できず、コードにそうした同期化機構が含まれていると、誤検出データ競合を報告することがあります。たとえばスレッドアナライザは、手動コーディングされたアセンブリ言語コードで実装されたスピンロックを認識できません。

コードにユーザー定義の同期化機構が含まれる場合は、そうした同期化機構を特定できるよう、スレッドアナライザがサポートするユーザー API をプログラムに挿入してください。特定することによって、スレッドアナライザは同期化機構であることを認識し、誤検出の数を減らすことができます。次は、ユーザー API の一覧です。

A.1 スレッドアナライザのユーザー API

表 A–1 スレッドアナライザのユーザー 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 のマニュアルページを参照してください。

A.2 そのほかの認識される API

後述の節では、スレッドアナライザが認識するスレッド API の詳細情報を示します。

A.2.1 POSIX スレッド 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()

A.2.2 Solaris スレッド API

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()

A.2.3 メモリー割り当て API

calloc()

malloc()

realloc()

valloc()

memalign()

A.2.4 OpenMP API

詳細は、『Sun Studio 12: OpenMP API User’s Guide』を参照してください。