/*
 * Copyright (C) 2017 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 "common/vsoc/shm/lock.h"

#include "common/libs/glog/logging.h"
#include "common/vsoc/lib/compat.h"
#include "common/vsoc/lib/region_view.h"

#include <stdlib.h>

using vsoc::layout::Sides;

namespace {

const uint32_t LockFree = 0U;
const uint32_t GuestWaitingFlag = (Sides::Guest << 30);
const uint32_t HostWaitingFlag = (Sides::Host << 30);
const uint32_t OurWaitingFlag = (Sides::OurSide << 30);
static_assert(GuestWaitingFlag, "GuestWaitingFlag is 0");
static_assert(HostWaitingFlag, "HostWaitingFlag is 0");
static_assert((GuestWaitingFlag & HostWaitingFlag) == 0,
              "Waiting flags should not share bits");

// Set if the current owner is the host
const uint32_t HostIsOwner = 0x20000000U;

// PID_MAX_LIMIT appears to be 0x00400000U, so we're probably ok here
const uint32_t OwnerMask = 0x3FFFFFFFU;

uint32_t MakeOwnerTid(uint32_t raw_tid) {
  if (Sides::OurSide == Sides::Host) {
    return (raw_tid | HostIsOwner) & OwnerMask;
  } else {
    return raw_tid & (OwnerMask & ~HostIsOwner);
  }
}

};  // namespace

namespace vsoc {
/**
 * This is a generic synchronization primitive that provides space for the
 * owner of the lock to write platform-specific information.
 */
bool vsoc::layout::WaitingLockBase::TryLock(uint32_t tid,
                                            uint32_t* expected_out) {
  uint32_t masked_tid = MakeOwnerTid(tid);
  uint32_t expected = LockFree;
  while (1) {
    // First try to lock assuming that the mutex is free
    if (lock_uint32_.compare_exchange_strong(expected, masked_tid)) {
      // We got the lock.
      return true;
    }
    // We didn't get the lock and our wait flag is already set. It's safe to
    // try to sleep
    if (expected & OurWaitingFlag) {
      *expected_out = expected;
      return false;
    }
    // Attempt to set the wait flag. This will fail if the lock owner changes.
    while (1) {
      uint32_t add_wait_flag = expected | OurWaitingFlag;
      if (lock_uint32_.compare_exchange_strong(expected, add_wait_flag)) {
        // We set the waiting flag. Try to sleep.
        *expected_out = expected;
        return false;
      }
      // The owner changed, but we at least we got the wait flag.
      // Try sleeping
      if (expected & OurWaitingFlag) {
        *expected_out = expected;
        return false;
      }
      // Special case: the lock was just freed. Stop trying to set the
      // waiting flag and try to grab the lock.
      if (expected == LockFree) {
        break;
      }
      // The owner changed and we have no wait flag
      // Try to set the wait flag again
    }
    // This only happens if the lock was freed while we attempt the set the
    // wait flag. Try to grab the lock again
  }
  // Never reached.
}

layout::Sides vsoc::layout::WaitingLockBase::UnlockCommon(uint32_t tid) {
  uint32_t expected_state = lock_uint32_;

  // We didn't hold the lock. This process is insane and must die before it
  // does damage.
  uint32_t marked_tid = MakeOwnerTid(tid);
  if ((marked_tid ^ expected_state) & OwnerMask) {
    LOG(FATAL) << tid << " unlocking " << this << " owned by "
               << expected_state;
  }
  // If contention is just starting this may fail twice (once for each bit)
  // expected_state updates on each failure. When this finishes we have
  // one bit for each waiter
  while (1) {
    if (lock_uint32_.compare_exchange_strong(expected_state, LockFree)) {
      break;
    }
  }
  if ((expected_state ^ marked_tid) & OwnerMask) {
    LOG(FATAL) << "Lock owner of " << this << " changed from " << tid << " to "
               << expected_state << " during unlock";
  }
  Sides rval;
  rval.value_ = expected_state & (GuestWaitingFlag | HostWaitingFlag) >> 30;
  return rval;
}

bool vsoc::layout::WaitingLockBase::RecoverSingleSided() {
  // No need to signal because the caller ensured that there were no other
  // threads...
  return lock_uint32_.exchange(LockFree) != LockFree;
}

void layout::GuestAndHostLock::Lock(RegionView* region) {
  uint32_t expected;
  uint32_t tid = gettid();
  while (1) {
    if (TryLock(tid, &expected)) {
      return;
    }
    region->WaitForSignal(&lock_uint32_, expected);
  }
}

void layout::GuestAndHostLock::Unlock(RegionView* region) {
  region->SendSignal(UnlockCommon(gettid()), &lock_uint32_);
}

bool layout::GuestAndHostLock::Recover(RegionView* region) {
  uint32_t expected_state = lock_uint32_;
  uint32_t expected_owner_bit = (Sides::OurSide == Sides::Host) ? HostIsOwner : 0;
  // This avoids check then act by reading exactly once and then
  // eliminating the states where Recover should be a noop.
  if (expected_state == LockFree) {
    return false;
  }
  // Owned by the other side, do nothing.
  if ((expected_state & HostIsOwner) != expected_owner_bit) {
    return false;
  }
  // At this point we know two things:
  //   * The lock was held by our side
  //   * There are no other threads running on our side (precondition
  //     for calling Recover())
  // Therefore, we know that the current expected value should still
  // be in the lock structure. Use the normal unlock logic, providing
  // the tid that we observed in the lock.
  region->SendSignal(UnlockCommon(expected_state), &lock_uint32_);
  return true;
}

}  // namespace vsoc
