/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#ifndef _BASEMETRIC_H
#define _BASEMETRIC_H

#include "dbe_structs.h"
#include "hwcentry.h"
#include "Table.h"

// METRIC_*_PRECISION determine the least threshold value
// for time measured metrics. Any event that counts for less
// than 1sec/METRIC_PRECISION is discarded.
#define METRIC_SIG_PRECISION    MICROSEC
#define METRIC_HR_PRECISION     MICROSEC

class Expression;
class Definition;
class Histable;
template <class ITEM> class Vector;

class BaseMetric
{
public:
  // sync enum changes with AnMetric.java
  enum Type
  { // Subtype==STATIC metrics:
    ONAME = 1,  //ONAME must be 1
    SIZES,
    ADDRESS,
    // Clock Profiling, Derived Metrics:
    CP_TOTAL,
    CP_TOTAL_CPU,
    // Clock profiling, Solaris Microstates (LMS_* defines)
    CP_LMS_USER,
    CP_LMS_SYSTEM,
    CP_LMS_TRAP,
    CP_LMS_TFAULT,
    CP_LMS_DFAULT,
    CP_LMS_KFAULT,
    CP_LMS_USER_LOCK,
    CP_LMS_SLEEP,
    CP_LMS_WAIT_CPU,
    CP_LMS_STOPPED,
    // Kernel clock profiling
    CP_KERNEL_CPU,
    // Sync Tracing
    SYNC_WAIT_TIME,
    SYNC_WAIT_COUNT,
    // HWC
    HWCNTR,
    // Heap Tracing:
    HEAP_ALLOC_CNT,
    HEAP_ALLOC_BYTES,
    HEAP_LEAK_CNT,
    HEAP_LEAK_BYTES,
    // I/O Tracing:
    IO_READ_BYTES,
    IO_READ_CNT,
    IO_READ_TIME,
    IO_WRITE_BYTES,
    IO_WRITE_CNT,
    IO_WRITE_TIME,
    IO_OTHER_CNT,
    IO_OTHER_TIME,
    IO_ERROR_CNT,
    IO_ERROR_TIME,
    // MPI Tracing:
    MPI_TIME,
    MPI_SEND,
    MPI_BYTES_SENT,
    MPI_RCV,
    MPI_BYTES_RCVD,
    MPI_OTHER,
    // OMP states:
    OMP_NONE,
    OMP_OVHD,
    OMP_WORK,
    OMP_IBAR,
    OMP_EBAR,
    OMP_WAIT,
    OMP_SERL,
    OMP_RDUC,
    OMP_LKWT,
    OMP_CTWT,
    OMP_ODWT,
    OMP_MSTR,
    OMP_SNGL,
    OMP_ORDD,
    OMP_MASTER_THREAD,
    // MPI states:
    MPI_WORK,
    MPI_WAIT,
    // Races and Deadlocks
    RACCESS,
    DEADLOCKS,
    // Derived Metrics
    DERIVED
  };

  // sync enum changes with AnMetric.java
  enum SubType
  {
    STATIC      = 1, // Type==SIZES, ADDRESS, ONAME
    EXCLUSIVE   = 2,
    INCLUSIVE   = 4,
    ATTRIBUTED  = 8,
    DATASPACE   = 16 // Can be accessed in dataspace views
  };

  BaseMetric (Type t);
  BaseMetric (Hwcentry *ctr, const char* _aux, const char* _cmdname,
	      const char* _username, int v_styles); // depended bm
  BaseMetric (Hwcentry *ctr, const char* _aux, const char* _username,
	      int v_styles, BaseMetric* _depended_bm = NULL); // master bm
  BaseMetric (const char *_cmd, const char *_username, Definition *def); // derived metrics
  BaseMetric (const BaseMetric& m);
  virtual ~BaseMetric ();

