/*
 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP
#define SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP

#include "memory/allocation.hpp"
#include "services/memoryPool.hpp"
#include "services/memoryService.hpp"

// Low Memory Detection Support
// Two memory alarms in the JDK (we called them sensors).
//   - Heap memory sensor
//   - Non-heap memory sensor
// When the VM detects if the memory usage of a memory pool has reached
// or exceeded its threshold, it will trigger the sensor for the type
// of the memory pool (heap or nonheap or both).
//
// If threshold == -1, no low memory detection is supported and
// the threshold value is not allowed to be changed.
// If threshold == 0, no low memory detection is performed for
// that memory pool.  The threshold can be set to any non-negative
// value.
//
// The default threshold of the Hotspot memory pools are:
//   Eden space        -1
//   Survivor space 1  -1
//   Survivor space 2  -1
//   Old generation    0
//   Perm generation   0
//   CodeCache         0
//
// For heap memory, detection will be performed when GC finishes
// and also in the slow path allocation.
// For Code cache, detection will be performed in the allocation
// and deallocation.
//
// May need to deal with hysteresis effect.
//
// Memory detection code runs in the Service thread (serviceThread.hpp).

class OopClosure;
class MemoryPool;

class ThresholdSupport : public CHeapObj<mtInternal> {
 private:
  bool            _support_high_threshold;
  bool            _support_low_threshold;
  size_t          _high_threshold;
  size_t          _low_threshold;
 public:
  ThresholdSupport(bool support_high, bool support_low) {
    _support_high_threshold = support_high;
    _support_low_threshold = support_low;
    _high_threshold = 0;
    _low_threshold= 0;
  }

  size_t      high_threshold() const        { return _high_threshold; }
  size_t      low_threshold()  const        { return _low_threshold; }
  bool        is_high_threshold_supported() { return _support_high_threshold; }
  bool        is_low_threshold_supported()  { return _support_low_threshold; }

  bool        is_high_threshold_crossed(MemoryUsage usage) {
    if (_support_high_threshold && _high_threshold > 0) {
      return (usage.used() >= _high_threshold);
    }
    return false;
  }
  bool        is_low_threshold_crossed(MemoryUsage usage) {
    if (_support_low_threshold && _low_threshold > 0) {
      return (usage.used() < _low_threshold);
    }
    return false;
  }

  size_t      set_high_threshold(size_t new_threshold) {
    assert(_support_high_threshold, "can only be set if supported");
    assert(new_threshold >= _low_threshold, "new_threshold must be >= _low_threshold");
    size_t prev = _high_threshold;
    _high_threshold = new_threshold;
    return prev;
  }

  size_t      set_low_threshold(size_t new_threshold) {
    assert(_support_low_threshold, "can only be set if supported");
    assert(new_threshold <= _high_threshold, "new_threshold must be <= _high_threshold");
    size_t prev = _low_threshold;
    _low_threshold = new_threshold;
    return prev;
  }
};

class SensorInfo : public CHeapObj<mtInternal> {
private:
  instanceOop     _sensor_obj;
  bool            _sensor_on;
  size_t          _sensor_count;

  // before the actual sensor on flag and sensor count are set
  // we maintain the number of pending triggers and clears.
  // _pending_trigger_count means the number of pending triggers
  // and the sensor count should be incremented by the same number.

  int             _pending_trigger_count;

  // _pending_clear_count takes precedence if it's > 0 which
  // indicates the resulting sensor will be off
  // Sensor trigger requests will reset this clear count to
  // indicate the resulting flag should be on.

  int             _pending_clear_count;

  MemoryUsage     _usage;

  void clear(int count, TRAPS);
  void trigger(int count, TRAPS);
public:
  SensorInfo();
  void set_sensor(instanceOop sensor) {
    assert(_sensor_obj == NULL, "Should be set only once");
    _sensor_obj = sensor;
  }

  bool has_pending_requests() {
    return (_pending_trigger_count > 0 || _pending_clear_count > 0);
  }

  int pending_trigger_count()      { return _pending_trigger_count; }
  int pending_clear_count()        { return _pending_clear_count; }

  // When this method is used, the memory usage is monitored
  // as a gauge attribute.  High and low thresholds are designed
  // to provide a hysteresis mechanism to avoid repeated triggering
  // of notifications when the attribute value makes small oscillations
  // around the high or low threshold value.
  //
  // The sensor will be triggered if:
  //  (1) the usage is crossing above the high threshold and
  //      the sensor is currently off and no pending
  //      trigger requests; or
  //  (2) the usage is crossing above the high threshold and
  //      the sensor will be off (i.e. sensor is currently on
  //      and has pending clear requests).
  //
  // Subsequent crossings of the high threshold value do not cause
  // any triggers unless the usage becomes less than the low threshold.
  //
  // The sensor will be cleared if:
  //  (1) the usage is crossing below the low threshold and
  //      the sensor is currently on and no pending
  //      clear requests; or
  //  (2) the usage is crossing below the low threshold and
  //      the sensor will be on (i.e. sensor is currently off
  //      and has pending trigger requests).
  //
  // Subsequent crossings of the low threshold value do not cause
  // any clears unless the usage becomes greater than or equal
  // to the high threshold.
  //
  // If the current level is between high and low threhsold, no change.
  //
  void set_gauge_sensor_level(MemoryUsage usage, ThresholdSupport* high_low_threshold);

  // When this method is used, the memory usage is monitored as a
  // simple counter attribute.  The sensor will be triggered
  // whenever the usage is crossing the threshold to keep track
  // of the number of times the VM detects such a condition occurs.
  //
  // The sensor will be triggered if:
  //   - the usage is crossing above the high threshold regardless
  //     of the current sensor state.
  //
  // The sensor will be cleared if:
  //  (1) the usage is crossing below the low threshold and
  //      the sensor is currently on; or
  //  (2) the usage is crossing below the low threshold and
  //      the sensor will be on (i.e. sensor is currently off
  //      and has pending trigger requests).
  //
  void set_counter_sensor_level(MemoryUsage usage, ThresholdSupport* counter_threshold);

  void process_pending_requests(TRAPS);
  void oops_do(OopClosure* f);

#ifndef PRODUCT
  // printing on default output stream;
  void print();
#endif // PRODUCT
};

class LowMemoryDetector : public AllStatic {
  friend class LowMemoryDetectorDisabler;
  friend class ServiceThread;
private:
  // true if any collected heap has low memory detection enabled
  static volatile bool _enabled_for_collected_pools;
  // > 0 if temporary disabed
  static volatile jint _disabled_count;

  static void check_memory_usage();
  static bool has_pending_requests();
  static bool temporary_disabled() { return _disabled_count > 0; }
  static void disable() { Atomic::inc(&_disabled_count); }
  static void enable() { Atomic::dec(&_disabled_count); }
  static void process_sensor_changes(TRAPS);

public:
  static void detect_low_memory();
  static void detect_low_memory(MemoryPool* pool);
  static void detect_after_gc_memory(MemoryPool* pool);

  static bool is_enabled(MemoryPool* pool) {
    // low memory detection is enabled for collected memory pools
    // iff one of the collected memory pool has a sensor and the
    // threshold set non-zero
    if (pool->usage_sensor() == NULL) {
      return false;
    } else {
      ThresholdSupport* threshold_support = pool->usage_threshold();
      return (threshold_support->is_high_threshold_supported() ?
               (threshold_support->high_threshold() > 0) : false);
    }
  }

  // indicates if low memory detection is enabled for any collected
  // memory pools
  static inline bool is_enabled_for_collected_pools() {
    return !temporary_disabled() && _enabled_for_collected_pools;
  }

  // recompute enabled flag
  static void recompute_enabled_for_collected_pools();

  // low memory detection for collected memory pools.
  static inline void detect_low_memory_for_collected_pools() {
    // no-op if low memory detection not enabled
    if (!is_enabled_for_collected_pools()) {
      return;
    }
    int num_memory_pools = MemoryService::num_memory_pools();
    for (int i=0; i<num_memory_pools; i++) {
      MemoryPool* pool = MemoryService::get_memory_pool(i);

      // if low memory detection is enabled then check if the
      // current used exceeds the high threshold
      if (pool->is_collected_pool() && is_enabled(pool)) {
        size_t used = pool->used_in_bytes();
        size_t high = pool->usage_threshold()->high_threshold();
        if (used > high) {
          detect_low_memory(pool);
        }
      }
    }
  }
};

class LowMemoryDetectorDisabler: public StackObj {
public:
  LowMemoryDetectorDisabler()
  {
    LowMemoryDetector::disable();
  }
  ~LowMemoryDetectorDisabler()
  {
    assert(LowMemoryDetector::temporary_disabled(), "should be disabled!");
    LowMemoryDetector::enable();
  }
};

#endif // SHARE_VM_SERVICES_LOWMEMORYDETECTOR_HPP
