Move fibers out of experimental
[folly.git] / folly / experimental / fibers / TimedMutex-inl.h
diff --git a/folly/experimental/fibers/TimedMutex-inl.h b/folly/experimental/fibers/TimedMutex-inl.h
deleted file mode 100644 (file)
index 96ee606..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2016 Facebook, Inc.
- *
- * 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.
- */
-#pragma once
-
-namespace folly {
-namespace fibers {
-
-//
-// TimedMutex implementation
-//
-
-template <typename BatonType>
-void TimedMutex<BatonType>::lock() {
-  pthread_spin_lock(&lock_);
-  if (!locked_) {
-    locked_ = true;
-    pthread_spin_unlock(&lock_);
-    return;
-  }
-
-  // Delay constructing the waiter until it is actually required.
-  // This makes a huge difference, at least in the benchmarks,
-  // when the mutex isn't locked.
-  MutexWaiter waiter;
-  waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
-  waiter.baton.wait();
-}
-
-template <typename BatonType>
-template <typename Rep, typename Period>
-bool TimedMutex<BatonType>::timed_lock(
-    const std::chrono::duration<Rep, Period>& duration) {
-  pthread_spin_lock(&lock_);
-  if (!locked_) {
-    locked_ = true;
-    pthread_spin_unlock(&lock_);
-    return true;
-  }
-
-  MutexWaiter waiter;
-  waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
-
-  if (!waiter.baton.timed_wait(duration)) {
-    // We timed out. Two cases:
-    // 1. We're still in the waiter list and we truly timed out
-    // 2. We're not in the waiter list anymore. This could happen if the baton
-    //    times out but the mutex is unlocked before we reach this code. In this
-    //    case we'll pretend we got the lock on time.
-    pthread_spin_lock(&lock_);
-    if (waiter.hook.is_linked()) {
-      waiters_.erase(waiters_.iterator_to(waiter));
-      pthread_spin_unlock(&lock_);
-      return false;
-    }
-    pthread_spin_unlock(&lock_);
-  }
-  return true;
-}
-
-template <typename BatonType>
-bool TimedMutex<BatonType>::try_lock() {
-  pthread_spin_lock(&lock_);
-  if (locked_) {
-    pthread_spin_unlock(&lock_);
-    return false;
-  }
-  locked_ = true;
-  pthread_spin_unlock(&lock_);
-  return true;
-}
-
-template <typename BatonType>
-void TimedMutex<BatonType>::unlock() {
-  pthread_spin_lock(&lock_);
-  if (waiters_.empty()) {
-    locked_ = false;
-    pthread_spin_unlock(&lock_);
-    return;
-  }
-  MutexWaiter& to_wake = waiters_.front();
-  waiters_.pop_front();
-  to_wake.baton.post();
-  pthread_spin_unlock(&lock_);
-}
-
-//
-// TimedRWMutex implementation
-//
-
-template <typename BatonType>
-void TimedRWMutex<BatonType>::read_lock() {
-  pthread_spin_lock(&lock_);
-  if (state_ == State::WRITE_LOCKED) {
-    MutexWaiter waiter;
-    read_waiters_.push_back(waiter);
-    pthread_spin_unlock(&lock_);
-    waiter.baton.wait();
-    assert(state_ == State::READ_LOCKED);
-    return;
-  }
-  assert(
-      (state_ == State::UNLOCKED && readers_ == 0) ||
-      (state_ == State::READ_LOCKED && readers_ > 0));
-  assert(read_waiters_.empty());
-  state_ = State::READ_LOCKED;
-  readers_ += 1;
-  pthread_spin_unlock(&lock_);
-}
-
-template <typename BatonType>
-template <typename Rep, typename Period>
-bool TimedRWMutex<BatonType>::timed_read_lock(
-    const std::chrono::duration<Rep, Period>& duration) {
-  pthread_spin_lock(&lock_);
-  if (state_ == State::WRITE_LOCKED) {
-    MutexWaiter waiter;
-    read_waiters_.push_back(waiter);
-    pthread_spin_unlock(&lock_);
-
-    if (!waiter.baton.timed_wait(duration)) {
-      // We timed out. Two cases:
-      // 1. We're still in the waiter list and we truly timed out
-      // 2. We're not in the waiter list anymore. This could happen if the baton
-      //    times out but the mutex is unlocked before we reach this code. In
-      //    this case we'll pretend we got the lock on time.
-      pthread_spin_lock(&lock_);
-      if (waiter.hook.is_linked()) {
-        read_waiters_.erase(read_waiters_.iterator_to(waiter));
-        pthread_spin_unlock(&lock_);
-        return false;
-      }
-      pthread_spin_unlock(&lock_);
-    }
-    return true;
-  }
-  assert(
-      (state_ == State::UNLOCKED && readers_ == 0) ||
-      (state_ == State::READ_LOCKED && readers_ > 0));
-  assert(read_waiters_.empty());
-  state_ = State::READ_LOCKED;
-  readers_ += 1;
-  pthread_spin_unlock(&lock_);
-  return true;
-}
-
-template <typename BatonType>
-bool TimedRWMutex<BatonType>::try_read_lock() {
-  pthread_spin_lock(&lock_);
-  if (state_ != State::WRITE_LOCKED) {
-    assert(
-        (state_ == State::UNLOCKED && readers_ == 0) ||
-        (state_ == State::READ_LOCKED && readers_ > 0));
-    assert(read_waiters_.empty());
-    state_ = State::READ_LOCKED;
-    readers_ += 1;
-    pthread_spin_unlock(&lock_);
-    return true;
-  }
-  pthread_spin_unlock(&lock_);
-  return false;
-}
-
-template <typename BatonType>
-void TimedRWMutex<BatonType>::write_lock() {
-  pthread_spin_lock(&lock_);
-  if (state_ == State::UNLOCKED) {
-    verify_unlocked_properties();
-    state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
-    return;
-  }
-  MutexWaiter waiter;
-  write_waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
-  waiter.baton.wait();
-}
-
-template <typename BatonType>
-template <typename Rep, typename Period>
-bool TimedRWMutex<BatonType>::timed_write_lock(
-    const std::chrono::duration<Rep, Period>& duration) {
-  pthread_spin_lock(&lock_);
-  if (state_ == State::UNLOCKED) {
-    verify_unlocked_properties();
-    state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
-    return true;
-  }
-  MutexWaiter waiter;
-  write_waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
-
-  if (!waiter.baton.timed_wait(duration)) {
-    // We timed out. Two cases:
-    // 1. We're still in the waiter list and we truly timed out
-    // 2. We're not in the waiter list anymore. This could happen if the baton
-    //    times out but the mutex is unlocked before we reach this code. In
-    //    this case we'll pretend we got the lock on time.
-    pthread_spin_lock(&lock_);
-    if (waiter.hook.is_linked()) {
-      write_waiters_.erase(write_waiters_.iterator_to(waiter));
-      pthread_spin_unlock(&lock_);
-      return false;
-    }
-    pthread_spin_unlock(&lock_);
-  }
-  assert(state_ == State::WRITE_LOCKED);
-  return true;
-}
-
-template <typename BatonType>
-bool TimedRWMutex<BatonType>::try_write_lock() {
-  pthread_spin_lock(&lock_);
-  if (state_ == State::UNLOCKED) {
-    verify_unlocked_properties();
-    state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
-    return true;
-  }
-  pthread_spin_unlock(&lock_);
-  return false;
-}
-
-template <typename BatonType>
-void TimedRWMutex<BatonType>::unlock() {
-  pthread_spin_lock(&lock_);
-  assert(state_ != State::UNLOCKED);
-  assert(
-      (state_ == State::READ_LOCKED && readers_ > 0) ||
-      (state_ == State::WRITE_LOCKED && readers_ == 0));
-  if (state_ == State::READ_LOCKED) {
-    readers_ -= 1;
-  }
-
-  if (!read_waiters_.empty()) {
-    assert(
-        state_ == State::WRITE_LOCKED && readers_ == 0 &&
-        "read waiters can only accumulate while write locked");
-    state_ = State::READ_LOCKED;
-    readers_ = read_waiters_.size();
-
-    while (!read_waiters_.empty()) {
-      MutexWaiter& to_wake = read_waiters_.front();
-      read_waiters_.pop_front();
-      to_wake.baton.post();
-    }
-  } else if (readers_ == 0) {
-    if (!write_waiters_.empty()) {
-      assert(read_waiters_.empty());
-      state_ = State::WRITE_LOCKED;
-
-      // Wake a single writer (after releasing the spin lock)
-      MutexWaiter& to_wake = write_waiters_.front();
-      write_waiters_.pop_front();
-      to_wake.baton.post();
-    } else {
-      verify_unlocked_properties();
-      state_ = State::UNLOCKED;
-    }
-  } else {
-    assert(state_ == State::READ_LOCKED);
-  }
-  pthread_spin_unlock(&lock_);
-}
-
-template <typename BatonType>
-void TimedRWMutex<BatonType>::downgrade() {
-  pthread_spin_lock(&lock_);
-  assert(state_ == State::WRITE_LOCKED && readers_ == 0);
-  state_ = State::READ_LOCKED;
-  readers_ += 1;
-
-  if (!read_waiters_.empty()) {
-    readers_ += read_waiters_.size();
-
-    while (!read_waiters_.empty()) {
-      MutexWaiter& to_wake = read_waiters_.front();
-      read_waiters_.pop_front();
-      to_wake.baton.post();
-    }
-  }
-  pthread_spin_unlock(&lock_);
-}
-}
-}