Statistics User Cache Information

Purpose

A performance statistics operation that returns user cache information.

Prior to V2R3, the user data was kept in data spaces. In V2R3, the data is kept in chunks of memory called cache spaces.

Format

syscall_parmlist
   opcode               int              242    STATOP_USER_CACHE
   parm[0]              int              Offset to STAT_API
   parm[1]              int              Offset of output following STAT_API   
   parm[2]              int              Offset to system name (optional)
   parm[3]              int              0
   parm[4]              int              0
   parm[5]              int              0
   parm[6]              int              0
STAT_API                                
   sa_eye               char[4]          "STAP"
   sa_len               int              Length of buffer that follows STAT_API
   sa_ver               int              1 or 2
   sa_flags             char[1]          0x80 for reset; 0x00 otherwise
   sa_fill              char[3]          Reserved
   sa_supported_ver     int              Version of data returned when sa_ver
                                         is 2
   sa_reserve           int[3]           Reserved
   posix_time_high      unsigned int     High order 32 bits since epoch
   posix_time_low       unsigned int     Low order 32 bits since epoch
   posix_useconds       unsigned int     Microseconds
   pad1                 int              Reserved

STAT_USER_CACHE[2]
   VM_STATS[2]
       vm_schedules          unsigned int      Number of I/O requests
       vm_setattrs           unsigned int      Number of setattr requests
       vm_fsyncs             unsigned int      Number of fsync operations
       vm_unmaps             unsigned int      Number of file deletions
       vm_reads              unsigned int      Number of read operations
       vm_readasyncs         unsigned int      Number of readaheads
       vm_writes             unsigned int      Number of write operations
       vm_getattrs           unsigned int      Number of getattr requests
       vm_flushes            unsigned int      Number of cache flushes
       vm_scheduled_deletes  unsigned int      Number of times an I/O is canceled
                                               because the file was deleted
       vm_reads_faulted      unsigned int      Number of times I/O needed to satisfy
                                               read operation (data was not in cache)
       vm_writes_faulted     unsigned int      Number of times I/O needed to read data
                                               before data can be written to cache
       vm_read_ios           unsigned int      Total number of file system reads for any reason
       vm_scheduled_writes   unsigned int      Number of data write I/Os issued
       vm_error_writes       unsigned int      Number of data writes done when flushign a file
                                               from the cache after an I/O error or canceled user
                                               
         vm_reclaim_writes     unsigned int      Number of data writes during
                                               space reclaim
       vm_read_waits         unsigned int      Number of times a read had to wait for pending I/O
       vm_write_waits        unsigned int      Number of waits for pending I/O so that new data
                                               could be written to the file
       vm_fsync_waits        unsigned int      Number of waits for pending I/O fsync operations did
       vm_error_waits        unsigned int      Number of waits when flushing a file from the cache
                                               cache after an I/O error or canceled user
       vm_reclaim_waits      unsigned int      Number of waits done during reclaim processing for I/O
       vm_reclaim_steal      unsigned int      Number of pages stolen during space reclaim processing
       vm_waits_for_reclaim  unsigned int      Number of waits for reclaim processing to complete
       vm_reserved           int[10]           Reserved
    suc dataspaces           int               Number of dataspaces in user data cache
    suc pages_per_dataspace  int               Number of pages per dataspace
    suc seg_size_local       int               Local segment size (in K)
    suc seg_size_remote      int               Remote segment size (in K)
    suc page_size            int               Page size (in K)
    suc cache_pages          int               Number of pages in user cache
    suc total_free           int               Number of free pages
    suc segment_cachesize    int               Number of segments
    stuc_reserved            int[5]            Reserved
    DS_ENTRY[32]
       ds_name               char[9]           Dataspace name
       pad1                  char[3]           Reserved
       ds_alloc_segs         int               Number of used (allocated)
                                               segments in the dataspace
       ds_free_pages         int               Number of free dataspace pages
       ds_reserved           int[5]            Reserved
