线程分析器可识别的 API
线程分析器可以识别由 OpenMP、POSIX 线程和 Solaris 线程提供的大多数标准同步 API 和构造。但是,该工具无法识别用户定义的同步,如果使用了这样的同步,可能会误报数据争用。例如,该工具无法识别通过手编汇编语言代码实现的自旋锁。
线程分析器用户 API
如果代码包含用户定义的同步,请将线程分析器支持的用户 API 插入该程序中来标识这些同步。通过此标识,线程分析器可识别这些同步并减少误报的数量。下面列出了在 libtha.so 中定义的线程分析器用户 API。
表 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()
|
可以在执行用户定义的等待同步之后立即调用此例程。
|
|
tha_check_datarace_mem()
|
该例程指示线程分析器在执行数据争用检测时监视或忽略对指定内存块的访问。
|
|
tha_check_datarace_thr()
|
该例程指示线程分析器在执行数据争用检测时监视或忽略一个或多个线程进行的内存访问。
|
|
提供了 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 应具有不同的值。其中一种做法是将同步对象的地址值用作 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) 手册页。
其他可识别的 API
以下几节将详细介绍线程分析器可识别的线程 API。
POSIX 线程 API
有关这些 API 的更多信息,请参见 Oracle Solaris 文档中的多线程编程指南。
| 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 线程 API
有关这些 API 的更多信息,请参见 Oracle Solaris 文档中的多线程编程指南。
| 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() |
|
内存分配 API
| calloc() | | malloc() | | realloc() | | valloc() | | memalign() | | free() |
|
有关内存分配 API 的信息,请参见 malloc(3C) 手册页。
内存操作 API
| memcpy() | | memccpy() | | memmove() | | memchr() | | memcmp() | | memset() |
|
有关内存操作 API 的信息,请参见 memcpy(3C) 手册页。
字符串操作 API
| strcat() | | strncat() | | strlcat() | | strcasecmp() | | strncasecmp() | | strchr() | | strrchr() | | strcmp() | | strncmp() | | strcpy() | | strncpy() | | strlcpy() | | strcspn() | | strspn() | | strdup() | | strlen() | | strpbrk() | | strstr() | | strtok() |
|
有关字符串操作 API 的信息,请参见 strcat(3C) 手册页。
实时库 API
| sem_post() | | sem_wait() | | sem_trywait() | | sem_timedwait() |
|
原子操作 (atomic_ops) API
| atomic_add() | | atomic_and() | | atomic_cas() | | atomic_dec() | | atomic_inc() | | atomic_or() | | atomic_swap() |
|
OpenMP API
线程分析器可识别 OpenMP 同步,例如屏障、锁、临界区域、原子区域和任务等待 (taskwait)。
有关更多信息,请参见Oracle Solaris Studio 12.4:OpenMP API 用户指南
。