Oracle Solaris Studio 12.2: スレッドアナライザユーザーズガイド

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

コードにユーザー定義の同期が含まれる場合、この同期を識別するために、スレッドアナライザがサポートするユーザー API をプログラムに挿入します。このように識別することによって、スレッドアナライザは同期を認識でき、誤検知の数を減らすことができます。スレッドアナライザのユーザー API は libtha.so に定義されます。その一覧を次の表に示します。

表 A–1 スレッドアナライザユーザー API

tha_notify_acquire_lock()

プログラムがユーザー定義のロックを取得しようとする直前に呼び出せます。 

tha_notify_lock_acquired()

ユーザー定義のロックが正しく取得された直後に呼び出せます。 

tha_notify_acquire_writelock()

プログラムが書き込みモードでユーザー定義の読み取り/書き込みロックを取得しようとする直前に呼び出せます。 

tha_notify_writelock_acquired()

書き込みモードでユーザー定義の読み取り/書き込みロックが正しく取得された直後に呼び出せます。 

tha_notify_acquire_readlock()

プログラムが読み取りモードでユーザー定義の読み取り/書き込みロックを取得しようとする直前に呼び出せます。 

tha_notify_readlock_acquired()

読み取りモードでユーザー定義の読み取り/書き込みロックが正しく取得された直後に呼び出せます。 

tha_notify_release_lock()

ユーザー定義のロックまたは読み取り/書き込みロックが解除される直前に呼び出せます。 

tha_notify_lock_released()

ユーザー定義のロック (読み取り/書き込みロックを含む) が正しく解除された直後に呼び出せます。 

tha_notify_sync_post_begin()

ユーザー定義の送信同期が実行される直前に呼び出せます。 

tha_notify_sync_post_end()

ユーザー定義の送信同期が実行された直後に呼び出せます。 

tha_notify_sync_wait_begin()

ユーザー定義の待機同期が実行される直前に呼び出せます。 

tha_notify_sync_wait_end()

ユーザー定義の待機同期が実行された直後に呼び出せます。 

C/C++ バージョンと Fortran バージョンの API が用意されています。それぞれの API 呼び出しは単一の引数 ID を取り、その値は同期オブジェクトを一意に識別します。

C/C++ バージョンの API では、引数の型は uintptr_t であり、これは 32 ビットモードでは 4 バイト長、64 ビットモードでは 8 バイト長になります。このバージョンの API を呼び出すときには、#include <tha_interface.h> を C/C++ ソースファイルに追加する必要があります。

Fortran バージョンの API では、引数の型は tha_sobj_kind の整数であり、これは 32 ビットおよび 64 ビットモードで 8 バイト長になります。このバージョンの API を呼び出すときには、#include "tha_finterface.h" を Fortran ソースファイルに追加する必要があります。

同期オブジェクトが一意に識別されるよう、引数の ID には同期オブジェクトごとに異なる値を割り当てる必要があります。これを行う 1 つの方法は、同期オブジェクトのアドレスの値を ID として使用することです。次のコード例では、API を使用して誤検知のデータの競合を回避する方法を示しています。


例 A–1 スレッドアナライザ API を使用して誤検知のデータの競合を回避する例

# include <tha_interface.h>
...
/* Initially, the ready_flag value is zero */
...
/* Thread 1: Producer */
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);
 
 
/* Thread 2: Consumer */
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) のマニュアルページを参照してください。