STAT_USER_CACHE2
   VM_STATS2
      vm_schedules           unsigned long long int  Number of I/O requests
      vm_setattrs            unsigned long long int  Number of setattrs
      vm_fsyncs              unsigned long long int  Number of fysnc operations
      vm_unmaps              unsigned long long int  Number of file deletions
      vm_reads               unsigned long long int  Number of read operations
      vm_readasyncs          unsigned long long int  Number of readaheads
      vm_writes              unsigned long long int  Number of write operations
      vm_getattrs            unsigned long long int  Number of getattrs
      vm_flushes             unsigned long long int  Number of times the user cache was flushed

      vm_scheduled_deletes   unsigned long long int  Number of times an I/O is canceled
                                                     because the file was deleted  
      vm_reads_faulted       unsigned long long int  Number of times I/O needed to satisify
                                                     read operation (data was not in cache)
      vm_writes_faulted      unsigned long long int  Number of times I/O needed to read
                                                     data before data can be written to cache
      vm_read_ios            unsigned long long int  Total number of file system reads for any
                                                     reason
      vm_scheduled_writes    unsigned long long int  Number of data write I/Os issued
      vm_error_writes        unsigned long long int  Number of data writes when flushing a file
                                                     from the cache after an I/O error or a
                                                     canceled user
      
      vm_reclaim_writes      unsigned long long int  Number of data writes during space reclaim
      vm_read_waits          unsigned long long int  Number of times a read had to wait for pending I/O
      vm_write_waits         unsigned long long int  Number of waits for a pending I/O so that new
                                                     data could be written to the file
      vm_fsync_waits         unsigned long long int  Number of waits for pending I/O fsync
                                                     operations did
      vm_error_waits         unsigned long long int  Number of waits in user cache error processing      
      vm_reclaim_waits       unsigned long long int  Number of waits done during the reclaim
                                                     processing for I/O 
      vm_reclaim_steal       unsigned long long int  Number of user cache pages stolen during
                                                     reclaim processing
      vm_waits_for_reclaim   unsigned long long int  Number of waits for space reclaim process
                                                     to complete
      vm_reserved            unsigned long long int[10]  Reserved
    suc dataspaces           int                     Number of dataspaces in user data cache
    suc pages_per_dataspace  int                     Number of pages per dataspace
    suc seg_size_local       int                     Local segment size (in K)
    suc seg_size_remote      int                     Remote segment size (in K)
    suc page_size            int                     Page size (in K)
    suc cache_pages          int                     Number of pages in cache
    suc total_free           int                     Number of free pages
    suc segment_cachesize    int                     Number of segments
    stuc_reserved            int[5]                  Reserved
    DS_ENTRY[32]
      ds_name                char[9]                 Dataspace name
      pad1                   char[2]                 Reserved
      ds_fixtype             char                    Indicates if cache space is 
                                                     one of the following:
                                                     0 - cache space is not fixed
                                                     1 - cache space fixed via IARV64
                                                     2 - cache space fixed via FPZ4RMR
      ds_alloc_segs          int                     Number of used segments in dataspace
      ds_free_pages          int                     Number of free pages in dataspace
      ds_total_pages         int                     Number of 8K pages in the cache space
      ds_addr                hyper                   Number of cache space in zFS memory
      ds_reserved            int[2]                  Reserved
      systemname             char[9]                 Name of system to get statistics from

Return value     0 if request is successful, -1 if it is not successful

Return code
  EINTR          ZFS is shutting down
  EINVAL         Invalid parameter list
  EMVSERR        Internal error occurred

Reason code
  0xEFxxnnnn     See z/OS Distributed File Service Messages and Codes
   

Usage notes

  1. Reserved fields and undefined flags must be set to binary zeros.
  2. When sa_supported_ver is 0 or 1, the output consists of STAT_USER_CACHE[2] and DS_ENTRY.
  3. When sa_supported_ver is 2 the output consists of STAT_USER_CACHE2 and DS_ENTRY.

Privilege required

None.

Related services

  • Statistics Locking Information
  • Statistics Storage Information

Restrictions

None.

Examples

#pragma linkage(BPX1PCT, OS)
#pragma LANGLVL(EXTENDED)

extern void BPX1PCT(char *, int, int, char *, int *, int *, int *);

