products/Sources/formale Sprachen/Java/openjdk-20-36_src/src/hotspot/share/runtime image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: graphKit.cpp   Sprache: C

/*
 * Copyright (c) 1998, 2022, 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"

#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.

class Mutex : public CHeapObj<mtSynchronizer> {

 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
#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() != NULL; }

  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; }

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

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(int64_t timeout = 0);
  bool wait_without_safepoint_check(int64_t timeout = 0);
  void notify();
  void notify_all();
};


class PaddedMutex : public Mutex {
  enum {
    CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_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_CACHE_LINE_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) {};
};

#endif // SHARE_RUNTIME_MUTEX_HPP

¤ Dauer der Verarbeitung: 0.35 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff