//===-- PThreadEvent.cpp ----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/16/07.
//
//===----------------------------------------------------------------------===//

#include "PThreadEvent.h"
#include "DNBLog.h"
#include "errno.h"

PThreadEvent::PThreadEvent(uint32_t bits, uint32_t validBits)
    : m_mutex(), m_set_condition(), m_reset_condition(), m_bits(bits),
      m_validBits(validBits), m_reset_ack_mask(0) {
  // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, 0x%8.8x)",
  // this, __FUNCTION__, bits, validBits);
}

PThreadEvent::~PThreadEvent() {
  // DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
}

uint32_t PThreadEvent::NewEventBit() {
  // DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
  PTHREAD_MUTEX_LOCKER(locker, m_mutex);
  uint32_t mask = 1;
  while (mask & m_validBits)
    mask <<= 1;
  m_validBits |= mask;
  return mask;
}

void PThreadEvent::FreeEventBits(const uint32_t mask) {
  // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
  // __FUNCTION__, mask);
  if (mask) {
    PTHREAD_MUTEX_LOCKER(locker, m_mutex);
    m_bits &= ~mask;
    m_validBits &= ~mask;
  }
}

uint32_t PThreadEvent::GetEventBits() const {
  // DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
  PTHREAD_MUTEX_LOCKER(locker, m_mutex);
  uint32_t bits = m_bits;
  return bits;
}

// Replace the event bits with a new bitmask value
void PThreadEvent::ReplaceEventBits(const uint32_t bits) {
  // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
  // __FUNCTION__, bits);
  PTHREAD_MUTEX_LOCKER(locker, m_mutex);
  // Make sure we have some bits and that they aren't already set...
  if (m_bits != bits) {
    // Figure out which bits are changing
    uint32_t changed_bits = m_bits ^ bits;
    // Set the new bit values
    m_bits = bits;
    // If any new bits are set, then broadcast
    if (changed_bits & m_bits)
      m_set_condition.Broadcast();
  }
}

// Set one or more event bits and broadcast if any new event bits get set
// that weren't already set.

void PThreadEvent::SetEvents(const uint32_t mask) {
  // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
  // __FUNCTION__, mask);
  // Make sure we have some bits to set
  if (mask) {
    PTHREAD_MUTEX_LOCKER(locker, m_mutex);
    // Save the old event bit state so we can tell if things change
    uint32_t old = m_bits;
    // Set the all event bits that are set in 'mask'
    m_bits |= mask;
    // Broadcast only if any extra bits got set.
    if (old != m_bits)
      m_set_condition.Broadcast();
  }
}

// Reset one or more event bits
void PThreadEvent::ResetEvents(const uint32_t mask) {
  // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
  // __FUNCTION__, mask);
  if (mask) {
    PTHREAD_MUTEX_LOCKER(locker, m_mutex);

    // Save the old event bit state so we can tell if things change
    uint32_t old = m_bits;
    // Clear the all event bits that are set in 'mask'
    m_bits &= ~mask;
    // Broadcast only if any extra bits got reset.
    if (old != m_bits)
      m_reset_condition.Broadcast();
  }
}

// Wait until 'timeout_abstime' for any events that are set in
// 'mask'. If 'timeout_abstime' is NULL, then wait forever.
uint32_t
PThreadEvent::WaitForSetEvents(const uint32_t mask,
                               const struct timespec *timeout_abstime) const {
  // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
  // __FUNCTION__, mask, timeout_abstime);
  int err = 0;
  // pthread_cond_timedwait() or pthread_cond_wait() will atomically
  // unlock the mutex and wait for the condition to be set. When either
  // function returns, they will re-lock the mutex. We use an auto lock/unlock
  // class (PThreadMutex::Locker) to allow us to return at any point in this
  // function and not have to worry about unlocking the mutex.
  PTHREAD_MUTEX_LOCKER(locker, m_mutex);
  do {
    // Check our predicate (event bits) in case any are already set
    if (mask & m_bits) {
      uint32_t bits_set = mask & m_bits;
      // Our PThreadMutex::Locker will automatically unlock our mutex
      return bits_set;
    }
    if (timeout_abstime) {
      // Wait for condition to get broadcast, or for a timeout. If we get
      // a timeout we will drop out of the do loop and return false which
      // is what we want.
      err = ::pthread_cond_timedwait(m_set_condition.Condition(),
                                     m_mutex.Mutex(), timeout_abstime);
      // Retest our predicate in case of a race condition right at the end
      // of the timeout.
      if (err == ETIMEDOUT) {
        uint32_t bits_set = mask & m_bits;
        return bits_set;
      }
    } else {
      // Wait for condition to get broadcast. The only error this function
      // should return is if
      err = ::pthread_cond_wait(m_set_condition.Condition(), m_mutex.Mutex());
    }
  } while (err == 0);
  return 0;
}

// Wait until 'timeout_abstime' for any events in 'mask' to reset.
// If 'timeout_abstime' is NULL, then wait forever.
uint32_t PThreadEvent::WaitForEventsToReset(
    const uint32_t mask, const struct timespec *timeout_abstime) const {
  // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
  // __FUNCTION__, mask, timeout_abstime);
  int err = 0;
  // pthread_cond_timedwait() or pthread_cond_wait() will atomically
  // unlock the mutex and wait for the condition to be set. When either
  // function returns, they will re-lock the mutex. We use an auto lock/unlock
  // class (PThreadMutex::Locker) to allow us to return at any point in this
  // function and not have to worry about unlocking the mutex.
  PTHREAD_MUTEX_LOCKER(locker, m_mutex);
  do {
    // Check our predicate (event bits) each time through this do loop
    if ((mask & m_bits) == 0) {
      // All the bits requested have been reset, return zero indicating
      // which bits from the mask were still set (none of them)
      return 0;
    }
    if (timeout_abstime) {
      // Wait for condition to get broadcast, or for a timeout. If we get
      // a timeout we will drop out of the do loop and return false which
      // is what we want.
      err = ::pthread_cond_timedwait(m_reset_condition.Condition(),
                                     m_mutex.Mutex(), timeout_abstime);
    } else {
      // Wait for condition to get broadcast. The only error this function
      // should return is if
      err = ::pthread_cond_wait(m_reset_condition.Condition(), m_mutex.Mutex());
    }
  } while (err == 0);
  // Return a mask indicating which bits (if any) were still set
  return mask & m_bits;
}

uint32_t
PThreadEvent::WaitForResetAck(const uint32_t mask,
                              const struct timespec *timeout_abstime) const {
  if (mask & m_reset_ack_mask) {
    // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
    // __FUNCTION__, mask, timeout_abstime);
    return WaitForEventsToReset(mask & m_reset_ack_mask, timeout_abstime);
  }
  return 0;
}