#include <stdio.h>

#define ZFSCALL_STATS     0x40000007
#define STATOP_USER_CACHE 242 /* Performance API queries */
#define NUM_DATASPACES    32
#define REMOTE            1
#define LOCAL             0

typedef struct hyper {                  /* This is a 64 bit integer to zFS */
    unsigned int  high;
    unsigned int  low;
} hyper;

typedef struct syscall_parmlist_t
{
  int opcode;   /* Operation code to perform */
  int parms[7]; /* Specific to type of operation, */
                /* provides access to the parms */
                /* parms[4]-parms[6] are currently unused*/
} syscall_parmlist;

typedef struct ds_entry
{
  char              ds_name[9];
  char              pad1[3];
  int               ds_alloc_segs;
  int               ds_free_pages;
  int               ds_reserved[5];  /*reserved for future use*/
} DS_ENTRY;

typedef struct ds_entry2
{
    char ds_name[9];              
    char pad2[2];                                                     
    char ds_fixtype;                /* Fix type of the cache space, one of the
                                       following:
                                       0 - cache space is not fixed
                                       1 - cache space is fixed via the IARV64
                                           page fix services
                                       2 - cache space is fixed via the zEDC
                                           FPZ4RMR page fix services */
    int  ds_alloc_segs;
    int  ds_free_pages;
    int  ds_total_pages;            /* Total number of pages in the cache space */
    hyper ds_addr;                  /* Address of cache space region */
    int  ds_reserved[2];            /*reserved for future use*/
} DS_ENTRY2;

typedef struct reset_time {
  unsigned int      posix_time_high; /* high order 32 bits since epoc */
  unsigned int      posix_time_low;  /* low order 32 bits since epoch */
  unsigned int      posix_usecs;     /* microseconds */
  int               pad1;
} RESET_TIME;

/*********************************************************************/
/* The following structure is the user data cache statistics */
/*********************************************************************/
typedef struct vm_stats_2_t
{
  /**********************************************************************/
  /* First set of counters are for external requests to the VM system.  */
  /**********************************************************************/
  unsigned long long int vm_schedules;
  unsigned long long int vm_setattrs;
  unsigned long long int vm_fsyncs;
  unsigned long long int vm_unmaps;
  unsigned long long int vm_reads;
  unsigned long long int vm_readasyncs;
  unsigned long long int vm_writes;
  unsigned long long int vm_getattrs;
  unsigned long long int vm_flushes;
  unsigned long long int vm_scheduled_deletes;

  /**********************************************************************/
  /* Next two are fault counters, they measure number of read or write  */
  /* requests requiring a fault to read in data, this synchronizes      */
  /* an operation to a DASD read, we want these counters as small as    */
  /* possible.  (These are read I/O counters).                          */
  /**********************************************************************/
  unsigned long long int vm_reads_faulted;
  unsigned long long int vm_writes_faulted;
  unsigned long long int vm_read_ios;

  /**********************************************************************/
  /* Next counters are write counters.  They measure number of times    */
  /* we scheduled and waited for write I/Os.                            */
  /**********************************************************************/
  unsigned long long int vm_scheduled_writes;
  unsigned long long int vm_error_writes;
  unsigned long long int vm_reclaim_writes;  /* Wrote dirty data for reclaim */

  /**********************************************************************/
  /* Next counters are I/O wait counters.  They count the number of     */
  /* times we had to wait for a write I/O and under what conditions.    */
  /**********************************************************************/
  unsigned long long int vm_read_waits;
  unsigned long long int vm_write_waits;
  unsigned long long int vm_fsync_waits;
  unsigned long long int vm_error_waits;
  unsigned long long int vm_reclaim_waits; /* Waited for pending 
                                              I/O for reclaim */

  /**********************************************************************/
  /* Final set are memory management counters.                          */
  /**********************************************************************/
  unsigned long long int vm_reclaim_steal;       /* Number of times steal from
                                                    others function invoked */
  unsigned long long int vm_waits_for_reclaim;   /* Waits for reclaim thread */
  unsigned long long int vm_reserved[10];        /*reserved for future use*/
} VM_STATS_2;

