/* Copyright (C) 2021-2024 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 */

