/*
 * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_RUNTIME_MUTEX_HPP
#define SHARE_RUNTIME_MUTEX_HPP

#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
#include "runtime/semaphore.hpp"

#if defined(LINUX) || defined(AIX) || defined(BSD)
# include "mutex_posix.hpp"
#else
# include OS_HEADER(mutex)
#endif


// A Mutex/Monitor is a simple wrapper around a native lock plus condition
// variable that supports lock ownership tracking, lock ranking for deadlock
// detection and coordinates with the safepoint protocol.

// Locking is non-recursive: if you try to lock a mutex you already own then you
// will get an assertion failure in a debug build (which should suffice to expose
// usage bugs). If you call try_lock on a mutex you already own it will return false.
// The underlying PlatformMutex may support recursive locking but this is not exposed
// and we account for that possibility in try_lock.

// A thread is not allowed to safepoint while holding a mutex whose rank
// is nosafepoint or lower.

// The Mutex class used to explicitly guarantee fence(); lock(); acquire(); semantics with
// a hand crafted implementation. That may or may not be a desirable contract for a Mutex,
// but is nevertheless something that older HotSpot code may or may not rely on for correctness.
// Newer code is encouraged not to rely more on this feature, but it is not generally safe to
// remove the fences, until all usages of Mutex have been evaluated on a case-by-case basis, whether
// they actually rely on this stronger contract, or not.

// Having a fence does not have any significant impact on peformance, as this is an internal VM
// mutex and is generally not in hot code paths.

class Mutex : public CHeapObj<mtSynchronizer> {

  friend class VMStructs;
 public:
  // Special low level locks are given names and ranges avoid overlap.
  enum class Rank {
       event,
       service        = event          +   6,
       stackwatermark = service        +   3,
       tty            = stackwatermark +   3,
       oopstorage     = tty            +   3,
       nosafepoint    = oopstorage     +   6,
       safepoint      = nosafepoint    +  20
  };

  // want C++later "using enum" directives.
  static const Rank event          = Rank::event;
  static const Rank service        = Rank::service;
  static const Rank stackwatermark = Rank::stackwatermark;
  static const Rank tty            = Rank::tty;
  static const Rank oopstorage     = Rank::oopstorage;
  static const Rank nosafepoint    = Rank::nosafepoint;
  static const Rank safepoint      = Rank::safepoint;

  static void assert_no_overlap(Rank orig, Rank adjusted, int adjust);

  friend Rank operator-(Rank base, int adjust) {
    Rank result = static_cast<Rank>(static_cast<int>(base) - adjust);
    DEBUG_ONLY(assert_no_overlap(base, result, adjust));
    return result;
  }

  friend constexpr bool operator<(Rank lhs, Rank rhs) {
    return static_cast<int>(lhs) < static_cast<int>(rhs);
  }

  friend constexpr bool operator>(Rank lhs, Rank rhs)  { return rhs < lhs; }
  friend constexpr bool operator<=(Rank lhs, Rank rhs) { return !(lhs > rhs); }
  friend constexpr bool operator>=(Rank lhs, Rank rhs) { return !(lhs < rhs); }

 private:
  // The _owner field is only set by the current thread, either to itself after it has acquired
  // the low-level _lock, or to null before it has released the _lock. Accesses by any thread other
  // than the lock owner are inherently racy.
  Thread* volatile _owner;
  void raw_set_owner(Thread* new_owner) { Atomic::store(&_owner, new_owner); }

 protected:                              // Monitor-Mutex metadata
  PlatformMonitor _lock;                 // Native monitor implementation
  const char* _name;                     // Name of mutex/monitor

  // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
#ifndef PRODUCT
  bool    _allow_vm_block;
#endif
  static Mutex** _mutex_array;
  static int _num_mutex;

#ifdef ASSERT
  Rank    _rank;                 // rank (to avoid/detect potential deadlocks)
  Mutex*  _next;                 // Used by a Thread to link up owned locks
  Thread* _last_owner;           // the last thread to own the lock
  bool _skip_rank_check;         // read only by owner when doing rank checks

  static Mutex* get_least_ranked_lock(Mutex* locks);
  Mutex* get_least_ranked_lock_besides_this(Mutex* locks);
  bool skip_rank_check() {
    assert(owned_by_self(), "only the owner should call this");
    return _skip_rank_check;
  }

 public:
  Rank   rank() const          { return _rank; }
  const char*  rank_name() const;
  Mutex* next()  const         { return _next; }
#endif // ASSERT

 protected:
  void set_owner_implementation(Thread* owner)                        NOT_DEBUG({ raw_set_owner(owner);});
  void check_block_state       (Thread* thread)                       NOT_DEBUG_RETURN;
  void check_safepoint_state   (Thread* thread)                       NOT_DEBUG_RETURN;
  void check_no_safepoint_state(Thread* thread)                       NOT_DEBUG_RETURN;
  void check_rank              (Thread* thread)                       NOT_DEBUG_RETURN;
  void assert_owner            (Thread* expected)                     NOT_DEBUG_RETURN;

 public:
  static const bool _allow_vm_block_flag        = true;

  // Locks can be acquired with or without a safepoint check. NonJavaThreads do not follow
  // the safepoint protocol when acquiring locks.

  // Each lock can be acquired by only JavaThreads, only NonJavaThreads, or shared between
  // Java and NonJavaThreads. When the lock is initialized with rank > nosafepoint,
  // that means that whenever the lock is acquired by a JavaThread, it will verify that
  // it is done with a safepoint check. In corollary, when the lock is initialized with
  // rank <= nosafepoint, that means that whenever the lock is acquired by a JavaThread
  // it will verify that it is done without a safepoint check.

  // TODO: Locks that are shared between JavaThreads and NonJavaThreads
  // should never encounter a safepoint check while they are held, or else a
  // deadlock can occur. We should check this by noting which
  // locks are shared, and walk held locks during safepoint checking.

  enum class SafepointCheckFlag {
    _safepoint_check_flag,
    _no_safepoint_check_flag
  };
  // Bring the enumerator names into class scope.
  static const SafepointCheckFlag _safepoint_check_flag =
    SafepointCheckFlag::_safepoint_check_flag;
  static const SafepointCheckFlag _no_safepoint_check_flag =
    SafepointCheckFlag::_no_safepoint_check_flag;

 public:
  Mutex(Rank rank, const char *name, bool allow_vm_block);

  Mutex(Rank rank, const char *name) :
    Mutex(rank, name, rank > nosafepoint ? false : true) {}

  ~Mutex();

  void lock(); // prints out warning if VM thread blocks
  void lock(Thread *thread); // overloaded with current thread
  void unlock();
  bool is_locked() const                     { return owner() != nullptr; }

  bool try_lock(); // Like lock(), but unblocking. It returns false instead
 private:
  void lock_contended(Thread *thread); // contended slow-path
  bool try_lock_inner(bool do_rank_checks);
 public:

  void release_for_safepoint();

  // Lock without safepoint check. Should ONLY be used by safepoint code and other code
  // that is guaranteed not to block while running inside the VM.
  void lock_without_safepoint_check();
  void lock_without_safepoint_check(Thread* self);
  // A thread should not call this if failure to acquire ownership will blocks its progress
  bool try_lock_without_rank_check();

  // Current owner - note not MT-safe. Can only be used to guarantee that
  // the current running thread owns the lock
  Thread* owner() const         { return Atomic::load(&_owner); }
  void set_owner(Thread* owner) { set_owner_implementation(owner); }
  bool owned_by_self() const;

  const char *name() const                  { return _name; }

  static void  add_mutex(Mutex* var);

  void print_on_error(outputStream* st) const;
  #ifndef PRODUCT
    void print_on(outputStream* st) const;
    void print() const;
  #endif

  // Print all mutexes/monitors that are currently owned by a thread; called
  // by fatal error handler.
  static void print_owned_locks_on_error(outputStream* st);
  static void print_lock_ranks(outputStream* st);
};

class Monitor : public Mutex {
 public:
  Monitor(Rank rank, const char *name, bool allow_vm_block)  :
    Mutex(rank, name, allow_vm_block) {}

  Monitor(Rank rank, const char *name) :
    Mutex(rank, name) {}
  // default destructor

  // Wait until monitor is notified (or times out).
  // Defaults are to make safepoint checks, wait time is forever (i.e.,
  // zero). Returns true if wait times out; otherwise returns false.
  bool wait(uint64_t timeout = 0);
  bool wait_without_safepoint_check(uint64_t timeout = 0);
  void notify();
  void notify_all();
};


class PaddedMutex : public Mutex {
  enum {
    CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Mutex),
    PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
  };
  char _padding[PADDING_LEN];
public:
  PaddedMutex(Rank rank, const char *name, bool allow_vm_block) : Mutex(rank, name, allow_vm_block) {};
  PaddedMutex(Rank rank, const char *name) : Mutex(rank, name) {};
};

class PaddedMonitor : public Monitor {
  enum {
    CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Monitor),
    PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
  };
  char _padding[PADDING_LEN];
 public:
  PaddedMonitor(Rank rank, const char *name, bool allow_vm_block) : Monitor(rank, name, allow_vm_block) {};
  PaddedMonitor(Rank rank, const char *name) : Monitor(rank, name) {};
};

// RecursiveMutex is a minimal implementation, and has no safety and rank checks that Mutex has.
// There are also no checks that the recursive lock is not held when going to Java or to JNI, like
// other JVM mutexes have.  This should be used only for cases where the alternatives with all the
// nice safety features don't work.
// Waiting on the RecursiveMutex partipates in the safepoint protocol if the current thread is a Java thread,
// (ie. waiting sets JavaThread to blocked)
class RecursiveMutex : public CHeapObj<mtThread> {
  Semaphore  _sem;
  Thread*    _owner;
  int        _recursions;

  NONCOPYABLE(RecursiveMutex);
 public:
  RecursiveMutex();
  void lock(Thread* current);
  void unlock(Thread* current);
  // For use in asserts
  bool holds_lock(Thread* current) { return _owner == current; }
};

#endif // SHARE_RUNTIME_MUTEX_HPP