  int get_id ()                     { return id; }
  Type get_type ()                  { return type; }
  Hwcentry *get_hw_ctr ()           { return hw_ctr; }
  char *get_aux ()                  { return aux; }
  char *get_username ()             { return username; }
  char *get_cmd ()                  { return cmd; }
  int get_flavors ()                { return flavors; }
  int get_clock_unit ()             { return clock_unit; }
  long long get_precision ()        { return precision; }
  ValueTag get_vtype ()             { return valtype; }
  int get_value_styles ()           { return value_styles; }
  bool is_zeroThreshold ()          { return zeroThreshold; }
  ProfData_type get_packet_type ()  { return packet_type; }
  Expression *get_cond ()           { return cond; }
  Expression *get_val ()            { return val; }
  Expression *get_expr ()           { return expr; }
  char *get_expr_spec ()            { return expr_spec; }
  Definition *get_definition ()     { return definition; };
  BaseMetric *get_dependent_bm ()   { return dependent_bm; };

  bool
  comparable ()
  {
    return val_spec != NULL || type == DERIVED || type == SIZES || type == ADDRESS;
  }

  // setters..
  void set_default_visbits (SubType subtype, int _visbits);
  void set_id (int _id)         { id = _id; }   //TBR, if possible
  // For comparison, set which packets to eval:
  void set_expr_spec (char *_expr_spec);
  void set_cond_spec (char *_cond_spec);
  int get_default_visbits (SubType subtype);
  char *dump ();
  Histable *get_comparable_obj (Histable *obj);
  bool is_internal ();          // Invisible for users

  char *legend;                 // for comparison: add'l column text

private:
  BaseMetric *dependent_bm;     // for HWCs only: a link to the timecvt metric
  Expression *cond;             // determines which packets to evaluate
  char *cond_spec;              // used to generate "cond"
  Expression *val;              // determines the numeric value for packet
  char *val_spec;               // used to generate "val"
  Expression *expr; // for comparison: an additional expression to determine
		    // which packets to eval. Should be NULL otherwise.
  char *expr_spec;                  // used to generate "expr"
  int id;                           // unique id (assigned to last_id @ "new")
  Type type;                        // e.g. HWCNTR
  char *aux;                        // for HWCs only: Hwcentry ctr->name
  char *cmd;                        // the .rc metric command, e.g. "total"
  char *username;                   // e.g. "GTXT("Total Wait Time")"
  int flavors;                      // bitmask of SubType capabilities
  int value_styles;                 // bitmask of ValueType capabilities
  static const int NSUBTYPES = 2;   // STATIC/EXCLUSIVE, INCLUSIVE
  int default_visbits[NSUBTYPES];   // ValueType, e.g. VAL_VALUE|VAL_TIMEVAL
  ValueTag valtype;                 // e.g. VT_LLONG
  long long precision;              // e.g. METRIC_SIG_PRECISION, 1, etc.
  Hwcentry *hw_ctr;                 // HWC definition
  ProfData_type packet_type;        // e.g. DATA_HWC, or -1 for N/A
  bool zeroThreshold;               // deadlock stuff
  Presentation_clock_unit clock_unit;

  static int last_id;           // incremented by 1 w/ every "new". Not MT-safe
  Definition *definition;

  void hwc_init (Hwcentry *ctr, const char* _aux, const char* _cmdname, const char* _username, int v_styles);
  void init (Type t);
  char *get_basetype_name ();
  void specify ();
  void specify_metric (char *_cond_spec, char *_val_spec);
  void set_val_spec (char *_val_spec);
  void specify_mstate_metric (int st);
  void specify_ompstate_metric (int st);
  void specify_prof_metric (char *_cond_spec);
};

class Definition
{
public:

  enum opType
  {
    opNULL,
    opPrimitive,
    opDivide
  };

  Definition (opType _op);
  ~Definition ();
  static Definition *add_definition (char *_def);
  Vector<BaseMetric *> *get_dependencies ();
  long *get_map ();
  double eval (long *indexes, TValue *values);

  opType op;
  Definition *arg1;
  Definition *arg2;
  char *def;

private:
  BaseMetric *bm;
  long *map;
  Vector<BaseMetric *> *dependencies;
  long index;
};

#endif  /* _BASEMETRIC_H */