typedef struct stat_user_cache_2_t
{
   /*Various statistics for both LOCAL and REMOTE systems */
  VM_STATS_2 stuc;                 
  
  int        stuc_dataspaces;     /* Number of dataspaces in user data cache */
  int        stuc_pages_per_ds;   /* Pages per dataspace */
  int        stuc_seg_size_loc;   /* Local Segment Size (in K) */ 
  int        stuc_seg_size_rmt;   /* Remote Segment Size (in K) */
  int        stuc_page_size;      /* Page Size (in K) */
  int        stuc_cache_pages;    /* Total number of pages */
  int        stuc_total_free;     /* Total number of free pages */
  int        stuc_vmSegTable_cachesize; /* Number of segments */
  int        stuc_reserved[5];          /*reserved for future use*/     
  DS_ENTRY2  stuc_ds_entry[NUM_DATASPACES];  /* Array of dataspace entries */
  char       reserved[4];
} STAT_USER_CACHE_2;

/* Version 1 Output Structures */

/*********************************************************************/
/* The following structure is the user data cache statistics */
/*********************************************************************/
typedef struct vm_stats_t {

  /**********************************************************************/
  /* First set of counters are for external requests to the VM system. */
  /**********************************************************************/
  unsigned int            vm_schedules;
  unsigned int            vm_setattrs;
  unsigned int            vm_fsyncs;
  unsigned int            vm_unmaps;
  unsigned int            vm_reads;
  unsigned int            vm_readasyncs;
  unsigned int            vm_writes;
  unsigned int            vm_getattrs;
  unsigned int            vm_flushes;
  unsigned int            vm_scheduled_deletes;
  /**********************************************************************/
  /* Next two are fault counters, they measure number of read or write  */
  /* requests requiring a fault to read in data, this synchronizes      */
  /* an operation to a DASD read, we want these counters as small as    */
  /* possible. (These are read I/O counters).                           */
  /**********************************************************************/
  unsigned int            vm_reads_faulted;
  unsigned int            vm_writes_faulted;
  unsigned int            vm_read_ios;
  /**********************************************************************/
  /* Next counters are write counters. They measure number of times     */
  /* we scheduled and waited for write I/Os.                            */
  /**********************************************************************/
  unsigned int            vm_scheduled_writes;
  unsigned int            vm_error_writes;
  unsigned int            vm_reclaim_writes; /* Wrote dirty data for reclaim */
  /**********************************************************************/
  /* Next counters are I/O wait counters. They count the number of      */
  /* times we had to wait for a write I/O and under what conditions.    */
  /**********************************************************************/
  unsigned int            vm_read_waits;
  unsigned int            vm_write_waits;
  unsigned int            vm_fsync_waits;
  unsigned int            vm_error_waits;
  unsigned int            vm_reclaim_waits; /* Waited for pending 
                                               I/O for reclaim */

  /**********************************************************************/
  /* Final set are memory management counters.                          */
  /**********************************************************************/
  unsigned int            vm_reclaim_steal;     /* Number of times steal from 
                                                   others function invoked */
  unsigned int            vm_waits_for_reclaim; /* Waits for reclaim thread */
  unsigned int            vm_reserved[10];      /*reserved for future use*/
} VM_STATS;

typedef struct stat_user_cache_t {
  VM_STATS          stuc[2];                   /* Various statistics for both 
                                                  LOCAL and REMOTE systems*/
  int               stuc_dataspaces;           /* Number of dataspaces 
                                                  in user data cache */
  int               stuc_pages_per_ds;         /* Pages per dataspace */
  int               stuc_seg_size_loc;         /* Local Segment Size (in K) */
  int               stuc_seg_size_rmt;         /* Remote Segment Size (in K) */
  int               stuc_page_size;            /* Page Size (in K) */
  int               stuc_cache_pages;          /* Total number of pages */
  int               stuc_total_free;           /* Total number of free pages */
  int               stuc_vmSegTable_cachesize; /* Number of segments */
  int               stuc_reserved[5];          /* reserved */
  DS_ENTRY          stuc_ds_entry[32];         /* Array of dataspace entries */
} STAT_USER_CACHE;

