.ds RH Using Race Coverage
.bp 
.ce
.ps 16 
Using Race Coverage
.ps 12
.XS
Using Race Coverage
.XE
.sp
.LP
.LP
.NH 1 
Setup
.LP
.IP (1) 
Add a line like
.nf

    (coverage race)

.fi
to the control file.  Race coverage cannot be combined with operator or
operand coverage.  It can be combined with all other kinds of
coverage.
.sp
Like routine instrumentation, race instrumentation is immune to the
effect of the \fBmacros\fR option.  As with routine instrumentation,
empty functions are not instrumented.
.IP (2) 
Edit the file gct-defs.h.  You'll see this code:
.nf

    <<<TAG>>>:  You may need to declare externs here.

    /* This yields a thread number from 0 to bits-in-word (for this simple
       implementation) */
    #define GCT_THREAD       <<<you must define this>>>

    /* The value of a group/thread - for debugging and testing */
    #define GCT_RACE_GROUP_VALUE(group, thread) \\
        (Gct_group_table[(group)] & (1 << (thread)))

.fi
.sp
You must define the GCT_THREAD macro to return a number between 0 and
the number of bits in a word (less one).  If you have more threads
than will fit in a word, you'll have to make more extensive changes.
The next chapter will give you the background you need.
.sp
Often, the thread is identified by a variable.  In a multiprocessing
UNIX kernel, for example, the definition might be
.nf

#define GCT_THREAD    cpuid

.fi
In this case, you'll need to declare \fBcpuid\fR in all files by
changing the line beginning <<<TAG>>> to 
.nf

extern int cpuid;

.fi
.IP (3) 
When compiling the instrumented file, you may see warnings about
unreachable statements.  You can ignore them. (See below for the
cause.) 
.NH 1
Greport
.LP
The output identifies a routine that has never had two threads in it
at once.
.nf

"example1.c", line 9: race in myfunc is never probed.

.fi
As with routine coverage, the line reported is the first line of a 
routine.
