/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "barrier.h"

#include <android-base/logging.h>

#include "base/aborting.h"
#include "base/mutex.h"
#include "base/time_utils.h"
#include "thread.h"

namespace art HIDDEN {

Barrier::Barrier(int count, bool verify_count_on_shutdown)
    : count_(count),
      lock_(new Mutex("GC barrier lock", kThreadSuspendCountLock)),
      condition_(new ConditionVariable("GC barrier condition", *lock_)),
      verify_count_on_shutdown_(verify_count_on_shutdown) {
}

template void Barrier::Increment<Barrier::kAllowHoldingLocks>(Thread* self, int delta);
template void Barrier::Increment<Barrier::kDisallowHoldingLocks>(Thread* self, int delta);

void Barrier::Pass(Thread* self) {
  MutexLock mu(self, *GetLock());
  SetCountLocked(self, count_ - 1);
}

void Barrier::IncrementNoWait(Thread* self) {
  MutexLock mu(self, *GetLock());
  SetCountLocked(self, count_ + 1);
}

void Barrier::Wait(Thread* self) {
  Increment(self, -1);
}

void Barrier::Init(Thread* self, int count) {
  MutexLock mu(self, *GetLock());
  SetCountLocked(self, count);
}

template <Barrier::LockHandling locks>
void Barrier::Increment(Thread* self, int delta) {
  MutexLock mu(self, *GetLock());
  SetCountLocked(self, count_ + delta);

  // Increment the count.  If it becomes zero after the increment
  // then all the threads have already passed the barrier.  If
  // it is non-zero then there is still one or more threads
  // that have not yet called the Pass function.  When the
  // Pass function is called by the last thread, the count will
  // be decremented to zero and a Broadcast will be made on the
  // condition variable, thus waking this up.
  while (count_ != 0) {
    if (locks == kAllowHoldingLocks) {
      condition_->WaitHoldingLocks(self);
    } else {
      condition_->Wait(self);
    }
  }
}

bool Barrier::Increment(Thread* self, int delta, uint32_t timeout_ms) {
  MutexLock mu(self, *GetLock());
  SetCountLocked(self, count_ + delta);
  bool timed_out = false;
  if (count_ != 0) {
    uint32_t timeout_ns = 0;
    uint64_t abs_timeout = NanoTime() + MsToNs(timeout_ms);
    for (;;) {
      timed_out = condition_->TimedWait(self, timeout_ms, timeout_ns);
      if (timed_out || count_ == 0) return timed_out;
      // Compute time remaining on timeout.
      uint64_t now = NanoTime();
      int64_t time_left = abs_timeout - now;
      if (time_left <= 0) return true;
      timeout_ns = time_left % (1000*1000);
      timeout_ms = time_left / (1000*1000);
    }
  }
  return timed_out;
}

int Barrier::GetCount(Thread* self) {
  MutexLock mu(self, *GetLock());
  return count_;
}

void Barrier::SetCountLocked(Thread* self, int count) {
  count_ = count;
  if (count == 0) {
    condition_->Broadcast(self);
  }
}

Barrier::~Barrier() {
  if (count_ != 0) {
    // Only check when not aborting and if we verify the count on shutdown.
    LOG((gAborting == 0 && verify_count_on_shutdown_) ? FATAL : WARNING)
        << "Attempted to destroy barrier with non zero count " << count_;
  }
}

}  // namespace art
