/*static char *SCCSID = "@(#)pvw.h      6.1 90/11/18";*/
/*static char *SCCSID = "@(#)pvw.h    13.4 90/05/30";*/

/*********************************************************************
 *
 *                       PerfView hooks
 *
 *      This file contains:
 *
 *  1.- The macros that expand the PVWDEF definitions in pvwdef.h
 *      and pvwdef2.h into meaningful variables and data
 *
 *  2.- Macros for manipulating the PerfView variables.
 *
 *
 *  The definitions in pvwdef files (pvwdef.h and pvwdef2.h) are
 *  expanded in different ways depending on the context in which
 *  this file is being included. The context is indicated to this
 *  file by the symbols PVWDATA and PVWTEXT.
 *
 *  1.- When PVWDATA is defined, the macros generated expand
 *      the definitions to variable declarations. This is ONLY
 *      used by pvwdata.c
 *
 *  2.- When PVWTEXT is defined, the macros generated expand
 *      the definitions to actual data that is used to initialize
 *      the PerfView text block. Essentially, the text block
 *      contains the variable names in string form. This is ONLY
 *      used by pvwtext.c
 *
 *  3.- When neither PVWDATA nor PVWTEXT are defined, the macros
 *      generated expand the definitions to an extern delcaration
 *      of the PerfView data block. This should be the case for
 *      ALL those files in which a PerfView variable is being
 *      used.
 *
 *      This is accomplished by simply including:
 *
 *      #include "pvw.h"
 *      #include "pvwdef.h"
 *
 *      in the file in which a PerfView variable is being used.
 *
 *  Cases 1 and 2 are very specific and cryptic. For understanding
 *  them you should take a look at pvwdata.c and pvwtext.c to see
 *  how these macros and the file pvw.h are used to declare and
 *  initialize the PerfView variables and data.
 *
 *  Note that 1 and 2 should be mutually exclusive
 *
 *********************************************************************/

#ifdef PERFVIEW


/*********************************************************************
 *
 *          Macros for Type-to-Prefix translation
 *
 *      An HPFS variable name is composed of 3 parts:
 *
 *  1.- Type: CT, TM or SS
 *  2.- Category (2 characters)
 *  3.- Name
 *
 *  Now, the type specified in the PVWDEF macro is one of
 *  CNT, TIMR or SUMSQ. These have to be like that because that is
 *  the way they are called in pvwxport.h.  We want our prefixes
 *  to be only 2 characters because the perfview display tool only
 *  displays 10 characters and we want to have as many characters
 *  as possible for the Name, besides we've seen that they use these
 *  same prefixes in the Kernel PerfView variables.
 *
 *  So we want our translation to be something like:
 *
 *  PVWDEF(TIMR,Rd,Total) ->    TIMR TMRdTotal;
 *
 *  How do we do the trick?
 *
 *  The C preprocessor understands the following operators:
 *
 *  #   The "make string" operator
 *  ##  The concatenate operator
 *
 *  Concatenating the parts is easy with the ## operator. The problem is
 *  the translation of the Type argument. The solution is to use a
 *  translation macro.
 *
 *  By using the translation macro we could look at the example
 *  above as:
 *
 *  PVWDEF(TIMR,Rd,Total)   ->  TIMR  TIMR##_X(_)##Rd##Total
 *                          ->  TIMR  TIMR_X(_)##Rd##Total
 *                          ->  TIMR  TM##Rd##Total
 *                          ->  TIMR  TMRdTotal
 *
 *  Note how the type is concatenated to _X(_) to form the name of a
 *  translation macro that then expands to the prefix that we want.
 *
 *  Now you may ask, Why do we have the dummy argument in the
 *  translation macros? The answer is: Because the C preprocessor
 *  won't expand the translation macro if it doesn't have that
 *  dummy parameter. In other words:
 *
 *  if we have #define TIMR_X TM
 *      TIMR##_X  will give TIMR_X (no macro expansion)
 *
 *  but if we have #define TIMR_X(x) TM
 *      TIMR##_X(foo) will give TM (macro expanded)
 *
 *  Why is this? Beats me..
 *
 **************************************************************************/

#define CNT_X(x)     CT
#define TIMR_X(x)    TM
#define SUMSQ_X(x)   SS
#define QCT_X(x)     QC                      /*25106*/

/*
 *  When we want the type to expand to a prefix in quotation marks we
 *  have to use the macros <Type>_XS(_)
 *
 *  We need these because trying to use the # operator on the
 *  type-to-prefix translation macros won't work.
 *
 *  That is,
 *
 *  #<Type>_X(_)  won't work
 *  defining CNT_XS(x) as  #CNT_X(x)  won't work either
 */