/*********************************************************************/
/* The following structure is the api query control block */
/* It is used for all api query commands */
/*********************************************************************/
typedef struct stat_api_t {
#define             SA_EYE "STAP"
  char              sa_eye[4];     /* 4 byte identifier must be */
  int               sa_len;        /* length of the buffer to put data into*/
                                   /* this buffer area follows this struct */
  int               sa_ver;        /* the version number currently always 1*/
#define             SA_VER_2 0x02
#define             SA_VER_INIT 0x01
  char              sa_flags;      /* flags field must be x00 or x80, */
                                   /* x80 means reset statistics      */
#define             SA_RESET 0x80
  char              sa_fill[3];       /* spare bytes */
  int               sa_supported_ver; /* version of data returned */
  int               sa_reserve[3];    /* Reserved */
  struct reset_time reset_time_info;
} STAT_API;

struct parmstruct {
  syscall_parmlist  myparms;
  STAT_API          myapi;
  STAT_USER_CACHE_2 mystats;
  char              systemname[9];
} myparmstruct;

int print_user_cache_version1(STAT_USER_CACHE   *stcacheptr);
int print_user_cache_version2(STAT_USER_CACHE_2 *stcacheptr);

int main(int argc, char **argv) 
{
  int      bpxrv;
  int      bpxrc;
  int      bpxrs;
  int      i,j;
  char     buf[33];

  STAT_API *stapptr = &(myparmstruct.myapi);

  myparmstruct.myparms.opcode = STATOP_USER_CACHE;
  myparmstruct.myparms.parms[0] = sizeof(syscall_parmlist);
  myparmstruct.myparms.parms[1] = sizeof(syscall_parmlist) + sizeof(STAT_API);
  myparmstruct.myparms.parms[2] = 0;

  /* Only specify a non-zero offset for the next field (parms[2]) if */
  /* you are running z/OS 1.7 and above, and you want to query the user cache 
     statistics of a different system than this one */
  /* myparmstruct.myparms.parms[2] = sizeof(syscall_parmlist) + 
                                     sizeof(STAT_API) + */
  /*                                 sizeof(STAT_USER_CACHE_2);  */

  myparmstruct.myparms.parms[3] = 0;
  myparmstruct.myparms.parms[4] = 0;
  myparmstruct.myparms.parms[5] = 0;
  myparmstruct.myparms.parms[6] = 0;

  memset(stapptr, 0, sizeof(STAT_API));
  memcpy(stapptr->sa_eye, SA_EYE, 4);
  stapptr->sa_ver = SA_VER_2;
  stapptr->sa_len = (int) sizeof(STAT_USER_CACHE_2);

  /* This next field should only be set if parms[2] is non-zero */
  /* strcpy(myparmstruct.systemname,"DCEIMGVQ"); */

  BPX1PCT("ZFS     ",
          ZFSCALL_STATS,              /* Perf statistics operation */
          sizeof(myparmstruct),       /* Length of Argument */
          (char *)&myparmstruct,      /* Pointer to Argument */
          &bpxrv,                     /* Pointer to Return_value */
          &bpxrc,                     /* Pointer to Return_code */
          &bpxrs);                    /* Pointer to Reason_code */

  if (bpxrv < 0) 
  {
    printf("Error querying user cache stats, "
           "BPXRV = %d BPXRC = %d BPXRS = %x\n", 
           bpxrv, bpxrc, bpxrs);
    return bpxrc;
  } 
  else 
  {
    if( stapptr->sa_supported_ver == SA_VER_INIT )
    {
      STAT_USER_CACHE *stcacheptr_v1;
      stcacheptr_v1 = (STAT_USER_CACHE*) &(myparmstruct.mystats);
      print_user_cache_version1(stcacheptr_v1);
    }
    else
    {
      STAT_USER_CACHE_2 *stcacheptr = &(myparmstruct.mystats);
      print_user_cache_version2(stcacheptr);
    }

    if (0 == ctime_r((time_t*) & stapptr->reset_time_info.posix_time_low, buf)) 
      printf("Could not get timestamp.\n");
    else 
    {   /* Insert the microseconds into the displayable time value */
      strncpy(&(buf[27]), &(buf[20]), 6);
      sprintf(&(buf[20]), "%06d", stapptr->reset_time_info.posix_usecs);
      buf[26] = ' ';
      buf[19] = '.';
      printf("Last Reset Time: %s", buf);
    }
  }
  return 0;
}

