Multithreaded Programming Guide

Timers, Alarms, and Profiling

The "End of Life" announcements for per-LWP timers (see timer_create(3R)) and per-thread alarms (see alarm(2) or setitimer(2)) were made in the Solaris 2.5 release. Both features are now supplemented with the per-process variants described in this section.

Originally, each LWP had a unique Realtime interval timer and alarm that a thread bound to the LWP could use. The timer or alarm delivered one signal to the thread when the timer or alarm expired.

Each LWP also had a virtual time or profile interval timer that a thread bound to the LWP could use. When the interval timer expired, either SIGVTALRM or SIGPROF, as appropriate, was sent to the LWP that owned the interval timer.

Per-LWP POSIX Timers

In the Solaris 2.3 and 2.4 releases, the timer_create(3R) function returned a timer object whose timer ID was meaningful only within the calling LWP and whose expiration signals were delivered to that LWP. Because of this, the only threads that could use the POSIX timer facility were bound threads.

Even with this restricted use, POSIX timers in Solaris 2.3 and 2.4 multithreaded applications were unreliable about masking the resulting signals and delivering the associated value from the sigvent structure.

With the Solaris 2.5 release, an application that is compiled defining the macro _POSIX_PER_PROCESS_TIMERS, or with a value greater that 199506L for the symbol _POSIX_C_SOURCE, can create per-process timers.

Applications compiled with a release before the Solaris 2.5 release, or without the feature test macros, will continue to create per-LWP POSIX timers. In some future release, calls to create per-LWP timers will return per-process timers.

The timer IDs of per-process timers are usable from any LWP, and the expiration signals are generated for the process rather than directed to a specific LWP.

The per-process timers are deleted only by timer_delete(3R) or when the process terminates.

Per-Thread Alarms

In the Solaris 2.3 and 2.4 releases, a call to alarm(2) or setitimer(2) was meaningful only within the calling LWP. Such timers were deleted automatically when the creating LWP terminated. Because of this, the only threads that could use these were bound threads.

Even with this restricted use, alarm() and setitimer() timers in Solaris 2.3 and 2.4 multithreaded applications were unreliable about masking the signals from the bound thread that issued these calls. When such masking was not required, then these two system calls worked reliably from bound threads.

With the Solaris 2.5 release, an application linking with -lpthread (POSIX) threads will get per-process delivery of SIGALRM when calling alarm(). The SIGALRM generated by alarm() is generated for the process rather than directed to a specific LWP. Also, the alarm is reset when the process terminates.

Applications compiled with a release before the Solaris 2.5 release, or not linked with -lpthread, will continue to see a per-LWP delivery of signals generated by alarm() and setitimer().

In some future release, calls to alarm() or to setitimer() with the ITIMER_REAL flag will cause the resulting SIGALRM to be sent to the process. For other flags, setitmer() will continue to be per-LWP. Flags other than the ITIMER_REAL flag, used by setitimer(), will continue to result in the generated signal being delivered to the LWP that issued the call, and so are usable only from bound threads.

Profiling

You can profile each LWP with profil(2), giving each LWP its own buffer, or sharing buffers between LWPs. Profiling data is updated at each clock tick in LWP user time. The profile state is inherited from the creating LWP.