bool LowMemoryDetector::has_pending_requests() {
  assert(Service_lock->owned_by_self(), "Must own Service_lock");
  bool has_requests = false;
  int num_memory_pools = MemoryService::num_memory_pools();
  for (int i = 0; i < num_memory_pools; i++) {
    MemoryPool* pool = MemoryService::get_memory_pool(i);
    SensorInfo* sensor = pool->usage_sensor();
    if (sensor != NULL) {
      has_requests = has_requests || sensor->has_pending_requests();
    }

    SensorInfo* gc_sensor = pool->gc_usage_sensor();
    if (gc_sensor != NULL) {
      has_requests = has_requests || gc_sensor->has_pending_requests();
    }
  }
  return has_requests;
}
void LowMemoryDetector::process_sensor_changes(TRAPS) {
  ResourceMark rm(THREAD);
  HandleMark hm(THREAD);

  // No need to hold Service_lock to call out to Java
  int num_memory_pools = MemoryService::num_memory_pools();
  for (int i = 0; i < num_memory_pools; i++) {
    MemoryPool* pool = MemoryService::get_memory_pool(i);
    SensorInfo* sensor = pool->usage_sensor();
    SensorInfo* gc_sensor = pool->gc_usage_sensor();
    if (sensor != NULL && sensor->has_pending_requests()) {
      sensor->process_pending_requests(CHECK);
    }
    if (gc_sensor != NULL && gc_sensor->has_pending_requests()) {
      gc_sensor->process_pending_requests(CHECK);
    }
  }
}
void LowMemoryDetector::low_memory_detector_thread_entry(JavaThread* jt, TRAPS) {
  while (true) {
    bool   sensors_changed = false;

    {
      // _no_safepoint_check_flag is used here as LowMemory_lock is a
      // special lock and the VMThread may acquire this lock at safepoint.
      // Need state transition ThreadBlockInVM so that this thread
      // will be handled by safepoint correctly when this thread is
      // notified at a safepoint.

      // This ThreadBlockInVM object is not also considered to be
      // suspend-equivalent because LowMemoryDetector threads are
      // not visible to external suspension.

      ThreadBlockInVM tbivm(jt);

      MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag);
      while (!(sensors_changed = has_pending_requests())) {
        // wait until one of the sensors has pending requests
        LowMemory_lock->wait(Mutex::_no_safepoint_check_flag);
      }
    }

    {
      ResourceMark rm(THREAD);
      HandleMark hm(THREAD);

      // No need to hold LowMemory_lock to call out to Java
      int num_memory_pools = MemoryService::num_memory_pools();
      for (int i = 0; i < num_memory_pools; i++) {
        MemoryPool* pool = MemoryService::get_memory_pool(i);
        SensorInfo* sensor = pool->usage_sensor();
        SensorInfo* gc_sensor = pool->gc_usage_sensor();
        if (sensor != NULL && sensor->has_pending_requests()) {
          sensor->process_pending_requests(CHECK);
        }
        if (gc_sensor != NULL && gc_sensor->has_pending_requests()) {
          gc_sensor->process_pending_requests(CHECK);
        }
      }
    }
  }
}