int print_user_cache_version2(STAT_USER_CACHE_2* stcacheptr)
{
  int i;
  double   ratio1, ratio2, ratio3, ratio4;
  printf("                   User File (VM) Caching System Statistics\n");
  printf("                   ----------------------------------------\n");
  printf("\n");

  printf("                   Direct Statistics\n");
  printf("                   -----------------\n\n");

  printf("External Requests:\n");
  printf("------------------\n");
  printf("%-9s %20llu     %-9s %20llu     %-9s %20llu\n",
         "Reads"    , stcacheptr->stuc.vm_reads,
         "Fsyncs"   , stcacheptr->stuc.vm_fsyncs,
         "Schedules", stcacheptr->stuc.vm_schedules);
  printf("%-9s %20llu     %-9s %20llu     %-9s %20llu\n",
         "Writes"   , stcacheptr->stuc.vm_writes,
         "Setattrs" , stcacheptr->stuc.vm_setattrs,
         "Unmaps"   , stcacheptr->stuc.vm_unmaps);
  printf("%-9s %20llu     %-9s %20llu     %-9s %20llu\n",
         "Asy Reads", stcacheptr->stuc.vm_readasyncs,
         "Getattrs" , stcacheptr->stuc.vm_getattrs,
         "Flushes"  , stcacheptr->stuc.vm_flushes);
  printf("\n");

  printf("File System Reads:\n");
  printf("------------------\n");

  ratio1 = ratio2 = ratio3 = ratio4 = 0.0;

  if (stcacheptr->stuc.vm_reads > 0) 
  {
    ratio1 = 100 * (((double)stcacheptr->stuc.vm_reads_faulted)
                    / ((double)stcacheptr->stuc.vm_reads));
  }
  if (stcacheptr->stuc.vm_writes > 0) 
  {
    ratio2 = 100 * (((double)stcacheptr->stuc.vm_writes_faulted)
                    / ((double)stcacheptr->stuc.vm_writes));
  }
  if (stcacheptr->stuc.vm_reads > 0) 
  {
    ratio3 = 100 * (((double)stcacheptr->stuc.vm_read_waits)
                    / ((double)stcacheptr->stuc.vm_reads));
  }

  printf("%-14s %20llu (%s Ratio %.2f%%)\n",
         "Reads Faulted", stcacheptr->stuc.vm_reads_faulted,
         "Fault", ratio1);

  printf("%-14s %20llu (%s Ratio %.2f%%)\n",
         "Writes Faulted", stcacheptr->stuc.vm_writes_faulted,
         "Fault", ratio2);

  printf("%-14s %20llu (%s Ratio %.2f%%)\n",
         "Read Waits", stcacheptr->stuc.vm_read_ios,
         "Wait", ratio3);

  printf("\n");
  printf("File System Writes:\n");
  printf("-------------------\n");
  printf("%-19s %20llu %-13s %20llu\n",
         "Scheduled Writes"   ,stcacheptr->stuc.vm_scheduled_writes,
         "Sync Waits"         ,stcacheptr->stuc.vm_fsync_waits);

  printf("%-19s %20llu %-13s %20llu\n",
         "Error Writes"       ,stcacheptr->stuc.vm_error_writes,
         "Error Waits"        ,stcacheptr->stuc.vm_error_waits);

  printf("%-19s %20llu %-13s %20llu\n",
         "Page Reclaim Writes", stcacheptr->stuc.vm_reclaim_writes,
         "Reclaim Waits"      , stcacheptr->stuc.vm_reclaim_waits);

  if (stcacheptr->stuc.vm_writes > 0) 
  {
    ratio4 = 100 * (((double)stcacheptr->stuc.vm_write_waits)
                    / ((double)stcacheptr->stuc.vm_writes));
  }
  printf("%-19s %20llu (Wait Ratio %.2f%%)\n",
         "Write Waits", stcacheptr->stuc.vm_write_waits,
         ratio4);

        
  printf("\n");
  printf("Page Management (Segment Size = (%dK Local %dK Remote) ) "
         "(Page Size = %dK)\n",
         stcacheptr->stuc_seg_size_loc,
         stcacheptr->stuc_seg_size_rmt,
         stcacheptr->stuc_page_size);
  printf("----------------------------------------"
         "---------------------------------\n");

  printf("Total Pages       %10u     Free               %10u\n",
         stcacheptr->stuc_cache_pages,
         stcacheptr->stuc_total_free);
  printf("Segments          %10u\n",
         stcacheptr->stuc_vmSegTable_cachesize);
  printf("Steal Invocations %20llu     Waits for Reclaim %21llu\n\n",
         stcacheptr->stuc.vm_reclaim_steal,
         stcacheptr->stuc.vm_waits_for_reclaim);

  printf("Number of dataspaces used: %5d ", 
         stcacheptr->stuc_dataspaces);
  printf("Pages per dataspace: %11d\n",
         stcacheptr->stuc_pages_per_ds);
  printf("\n");

  printf("Space         Total 8K      Free          Assigned\n");
  printf("Address       Pages         Pages         Segments      Fix Type\n");
  printf("----------    ----------    ----------    ----------    --------\n");
  for (i = 0; i < stcacheptr->stuc_dataspaces; i++)
  {
      char fixtype[10];
      if (stcacheptr->stuc_ds_entry[i].ds_fixtype == 0)
        strcpy(fixtype, "Not Fixed");
      else if (stcacheptr->stuc_ds_entry[i].ds_fixtype == 1)
        strcpy(fixtype, "IARV64");
      else
        strcpy(fixtype, "FPZ4RMR");
       printf("%2.2X%8.8X    %10u    %10u    %10u    %s\n",
             stcacheptr->stuc_ds_entry[i].ds_addr.high,
             stcacheptr->stuc_ds_entry[i].ds_addr.low,
             stcacheptr->stuc_ds_entry[i].ds_total_pages,
             stcacheptr->stuc_ds_entry[i].ds_free_pages,
             stcacheptr->stuc_ds_entry[i].ds_alloc_segs,
             fixtype);
  }

  return 0;
}

