The Thread Analyzer can recognize most standard synchronization APIs and constructs provided by OpenMP directives, POSIX threads, and Solaris threads. However, the tool cannot recognize user-defined synchronizations, and may report false positive data-races if you employ such synchronizations. For example, the tool cannot recognize spin locking that is implemented through hand-coded assembly-language code.
If your code includes user-defined synchronizations, insert the user APIs supported by the Thread Analyzer into the program to identify those synchronizations. This identification allows the Thread Analyzer to recognize the synchronizations and reduce the number of false positives. The user APIs are listed below:
tha_notify_acquire_lock(id)() |
Insert immediately before the program tries to acquire a user-defined lock. |
tha_notify_lock_acquired(id)() |
Insert immediately after a user-defined lock is successfully acquired. |
tha_notify_writelock_acquired(id)() |
Insert immediately after a user-defined read-write lock is successfully acquired in write mode. |
tha_notify_readlock_acquired(id)() |
Insert immediately after a user-defined read-write lock is successfully acquired in read mode. |
tha_notify_lock_released(id)() |
Insert immediately after a user-defined lock (including a read-write lock) is successfully released. |
tha_notify_sync_post_begin(id)() |
Insert immediately before a user-defined post synchronization is performed. |
tha_notify_sync_post_end(id)() |
Insert immediately after a user-defined post synchronization is performed. |
tha_notify_sync_wait_begin(id)() |
Insert immediately before a user-defined wait synchronization is performed. |
tha_notify_sync_wait_end(id)() |
Insert immediately after a user-defined wait synchronization is performed. |
A C/C++ version and a Fortran version of the APIs are provided. Each API call takes a single argument id, whose value should uniquely identify the synchronization object.
In the C/C++ version of the APIs, the type of the argument is uintptr_t, which is 4 bytes long in 32-bit mode and 8 bytes long in 64-bit mode. You need to add #include <tha_interface.h> to your C/C++ source file when calling any of the APIs.
In the Fortran version of the APIs, the type of the argument is integer of kind tha_sobj_kind which is 8-bytes long in both 32-bit and 64–bit mode. You need to add include "tha_finterface.h" to your Fortran source file when calling any of the APIs. To uniquely identify a synchronization object, the argument id should have a different value for each different synchronization object. One way to do this is to use the value of the address of the synchronization object as the ID. The following code example shows how to use the API to avoid a false positive data-race:
# 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;
For more information on the user APIs, see the libtha.3 man page.
The following sections detail the threading APIs which the Thread Analyzer recognizes:
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() |
See the Sun Studio 12: OpenMP API User’s Guide for more information.