/*
 * Copyright 2022 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.
 */

#pragma once

#define FTL_ATTRIBUTE(a) __attribute__((a))

namespace android::ftl {

// Granular alternative to [[clang::no_thread_safety_analysis]]. Given a std::mutex-like object,
// FakeGuard suppresses enforcement of thread-safe access to guarded variables within its scope.
// While FakeGuard is scoped to a block, there are macro shorthands for a single expression, as
// well as function/lambda scope (though calls must be indirect, e.g. virtual or std::function):
//
//   struct {
//     std::mutex mutex;
//     int x FTL_ATTRIBUTE(guarded_by(mutex)) = -1;
//
//     int f() {
//       {
//         ftl::FakeGuard guard(mutex);
//         x = 0;
//       }
//
//       return FTL_FAKE_GUARD(mutex, x + 1);
//     }
//
//      std::function<int()> g() const {
//        return [this]() FTL_FAKE_GUARD(mutex) { return x; };
//      }
//   } s;
//
//   assert(s.f() == 1);
//   assert(s.g()() == 0);
//
// An example of a situation where FakeGuard helps is a mutex that guards writes on Thread 1, and
// reads on Thread 2. Reads on Thread 1, which is the only writer, need not be under lock, so can
// use FakeGuard to appease the thread safety analyzer. Another example is enforcing and documenting
// exclusive access by a single thread. This is done by defining a global constant that represents a
// thread context, and annotating guarded variables as if it were a mutex (though without any effect
// at run time):
//
//   constexpr class [[clang::capability("mutex")]] {
//   } kMainThreadContext;
//
template <typename Mutex>
struct [[clang::scoped_lockable]] FakeGuard final {
  explicit FakeGuard(const Mutex& mutex) FTL_ATTRIBUTE(acquire_capability(mutex)) {}
  [[clang::release_capability()]] ~FakeGuard() {}

  FakeGuard(const FakeGuard&) = delete;
  FakeGuard& operator=(const FakeGuard&) = delete;
};

}  // namespace android::ftl

// TODO: Enable in C++23 once standard attributes can be used on lambdas.
#if 0
#define FTL_FAKE_GUARD1(mutex) [[using clang: acquire_capability(mutex), release_capability(mutex)]]
#else
#define FTL_FAKE_GUARD1(mutex)             \
  FTL_ATTRIBUTE(acquire_capability(mutex)) \
  FTL_ATTRIBUTE(release_capability(mutex))
#endif

// The parentheses around `expr` are needed to deduce an lvalue or rvalue reference.
#define FTL_FAKE_GUARD2(mutex, expr)            \
  [&]() -> decltype(auto) {                     \
    const android::ftl::FakeGuard guard(mutex); \
    return (expr);                              \
  }()

#define FTL_MAKE_FAKE_GUARD(arg1, arg2, guard, ...) guard

#define FTL_FAKE_GUARD(...) \
  FTL_MAKE_FAKE_GUARD(__VA_ARGS__, FTL_FAKE_GUARD2, FTL_FAKE_GUARD1, )(__VA_ARGS__)