#define CNT_XS(x)   "CT"
#define TIMR_XS(x)  "TM"
#define SUMSQ_XS(x) "SS"
#define QCT_XS(x)   "QC"                     /*25106*/



#if defined(PVWDATA)

    /*********************************************************************
     *
     *              For PerfView Data Block
     *
     *  Condition:
     *      PVWDATA defined
     *
     *  Warnings:
     *      Note that pvwdata.c includes pvwdef.h multiple times, and
     *      that it itself redefines the PVWDEF macro. This is done
     *      for declaring and initializing the Perfview variables.
     *
     *********************************************************************/

    /* Allocate memory for counter or timer */
    #define PVWDEF(TYPE,Category,Name)  TYPE TYPE##_X(_)##Category##Name;


#elif defined(PVWTEXT)

    /*********************************************************************
     *
     *              For PerfView Text Block
     *
     *  Condition:
     *      PVWTEXT defined
     *      PVWDATA not defined
     *
     *********************************************************************/

    /* Initialize Counter\Timer flags */
    #define FLAGS_CNT    PVW_CT_CNT
    #define FLAGS_TIMR   PVW_CT_TIMR
    #define FLAGS_QCT    PVW_CT_QCT                     /*25106*/

    /* Define counter or timer name */
    #define PVWDEF(TYPE,Category,Name) {FLAGS_##TYPE,sizeof(TYPE),0,TYPE##_XS(_)###Category###Name},


#else

    /*********************************************************************
     *
     *              General PerfView usage
     *
     *  This is the part seen by all source files that use PerfView
     *
     *  Condition:
     *      PVWTEXT not defined
     *      PVWDATA not defined
     *
     *********************************************************************/

    #define PVWDEF(TYPE,Category,Name)  TYPE TYPE##_X(_)##Category##Name;

    /* Note pvwData is redefined in fsdata\PVWDATA.C */

    extern  struct PVWDATA {
        PVWFSDDATAH pvdHeader;
        #include "pvwdef.h"
    } pvwData;

    extern PVWFSDTEXTH far pvwTextHeader;

    /* Increment counter by one */
    #define PVWINC(Category,Name)     pvwData.CNT_X(_)##Category##Name++

    /* Increment queue counter by n */
/*25106  #define PVWADD(Category,Name,n)   pvwData.CNT_X(_)##Category##Name += (n) */
         #define PVWADD(Category,Name,n)   pvwData.QCT_X(_)##Category##Name += (n)

    /* Increment counter by n */             /*25106*/
         #define PVWADDC(Category,Name,n)   pvwData.CNT_X(_)##Category##Name += (n)

    /* Start timer */
    #define PVWSTART(Category,Name)                               \
        if (pvwData.pvdHeader.ddbh_pfnTmrSub)                     \
            (*pvwData.pvdHeader.ddbh_pfnTmrSub)                   \
                                        (&pvwData.TIMR_X(_)##Category##Name)

    /* Stop timer */
    #define PVWSTOP(Category,Name)                                \
        if (pvwData.pvdHeader.ddbh_pfnTmrAdd)                     \
            (*pvwData.pvdHeader.ddbh_pfnTmrAdd)                   \
                                        (&pvwData.TIMR_X(_)##Category##Name)

    /* Set counter to n  */
/*25106 #define PVWSETCNT(Category,Name,n)  pvwData.CNT_X(_)##Category##Name = (n) */
        #define PVWSETCNT(Category,Name,n)  pvwData.QCT_X(_)##Category##Name = (n)

    /* Reset counter */
    #define PVWRESETCNT(Category,Name)  PVWSETCNT(Category,Name,0)

    /* Reset timer */
    #define PVWRESETTMR(Category,Name)                                  \
                            pvwData.TIMR_X(_)##Category##Name.qw_ulLo = \
                            pvwData.TIMR_X(_)##Category##Name.qw_ulHi = 0

#endif







#else

/************************************************************************
 *
 *                      PerfView Disabled
 *
 ************************************************************************

/* Define counter/Timer     */
#define PVWDEF(TYPE,Category,Name)

/* Increment counter by one */
#define PVWINC(Category,Name)

/* Increment queue counter by n   */
#define PVWADD(Category,Name,n)

/* Increment counter by n */      /*25106*/
#define PVWADDC(Category,Name,n)

/* Start timer              */
#define PVWSTART(Category,Name)

/* Stop timer               */
#define PVWSTOP(Category,Name)

/* Set counter to n         */
#define PVWSETCNT(Category,Name,n)

/* Reset counter            */
#define PVWRESETCNT(Category,Name)

/* Reset timer              */
#define PVWRESETTMR(Category,Name)

#endif