int print_user_cache_version1(STAT_USER_CACHE *stcacheptr)
{
  int i;
  double ratio1, ratio2, ratio3, ratio4;
  printf("Version 1 Output is being displayed\n\n");
  
  printf("                   User File (VM) Caching System Statistics\n");
  printf("                   ----------------------------------------\n");
  printf("\n");

  for (i = 0; i <= REMOTE; i++) 
  {
    if (i == 0) 
    {
      printf("                   Direct Statistics\n");
      printf("                   -----------------\n\n");
    } 
    else 
    {
      printf("\n                   Client Statistics\n");
      printf("                   -----------------\n\n");
    }

    printf("External Requests:\n");
    printf("------------------\n");
    printf("%-9s %10u     %-9s %10u     %-9s %10u\n",
           "Reads"    , stcacheptr->stuc[i].vm_reads,
           "Fsyncs"   , stcacheptr->stuc[i].vm_fsyncs,
           "Schedules", stcacheptr->stuc[i].vm_schedules);
    printf("%-9s %10u     %-9s %10u     %-9s %10u\n",
           "Writes"   , stcacheptr->stuc[i].vm_writes,
           "Setattrs" , stcacheptr->stuc[i].vm_setattrs,
           "Unmaps"   , stcacheptr->stuc[i].vm_unmaps);
    printf("%-9s %10u     %-9s %10u     %-9s %10u\n",
           "Asy Reads", stcacheptr->stuc[i].vm_readasyncs,
           "Getattrs" , stcacheptr->stuc[i].vm_getattrs,
           "Flushes"  , stcacheptr->stuc[i].vm_flushes);
    printf("\n");

    printf("File System Reads:\n");
    printf("------------------\n");

    ratio1 = ratio2 = ratio3 = ratio4 = 0.0;

    if (stcacheptr->stuc[i].vm_reads > 0) 
    {
      ratio1 = 100 * (((double)stcacheptr->stuc[i].vm_reads_faulted)
                      / ((double)stcacheptr->stuc[i].vm_reads));
    }
    if (stcacheptr->stuc[i].vm_writes > 0) 
    {
      ratio2 = 100 * (((double)stcacheptr->stuc[i].vm_writes_faulted)
                      / ((double)stcacheptr->stuc[i].vm_writes));
    }
    if (stcacheptr->stuc[i].vm_reads > 0) 
    {
      ratio3 = 100 * (((double)stcacheptr->stuc[i].vm_read_waits)
                      / ((double)stcacheptr->stuc[i].vm_reads));
    }

    printf("%-14s %10u (%s Ratio %.2f%%)\n",
           "Reads Faulted", stcacheptr->stuc[i].vm_reads_faulted,
           "Fault", ratio1);

    printf("%-14s %10u (%s Ratio %.2f%%)\n",
           "Writes Faulted", stcacheptr->stuc[i].vm_writes_faulted,
           "Fault", ratio2);

    printf("%-14s %10u (%s Ratio %.2f%%)\n",
           "Read Waits", stcacheptr->stuc[i].vm_read_ios,
           "Wait", ratio3);

    printf("\n");
    printf("File System Writes:\n");
    printf("-------------------\n");
    printf("%-19s %10u %-13s %10u\n",
           "Scheduled Writes"   , stcacheptr->stuc[i].vm_scheduled_writes,
           "Sync Waits"         , stcacheptr->stuc[i].vm_fsync_waits);

    printf("%-19s %10u %-13s %10u\n",
           "Error Writes"       , stcacheptr->stuc[i].vm_error_writes,
           "Error Waits"        , stcacheptr->stuc[i].vm_error_waits);

    printf("%-19s %10u %-13s %10u\n",
           "Page Reclaim Writes", stcacheptr->stuc[i].vm_reclaim_writes,
           "Reclaim Waits"      , stcacheptr->stuc[i].vm_reclaim_waits);

    if (stcacheptr->stuc[i].vm_writes > 0) 
    {
      ratio4 = 100 * (((double)stcacheptr->stuc[i].vm_write_waits)
                      / ((double)stcacheptr->stuc[i].vm_writes));
    }
    printf("%-19s %10u (Wait Ratio %.2f%%)\n",
           "Write Waits", stcacheptr->stuc[i].vm_write_waits,
           ratio4);
  }
        
  printf("\n");
  printf("Page Management (Segment Size = (%dK Local %dK Remote) ) "
         "(Page Size = %dK)\n",
         stcacheptr->stuc_seg_size_loc,
         stcacheptr->stuc_seg_size_rmt,
         stcacheptr->stuc_page_size);
  printf("--------------------------------------"
         "-----------------------------------\n");

  printf("Total Pages       %10u     Free               %10u\n",
         stcacheptr->stuc_cache_pages,stcacheptr->stuc_total_free);
  printf("Segments          %10u\n",
         stcacheptr->stuc_vmSegTable_cachesize);
  printf("Steal Invocations %10u     Waits for Reclaim %11u\n\n",
         stcacheptr->stuc[0].vm_reclaim_steal,
         stcacheptr->stuc[0].vm_waits_for_reclaim);

  printf("Number of dataspaces used: %5d ", stcacheptr->stuc_dataspaces);
  printf("Pages per dataspace: %11d\n", stcacheptr->stuc_pages_per_ds);
  printf("\n");
  printf("Dataspace   Allocated     Free\n");
  printf("Name        Segments      Pages\n");
  printf("--------    ----------    ----------\n");

  for (i = 0; i < stcacheptr->stuc_dataspaces; i++)
  {
    printf("%8s    %10u    %10u\n\n",
           stcacheptr->stuc_ds_entry[i].ds_name,
           stcacheptr->stuc_ds_entry[i].ds_alloc_segs,
           stcacheptr->stuc_ds_entry[i].ds_free_pages);
  }
  return 0;
}