NetBeans IDE 6.8 Beta with the C/C++/Fortran plugin features the Thread Microstates tool for observing the
execution states of threads. The tool shows an overall view of the changing runtime states
of your project's threads, and a more detailed view of the state of individual threads.
You can detect runtime problems in your applications that might not be detectable when
debugging your code.
This tutorial demonstrates how to use the Thread Microstates tool for C/C++ projects running on
Solaris 10 or OpenSolaris operating systems. The tool is supported only on Solaris operating systems
because Solaris microstate accounting technology and the DTrace utility are required to gather the thread state data.
The Thread Microstates tool runs by default when you run your NetBeans project.
If you are a Windows or MacOS X user and have a Solaris system available to you, note that you
can run the IDE locally on your PC or Mac and set up your project to use the Solaris system as a remote development host.
Remote development would enable you to use Thead Microstates
profiling tool and other Solaris-based tools even when you run the IDE in Windows or MacOS X.
The remote development feature is
only available in the C/C++/Fortran module for the NetBeans IDE.
See the
C/C++ Remote Development Tutorial for more information about how
to set up to build on a remote development host.
This tutorial uses a project running on a Solaris SPARC processor-based system. You can follow the steps
of the tutorial if you
run NetBeans IDE 6.8 on Solaris or OpenSolaris on SPARC-based or x86-based systems. Note that this
tutorial uses
"Solaris operating systems" to mean both OpenSolaris and Solaris 10 operating systems.
Solaris Microstate Accounting
Many operating systems gather CPU statistics with every CPU clock cycle, or at a fixed time interval. Solaris operating systems use a
technology called microstate accounting to gather statistics from the CPU and threads,
for every event. Each thread's activity is tracked and the system records the time when each thread transitions from one execution state to another.
These timestamps enable you to see how much time a thread spends running, sleeping, waiting, blocked, and so on. The technique enables very accurate
statistics to be gathered without adding significant system overhead.
Setting Up Your Solaris Environment for the Tutorial
In order to use the Thread Microstate tool, the Solaris user account that you use when you run NetBeans must have sufficient DTrace privileges to observe system behavior.
The user account must have the dtrace_user, dtrace_proc, and dtrace_kernel privileges.
To check your DTrace privileges, type the following at the command prompt: /bin/ppriv -v $$ | grep dtrace
If your account has the required privileges, the ppriv command should return a line similar to:
If your account doesn't have the required privileges, and you do not have administrator privileges or root access to your system, you should
ask your system administrator to add the dtrace_user, dtrace_proc, and dtrace_kernel privileges
to your account.
If you have administrator privileges or root access to your system, you can grant your user account the required privileges as described below.
To permanently grant required DTrace privileges to a user account:
Make sure the user account whose privileges you want to modify is logged out of the system.
Log in as superuser (root) or another administrator user.
Type the following at the command prompt, and replace username with the user account name you are modifying:
$ usermod -K defaultpriv=basic,dtrace_kernel,dtrace_user,dtrace_proc username
You can then log in to the user account, start the NetBeans IDE, and use the profiling tools with the DTrace data provider.
To temporarily grant required DTrace privileges to a user account:
Type the following to determine the process ID of the shell's process:
$ echo $$
Become superuser (root) or another administrator user.
Type the following, and replace process-ID with the process ID that was returned from the echo command :
$ ppriv -s I+dtrace_user,dtrace_proc,dtrace_kernelprocess-ID
All commands typed in the shell specified by process-ID now inherit the required privileges. The user account can start
the NetBeans IDE in this shell and use the profiling tools with the DTrace data provider.
Create the Project for the Tutorial
To explore the thread microstate profiling features, we'll create a new project from
the ProfilingDemo sample application, which is included in the IDE.
The ProfilingDemo application has three stages in which it performs two tasks repeatedly for 10
seconds, using three different techniques to generate some interesting activity to show in the profiling tools.
The first task is to write some data to a file,
and the second task is to perform some calculations. Each set of two tasks is performed a number of times that is equal
to the number of CPUs detected on the development host. For a single-processor system, the program performs the two tasks
one time. For a development host having 32 cores, the program performs the two tasks 32 times. You must press the Enter
key to begin each set of tasks, so you have to pay attention.
The ProfilingDemo's stages are as follows:
Sequential Demo is single-threaded and runs the two tasks, one after the other, each one for 10 seconds.
This can take some time on a system with a large number of CPUs because more sets of tasks are performed, one after another.
Parallel Demo is multithreaded and performs the same write to file and calculation tasks simultaneously in separate threads,
once for each CPU. This stage is much faster than the Sequential Demo on multicore machines because the same
number of tasks are performed as in the Sequential Demo, but they are executed simultateously. However, the threads are not
prevented from competively accessing the same data, which can lead to inaccurate results.
Pthread Mutex Demo is also multithreaded and performs the same write task and calculation tasks as the other demo stages. However,
the code uses mutual exclusion locks to prevent overlapping access to certain functions by multiple threads.
To create the ProfilingDemo Project
Open the New Project wizard by choosing File > New Project.
In the wizard, select the Samples category, and then the C/C++ subcategory.
Select the Profiling Demo sample as shown in the figure and click Next.
You can choose the name of the project and the location of the project. Here we
use the default ProfilingDemo_1 in our NetBeansProjects directory.
Click Finish to exit the wizard and create the project.
Check the Profiler Tools Manager
The profiler tools should be set up automatically to use default settings that make sense for
the platform and compiler tool chain that the IDE discovers. However, we will look in the Profiler Tools Manager
to make sure the Thread Microstates tool is selected, and that it will run when you run the project.
Select Tools > Profiler Tools to open the Profiler Tools Manager.
Select a Profiler Configuration that enables the Thread Microstates tool. In the Beta software
the configuration might be called C/C++ Profiling or something similar. You should see a checkmark
next to Thread Microstates in the Tools panel.
If you see an option for a Data Provider, select DTrace.
Select Profile on Run and click OK..
Build and Run the ProfilingDemo Project
(Optional) If you want the output of the project to be dislayed in the Output Window in NetBeans as shown in this tutorial,
right-click the ProfilingDemo project node and select Properties. In the Project Properties,
click the Run node in the Categories panel, and for Console Type select Output Window. Click OK.
Right-click the ProfilingDemo project node and select Build.
The Output tab shows the results of the build, similar to that shown below.
The compiler shown in the screenshot is the GNU C compiler, gcc. You can also use the Sun Studio tool collection's
cc compiler.
Right-click the ProfilingDemo project node and select Run.
Press Enter whenever you are prompted during the run of the ProfilingDemo project.
The Run Monitor tab opens to display the dynamic graph for Thread Microstate tool,
and possibly other tools if they were selected in the Profiler Tools Manager.
In the following screenshot, all the tools are displayed.
If you want to see all the tools, you might need to increase the size of the Run Monitor tab by clicking and dragging
the top border of the Run Monitor tab upwards.
Notice in the output window the ProfilingDemo program tells you what it is doing
so you can match it to the data that the IDE is representing graphically in the tools. For example,
the program displays how much memory it is allocating, performs calculations, and
then frees the memory. You can see the graphs reflect the program's activity. The Thread Microstates
tool shows an overview of the program's threads as they enter various execution states
during the project's run.
Explore Thread Microstates
The Thread Microstates graph in the Run Monitor window shows an overview of the program's threads as they enter various execution states
during the project's run. The Solaris microstate accounting feature uses the DTrace facility to provide fine-grained
information about the state of each thread as it enters and exits ten different execution states.
The Thread Microstates tool graphically shows summarized state information for all the threads
that are created during the project run. Only four states are shown: Sleeping, Waiting, Blocked, and Running. These states represent a
simplified or summary view of ten possible microstates, and give an overview of the states of all the threads running in your program.
For example, the time spent in the Running state represents all types of running states: running in user mode, running in system calls, running in page faults, running
in traps.
The screenshot below was taken at the beginning of the program's run, during the SEQUENTIAL DEMO portion, in which two tasks
are run one after the other in a single thread. The points where the thread is sleeping correspond to the
points where the program is waiting for you to press Enter.
Screenshot showing Thread Microstates for a single thread.
At the bottom of the Run Monitor window, notice there is a scroll bar. Click and drag it to the left and right
so that you can view the data in all the profiling tools, from the beginning of the run time to the end.
Notice in the screenshot below at about 0:28 seconds, the number of threads shown in Thread Microstates jumps to three
as the program enters the PARALLEL DEMO portion. The main thread launches two additional threads to run two tasks in
parallel, each in its own thread. You can see that there is a lot of time spent in the Waiting state (yellow) and the Sleeping state (blue),
and not so much in the Running state (green). No time is spent in the Blocked state (orange) during the PARALLEL DEMO portion because
this portion of the program does not implement any thread synchronization tactics such as mutex locks which would block threads.
Notice in the screenshot below at about 0:40 seconds, the Blocked microstate shown in orange appears for the first time
during the program run. This corresponds to the point where the program enters the PTHREAD MUTEX DEMO portion,
in which each thread uses mutual exclusion locks to prevent other threads from interfering at certain points. Each thread can only
run actively after it obtains the mutex lock. A thread is blocked when it tries to access a locked section of code when another thread
owns the mutex lock. The use of mutual exclusion locks prevents the threads from entering a data race condition, where the
threads have overlapping access to the same data.
Click the Thread Details button to display details about the thread microstates.
The Thread Details tab opens to display a graphic representation of all the threads run in the program, along with
a detailed state information.
screenshot showing the Thread Details tab
The Thread Details show the state transitions for each thread during the complete run time of the program. Lets explore this window
a bit to see what you can do here.
Move the mouse pointer on one of the colored areas of a thread and you see a popup displaying details about what is going on at that particular
moment. Details include the time when the data was taken, and the percentage of time spent in each thread states at that moment. When you move
the mouse pointer over the "Summary" area on the right, the popup displays the percentages for the thread's complete run
You can control what is shown in the Thread Details window by altering several settings:
Click the View Mode list to select the level of detail you want to see. The options go from simple to more complex, with the simplest view
showing only four generalized execution states, and the most complex view showing ten microstates.
Click the Show list, and select which type of threads to display. Finished Threads Only shows only those threads that have terminated
during the program run. Live Threads Only shows only threads that are still active when you open the thread details (***?) All Threads shows both live and finished threads.
Click on an individual thread and notice that the thread is highlighted. Then press the Shift key and click another thread to select
a range of threads. You can also select multiple threads that are not adjacent by pressing the Control
key before clicking the threads you are interested in. When the threads you want are highlighted, right-click and select Show Only Selected Threads.
You can see all the threads again by using the Show list.
You can zoom in on the thread graphs to get a closer look and more microstate data by clicking the plus (+) button in the top left of the Thread Details window.
You can also zoom out to get a wider look by clicking the minus (-) button. The Scale to Fit button sizes the graphs so that data from the entire project run fits in the Thread Details window without scrolling.
When you click the button a second time, you return to the scrolling view of the thread details.
Click on a particular spot in the Thread Details, and a new tab opens below to show a stack dump. Within the stack dump display,
you can expand individual nodes in the stack to see the calls in the stack, or right click the top node and select Expand All to see all the calls
happening at that time.
Thread States
The Solaris thread microstates are described below.
*** more information later
State
Description
USR
The percentage of time the process has spent in user
mode.
SYS
The percentage of time the process has spent in system
mode.
TRP
The percentage of time the process has spent in process-
ing system traps.
TFL
The percentage of time the process has spent in processing text page faults.
DFL
The percentage of time the process has spent in processing data page faults.
LCK
The percentage of time the process has spent waiting for
user locks.
SLP
The percentage of time the process has spent sleeping.