APIs Recognized by Thread Analyzer
Thread Analyzer can recognize most standard synchronization APIs and constructs provided by
OpenMP, POSIX threads, and Solaris threads. However, the tool cannot recognize user-defined
synchronizations, and might 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.
Thread Analyzer User APIs
If your code includes user-defined synchronizations, insert user APIs supported by Thread
Analyzer into the program to identify those synchronizations. This identification enables Thread
Analyzer to recognize the synchronizations and reduce the number of false positives. Thread Analyzer
user APIs are defined in libtha.so and are listed below.
Table A-1 Thread Analyzer User APIs
|
|
tha_notify_acquire_lock()
|
This routine can be called immediately before the program tries to acquire a user-defined
lock.
|
tha_notify_lock_acquired()
|
This routine can be called immediately after a user-defined lock is successfully
acquired.
|
tha_notify_acquire_writelock()
|
This routine can be called immediately before the program tries to acquire a user-defined
read/write lock in write mode.
|
tha_notify_writelock_acquired()
|
This routine can be called immediately after a user-defined read/write lock is successfully
acquired in write mode.
|
tha_notify_acquire_readlock()
|
This routine can be called immediately before the program tries to acquire a user-defined
read/write lock in read mode.
|
tha_notify_readlock_acquired()
|
This routine can be called immediately after a user-defined read/write lock is successfully
acquired in read mode.
|
tha_notify_release_lock()
|
This routine can be called immediately before a user-defined lock or read/write lock is to be
released.
|
tha_notify_lock_released()
|
This routine can be called immediately after a user-defined lock or read/write lock is
successfully released.
|
tha_notify_sync_post_begin()
|
This routine can be called immediately before a user-defined post synchronization is
performed.
|
tha_notify_sync_post_end()
|
This routine can be called immediately after a user-defined post synchronization is
performed.
|
tha_notify_sync_wait_begin()
|
This routine can be called immediately before a user-defined wait synchronization is
performed.
|
tha_notify_sync_wait_end()
|
This routine can be called immediately after a user-defined wait synchronization is
performed.
|
tha_check_datarace_mem()
|
This routine instructs Thread Analyzer to monitor or ignore accesses to a specified block of
memory when doing data race detection.
|
tha_check_datarace_thr()
|
This routine instructs Thread Analyzer to monitor or ignore memory accesses by one or more
threads when doing data race detection.
|
|
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.
Example A-1 Example Using Thread Analyzer APIs to Avoid False
Positive Data Races
# 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.
Other Recognized APIs
The following sections detail the threading APIs which Thread Analyzer recognizes.
POSIX Thread APIs
See the Multithreaded Programming Guide in the Oracle
Solaris documentation for more information about these APIs.
| pthread_detach() | | pthread_mutex_init() | | pthread_mutex_lock() | | pthread_mutex_timedlock() | | pthread_mutex_reltimedlock_np() | | pthread_mutex_timedlock() | | 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_rwlock_init() | | 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()
|
|
Oracle Solaris Thread APIs
See the Multithreaded Programming Guide in the Oracle
Solaris documentation for more information about these APIs.
| mutex_init() | | mutex_lock() | | mutex_trylock() | | mutex_unlock() | | rw_rdlock() | | rw_tryrdlock() | | rw_wrlock() | | rw_trywrlock() | | rw_unlock() | | rwlock_init() | | thr_create() | | thr_join() | | cond_signal() | | cond_broadcast() | | cond_wait() | | cond_timedwait() | | cond_reltimedwait() | | sema_post() | | sema_wait() | | sema_trywait() |
|
Memory Allocation APIs
| calloc() | | malloc() | | realloc() | | valloc() | | memalign() | | free() |
|
See the malloc(3C) man page for information about the memory allocation
APIs.
Memory Operations APIs
| memcpy() | | memccpy() | | memmove() | | memchr() | | memcmp() | | memset() |
|
See the memcpy(3C) man page for information about the memory operations
APIs.
String Operations APIs
| strcat() | | strncat() | | strlcat() | | strcasecmp() | | strncasecmp() | | strchr() | | strrchr() | | strcmp() | | strncmp() | | strcpy() | | strncpy() | | strlcpy() | | strcspn() | | strspn() | | strdup() | | strlen() | | strpbrk() | | strstr() | | strtok() |
|
See the strcat(3C) man page for information about the string operations
APIs.
Realtime Library APIs
| sem_post() | | sem_wait() | | sem_trywait() | | sem_timedwait() |
|
Atomic Operations (atomic_ops) APIs
| atomic_add() | | atomic_and() | | atomic_cas() | | atomic_dec() | | atomic_inc() | | atomic_or() | | atomic_swap() |
|
OpenMP APIs
Thread Analyzer recognizes OpenMP synchronizations, such as barriers, locks, critical regions,
atomic regions, and taskwait.
See the Oracle Solaris Studio 12.4: OpenMP API User’s Guide
for more information.