Sun Studio 12: Thread Analyzer User's Guide

3.4 Understanding the Experiment Results

This section explains how to use the Thread Analyzer to investigate the deadlocks in the dining philosopher program. We'll start by executing runs that result in actual deadlocks and then examine runs that terminate normally but have the potential for deadlocks.

3.4.1 Examining Runs That Deadlock

The following listing shows a run of the dining philosophers program that results in an actual deadlock.

prompt% cc din_philo.c -mt -g             

prompt% collect -r deadlock a.out
Creating experiment database tha.1.er ...
Philosopher 1 is done thinking and now ready to eat.
Philosopher 2 is done thinking and now ready to eat.
Philosopher 3 is done thinking and now ready to eat.
Philosopher 0 is done thinking and now ready to eat.
Philosopher 1: got right  chopstick 1
Philosopher 3: got right  chopstick 3
Philosopher 0: got right  chopstick 0
Philosopher 1: got left chopstick 2
Philosopher 3: got left chopstick 4
Philosopher 4 is done thinking and now ready to eat.
Philosopher 1: eating.
Philosopher 3: eating.
Philosopher 3: got right  chopstick 3
Philosopher 4: got right  chopstick 4
Philosopher 2: got right  chopstick 2
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 1: got right  chopstick 1
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 4: got right  chopstick 4
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 3: got right  chopstick 3
Philosopher 1: got left chopstick 2
Philosopher 1: eating.
Philosopher 2: got right  chopstick 2
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 1: got right  chopstick 1
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 4: got right  chopstick 4
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 3: got right  chopstick 3
Philosopher 1: got left chopstick 2
Philosopher 1: eating.
Philosopher 2: got right  chopstick 2
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 1: got right  chopstick 1
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 4: got right  chopstick 4
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 2: got right  chopstick 2
Philosopher 3: got right  chopstick 3
(hang)

Execution terminated by pressing CTRL-C


% er_print tha.1.er 
(er_print) deadlocks

Deadlock #1, Potential deadlock
	Thread #2
		Lock being held:	0x215a8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215c0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #3
		Lock being held:	0x215c0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215d8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #4
		Lock being held:	0x215d8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215f0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #5
		Lock being held:	0x215f0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x21608, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #6
		Lock being held:	0x21608, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215a8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"

Deadlock #2, Actual deadlock
	Thread #2
		Lock being held:	0x215a8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215c0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #3
		Lock being held:	0x215c0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215d8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #4
		Lock being held:	0x215d8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215f0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #5
		Lock being held:	0x215f0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x21608, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #6
		Lock being held:	0x21608, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215a8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"

Deadlocks List Summary: Experiment: tha.1.er Total Deadlocks: 2
(er_print) 

The following screen-shot shows the Thread Analyzer's presentation of the deadlock information:

A screen shot of the Thread Analyzer's window which shows
an actual deadlock.

The Thread Analyzer reports two deadlocks for din_philo.c, one potential and the other actual. On closer inspection, we find that the two deadlocks are identical. The circular chain involved in the deadlock is as follows:

Thread 2: holds lock at address 0x215a8, requests lock at address 0x215c0

Thread 3: holds lock at address 0x215c0, requests lock at address 0x215d8

Thread 4: holds lock at address 0x215d8, requests lock at address 0x215f0

Thread 5: holds lock at address 0x215f0, requests lock at address 0x21608

Thread 6: holds lock at address 0x21608, requests lock at address 0x215a8

Select the first thread in the chain (Thread #2) and then click on the Dual Source tab to see where in the source code Thread #2 held the lock at address 0x215a8, and where in the source code it requested the lock at address 0x215c0. The following screen-shot shows the Dual Source tab for thread number two. The default metric (Exclusive Deadlocks metric) is shown to the left of each source line. This metric gives a count of the number of times a lock-hold or lock-request operation, which was involved in a deadlock, was reported on that line.

A screen shot of the Thread Analyzer's Dual-Source tab
which shows a potential deadlock.

3.4.2 Examining Runs That Complete Despite Deadlock Potential

The dining philosophers program can avoid actual deadlock and terminate normally if you supply a large enough sleep argument. Normal termination, however, does not mean the program is safe from deadlocks. It simply means that the locks held and requested did not form a deadlock chain during a given run. If the timing changes in other runs, an actual deadlock can occur. The following listing shows a run of the dining philosophers program that terminates normally. However, the er_print utility and the Thread Analyzer report potential deadlocks.

% cc din_philo.c -mt -g                


% collect -r deadlock a.out 40
Creating experiment database tha.2.er ...
Philosopher 0 is done thinking and now ready to eat.
Philosopher 2 is done thinking and now ready to eat.
Philosopher 1 is done thinking and now ready to eat.
Philosopher 3 is done thinking and now ready to eat.
Philosopher 2: got right  chopstick 2
Philosopher 3: got right  chopstick 3
Philosopher 0: got right  chopstick 0
Philosopher 4 is done thinking and now ready to eat.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 0: got right  chopstick 0
Philosopher 4: got right  chopstick 4
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3: got right  chopstick 3
Philosopher 2: got right  chopstick 2
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 4: got right  chopstick 4
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 3: got right  chopstick 3
Philosopher 2: got right  chopstick 2
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 0: got right  chopstick 0
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
...
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 4: got right  chopstick 4
Philosopher 3: got right  chopstick 3
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 0: got right  chopstick 0
Philosopher 3: got left chopstick 4
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3: eating.
Philosopher 0: got right  chopstick 0
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 4: got right  chopstick 4
Philosopher 3: got right  chopstick 3
Philosopher 2: got right  chopstick 2
Philosopher 4: got left chopstick 0
Philosopher 4: eating.
Philosopher 4 is done eating.
Philosopher 3: got left chopstick 4
Philosopher 3: eating.
Philosopher 0: got right  chopstick 0
Philosopher 0: got left chopstick 1
Philosopher 0: eating.
Philosopher 3 is done eating.
Philosopher 2: got left chopstick 3
Philosopher 2: eating.
Philosopher 0 is done eating.
Philosopher 2 is done eating.
Philosopher 1: got right  chopstick 1
Philosopher 1: got left chopstick 2
Philosopher 1: eating.
Philosopher 1 is done eating.
%

Execution terminated normally


% er_print tha.2.er 
(er_print) deadlocks

Deadlock #1, Potential deadlock
	Thread #2
		Lock being held:	0x215a8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215c0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #3
		Lock being held:	0x215c0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215d8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #4
		Lock being held:	0x215d8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215f0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #5
		Lock being held:	0x215f0, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x21608, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
	Thread #6
		Lock being held:	0x21608, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"
		Lock being requested:	0x215a8, at: grab_chopstick + 0x0000002C, line 101 in "din_philo.c"

Deadlocks List Summary: Experiment: tha.2.er Total Deadlocks: 1
(er_print) 
 

The following screen-shot shows the potential deadlock information in the Thread Analyzer interface:

A screen-shot of the Thread Analyzer window which shows
a potential deadlocks.