/* loadavg.cc: load average support.

  This file is part of Cygwin.

  This software is a copyrighted work licensed under the terms of the
  Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
  details. */

/*
  Emulate load average

  There's a fair amount of approximation done here, so don't try to use this to
  actually measure anything, but it should be good enough for programs to
  throttle their activity based on load.

  A global load average estimate is maintained in shared memory.  Access to that
  is guarded by a mutex.  This estimate is only updated at most every 5 seconds.

  We attempt to count running and runnable processes, but unlike linux we don't
  count processes in uninterruptible sleep (blocked on I/O).

  The number of running processes is estimated as (NumberOfProcessors) * (%
  Processor Time).  The number of runnable processes is estimated as
  ProcessorQueueLength.

  Note that PDH will only return data for '% Processor Time' afer the second
  call to PdhCollectQueryData(), as it's computed over an interval, so the first
  attempt to estimate load will fail and 0.0 will be returned.

  We also assume that '% Processor Time' averaged over the interval since the
  last time getloadavg() was called is a good approximation of the instantaneous
  '% Processor Time'.
*/

#include "winsup.h"
#include "shared_info.h"
#include "loadavg.h"

#include <math.h>
#include <time.h>
#include <sys/strace.h>

/* Prototype for PdhAddEnglishCounterA in pdh.h under _WIN32_WINNT >= 0x0600 is
   missing WINAPI */
#undef	_WIN32_WINNT
#include <pdh.h>
extern "C"
PDH_FUNCTION PdhAddEnglishCounterA(PDH_HQUERY hQuery, LPCSTR szFullCounterPath,
				   DWORD_PTR dwUserData, PDH_HCOUNTER *phCounter);

static PDH_HQUERY query;
static PDH_HCOUNTER counter1;
static PDH_HCOUNTER counter2;
static HANDLE mutex;

static bool load_init (void)
{
  static NO_COPY bool tried = false;
  static NO_COPY bool initialized = false;

  if (!tried) {
    tried = true;

    if (!((PdhOpenQueryA (NULL, 0, &query) == ERROR_SUCCESS) &&
	  (PdhAddEnglishCounterA (query, "\\Processor(_Total)\\% Processor Time",
				  0, &counter1) == ERROR_SUCCESS) &&
	  (PdhAddEnglishCounterA (query, "\\System\\Processor Queue Length",
				  0, &counter2) == ERROR_SUCCESS))) {
      debug_printf("loadavg PDH initialization failed\n");
      return false;
    }

    mutex = CreateMutex(&sec_all_nih, FALSE, "cyg.loadavg.mutex");
    if (!mutex) {
      debug_printf("opening loadavg mutexfailed\n");
      return false;
    }

    initialized = true;
  }

  return initialized;
}

/* estimate the current load */
static bool get_load (double *load)
{
  *load = 0.0;

  PDH_STATUS ret = PdhCollectQueryData (query);
  if (ret != ERROR_SUCCESS)
    return false;

  /* Estimate the number of running processes as (NumberOfProcessors) * (%
     Processor Time) */
  PDH_FMT_COUNTERVALUE fmtvalue1;
  ret = PdhGetFormattedCounterValue (counter1, PDH_FMT_DOUBLE, NULL, &fmtvalue1);
  if (ret != ERROR_SUCCESS)
    return false;

  SYSTEM_INFO sysinfo;
  GetSystemInfo (&sysinfo);

  double running = fmtvalue1.doubleValue * sysinfo.dwNumberOfProcessors / 100;

  /* Estimate the number of runnable processes using ProcessorQueueLength */
  PDH_FMT_COUNTERVALUE fmtvalue2;
  ret = PdhGetFormattedCounterValue (counter2, PDH_FMT_LONG, NULL, &fmtvalue2);
  if (ret != ERROR_SUCCESS)
    return false;

  LONG rql = fmtvalue2.longValue;

  *load = rql + running;
  return true;
}

/*
  loadavginfo shared-memory object
*/

void loadavginfo::initialize ()
{
  for (int i = 0; i < 3; i++)
    loadavg[i] = 0.0;

  last_time = 0;
}

void loadavginfo::calc_load (int index, int delta_time, int decay_time, double n)
{
  double df = 1.0 / exp ((double)delta_time/decay_time);
  loadavg[index] = (loadavg[index] * df) + (n * (1.0 - df));
}

void loadavginfo::update_loadavg ()
{
  double active_tasks;

  if (!get_load (&active_tasks))
    return;

  /* Don't recalculate the load average if less than 5 seconds has elapsed since
     the last time it was calculated */
  time_t curr_time = time (NULL);
  int delta_time = curr_time - last_time;
  if (delta_time < 5) {
    return;
  }

  if (last_time == 0) {
    /* Initialize the load average to the current load */
    for (int i = 0; i < 3; i++) {
      loadavg[i] = active_tasks;
    }
  } else {
    /* Compute the exponentially weighted moving average over ... */
    calc_load (0, delta_time, 60,  active_tasks); /* ... 1 min */
    calc_load (1, delta_time, 300, active_tasks); /* ... 5 min */
    calc_load (2, delta_time, 900, active_tasks); /* ... 15 min */
  }

  last_time = curr_time;
}

int loadavginfo::fetch (double _loadavg[], int nelem)
{
  if (!load_init ())
    return 0;

  WaitForSingleObject(mutex, INFINITE);

  update_loadavg ();

  memcpy (_loadavg, loadavg, nelem * sizeof(double));

  ReleaseMutex(mutex);

  return nelem;
}

/* getloadavg: BSD */
extern "C" int
getloadavg (double loadavg[], int nelem)
{
  /* The maximum number of samples is 3 */
  if (nelem > 3)
    nelem = 3;

  /* Return the samples and number of samples retrieved */
  return cygwin_shared->loadavg.fetch(loadavg, nelem);
}
