Man Page libtha.3
NAME
libtha - API that can be used in conjunction with the Sun
Studio Thread Analyzer (THA)
SYNOPSIS -- C and C++ Version of the API
#include "tha_interface.h"
void tha_notify_acquire_lock (uintptr id);
void tha_notify_lock_acquired (uintptr id);
void tha_notify_writelock_acquired (uintptr id);
void tha_notify_readlock_acquired (uintptr id);
void tha_notify_lock_released (uintptr id);
void tha_notify_sync_post_begin (uintptr id);
void tha_notify_sync_post_end (uintptr id);
void tha_notify_sync_wait_begin (uintptr id);
void tha_notify_sync_wait_end (uintptr id);
SYNOPSIS -- Fortran Version of the API
include "tha_finterface.h"
subroutine tha_notify_acquire_lock (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_lock_acquired (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_writelock_acquired (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_readlock_acquired (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_lock_released (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_sync_post_begin (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_sync_post_end (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_sync_wait_begin (id)
integer(kind=tha_sobj_kind) :: id
subroutine tha_notify_sync_wait_end (id)
integer(kind=tha_sobj_kind) :: id
DESCRIPTION
The shared object, libtha.so, provides an API that can be
used in conjunction with the Sun Studio Thread Analyzer.
The Thread Analyzer can recognize most standard synchroniza-
tion APIs and constructs provided by OpenMP, POSIX threads,
and Solaris threads. However, the tool cannot recognize
roll-your-own style synchronizations, and may report false
data-races if such synchronizations are used. For example,
the tool cannot recognize spin locking implemented using
hand-coded assembly.
If your program includes roll-your-own style synchroniza-
tions, then you can insert calls to the libtha.so API in the
program to inform the Thread Analyzer of those synchroniza-
tions. This allows the tool to recognize the synchroniza-
tions, thus reducing the number of false data-races
reported.
The libtha.so API consists of the following routines:
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 has been acquired suc-
cessfully.
tha_notify_writelock_acquired(): This routine can be called
immediately after a user-defined read-write lock has been
acquired successfully in write mode.
tha_notify_readlock_acquired(): This routine can be called
immediately after a user-defined read-write lock has been
acquired successfully in read mode.
tha_notify_lock_released(): This routine can be called
immediately after a user-defined lock (including a read-
write lock) has been released successfully.
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 has
been 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 has
been performed.
In the C/C++ version of the libtha API, each function takes
a single argument, id, whose value should uniquely identify
the synchronization object. The type of id is uintptr, which
is defined in <sys/types.h>. The size of id is 4 bytes in
32-bit mode and 8 bytes in 64-bit mode.
In the Fortran version of the libtha API, each subroutine
takes a single argument, id, whose value should uniquely
identify the synchronization object. The type of id is
integer, and its size is given by tha_sobj_kind which is
defined in tha_finterface.h to be 8 bytes in both 32-bit
mode and 64-bit mode.
To uniquely identify a synchronization object, you should
make sure that the argument id has a different value for
each different synchronization object. One way to do this
is to let the value of id be the address of the synchroniza-
tion object. That address can be obtained using the &
operator in C/C++, or using the loc() library routine in
Fortran. See Example 1 under the EXAMPLE section below.
Note that libtha.so provides only "hook" (or dummy) entry
points for the API routines. This allows programs that call
these routines and are linked with libtha.so to run under a
Thread Analyzer experiment, as well as outside of such an
experiment.
If the program is run under a Thread Analyzer experiment
(i.e., the program is run under collect -r on), then the
routines will have effect, and the Thread Analyzer will be
notified about synchronizations in the program.
If the program is run outside a Thread Analyzer experiment
(i.e., the program is not run under collect -r on), then the
API routines will not have any effect.
See collect(1) for more information about performing a
Thread Analyzer experiment.
LINKING WITH libtha.so
The shared object, libtha.so can be linked into the execut-
able by using the compiler option -xinstrument=datarace.
This option causes the source code to be instrumented for
data-race detection at compile-time, and causes libtha.so be
linked in at the link stage. Examples:
cc [ <options> ] -xinstrument=datarace <file>
CC [ <options> ] -xinstrument=datarace <file>
f90 [ <options> ] -xinstrument=datarace <file>
If you do not wish the source code to be instrumented at
compile-time, then use -ltha with the cc, CC, or f90 command
to explicitly link in libtha.so at the link stage. Examples:
cc [ <options> ] -ltha <file>
CC [ <options> ] -ltha <file>
f90 [ <options> ] -ltha <file>
EXAMPLES
Example 1:
The following Fortran example shows how
tha_notify_acquire_lock() and tha_notify_release_lock() can
be used to inform the Thread Analyzer that a user-defined
lock has been aquired and released, respectively. In this
example, the address of the lock object is used as id to
uniquely identify the object.
include "tha_finterface.h"
integer :: my_lock
integer(kind= tha_sobj_kind) :: id
id = loc (my_lock)
tha_notify_acquire_lock (id)
call my_lock_routine(my_lock)
tha_notify_lock_acquired (id)
...
call my_unlock_routine(my_lock)
tha_notify_lock_released (id)
Example 2:
The following C/C++ example shows how
tha_notify_sync_wait_begin() and tha_notify_sync_wait_end()
can be used to inform the Thread Analyzer of the start and
end of a user-defined wait synchronization, respectively.
In addition, the example shows how
tha_notify_sync_post_begin() and tha_notify_sync_post_end()
can be used immediately before and after a post synchroniza-
tion, respectively.
#include "tha_interface.h"
int busy_wait = 1;
/* Code executed by thread 1 */
tha_notify_sync_wait_begin(&busy_wait);
while (busy_wait) {
no_op();
}
tha_notify_sync_wait_end(&busy_wait);
/* Code executed by thread 2 */
tha_notify_sync_post_begin(&busy_wait);
busy_wait = 0;
tha_notify_sync_post_end(&busy_wait);
ATTRIBUTES
_________________________________________________________
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
|__________________|______________________________________|
| Stability Level | Unstable. This interface is provided |
| | to give developers early access to |
| | new technology for which a more |
| | stable solution is anticipated in |
| | the future. |
|__________________|______________________________________|
SEE ALSO
tha(1), analyzer(1), collect(1), collector(1), er_print(1),
attributes(5), and the Performance Analyzer manual.