Oracle Solaris Studio 12.2:线程分析器用户指南

附录 A 线程分析器可识别的 API

线程分析器可以识别由 OpenMP 指令、POSIX 线程和 Solaris 线程提供的大多数标准同步 API 和构造。但是,该工具无法识别用户自定义的同步,如果使用了这样的同步,可能会误报数据争用。例如,该工具无法识别通过手编汇编语言代码实现的自旋锁。

A.1 线程分析器用户 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()

可以在执行用户自定义的等待同步之后立即调用此例程。 

提供了 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) 手册页。

A.2 其他可识别的 API

以下几节将详细介绍线程分析器可识别的线程 API。

A.2.1 POSIX 线程 API

有关这些 API 的更多信息,请参见 Oracle Solaris 开发者文档集的《多线程编程指南》

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()

A.2.2 Solaris 线程 API

有关这些 API 的更多信息,请参见 Oracle Solaris 开发者文档集的《多线程编程指南》

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()

A.2.3 内存分配 API

calloc()

malloc()

realloc()

valloc()

memalign()

有关内存分配 API 的信息,请参见 malloc(3C) 手册页。

A.2.4 内存操作 API

memcpy()

memmove()

memchr()

memcmp()

memset()

有关内存操作 API 的信息,请参见 memcpy(3C) 手册页。

A.2.5 字符串操作 API

strcat()

strncat()

strlcat()

strcasecmp()

strncasecmp()

strchr()

strrchr()

strcmp()

strncmp()

strcpy()

strncpy()

strlcpy()

strcspn()

strspn()

strdup()

strlen()

strpbrk()

strstr()

strtok()

有关字符串操作 API 的信息,请参见 strcat(3C) 手册页。

A.2.6 OpenMP API

线程分析器可识别 OpenMP 同步,例如屏障、锁、临界区域、原子区域和任务等待 (taskwait)。

有关更多信息,请参见《Oracle Solaris Studio 12.2:OpenMP API 用户指南》