Oracle® Solaris Studio 12.4: Thread Analyzer User's Guide

Exit Print View

Updated: December 2014
 
 

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
Routine Name
Description
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.