/* Copyright (C) 2011-2026 Free Software Foundation, Inc.
   Contributed by Torvald Riegel <triegel@redhat.com>.

   This file is part of the GNU Transactional Memory Library (libitm).

   Libitm is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   Libitm 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 for
   more details.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */

#include "libitm_i.h"

using namespace GTM;

namespace {

// This group consists of all TM methods that synchronize via just a single
// global lock (or ownership record).
struct gl_mg : public method_group
{
  static const gtm_word LOCK_BIT = (~(gtm_word)0 >> 1) + 1;
  // We can't use the full bitrange because ~0 in gtm_thread::shared_state has
  // special meaning.
  static const gtm_word VERSION_MAX = (~(gtm_word)0 >> 1) - 1;
  static bool is_locked(gtm_word l) { return l & LOCK_BIT; }
  static gtm_word set_locked(gtm_word l) { return l | LOCK_BIT; }
  static gtm_word clear_locked(gtm_word l) { return l & ~LOCK_BIT; }

  // The global ownership record.
  // No tail-padding necessary (the virtual functions aren't used frequently).
  atomic<gtm_word> orec __attribute__((aligned(HW_CACHELINE_SIZE)));

  virtual void init()
  {
    // This store is only executed while holding the serial lock, so relaxed
    // memory order is sufficient here.
    orec.store(0, memory_order_relaxed);
  }
  virtual void fini() { }
};

static gl_mg o_gl_mg;


// The global lock, write-through TM method.
// Acquires the orec eagerly before the first write, and then writes through.
// Reads abort if the global orec's version number changed or if it is locked.
// Currently, writes require undo-logging to prevent deadlock between the
// serial lock and the global orec (writer txn acquires orec, reader txn
// upgrades to serial and waits for all other txns, writer tries to upgrade to
// serial too but cannot, writer cannot abort either, deadlock). We could
// avoid this if the serial lock would allow us to prevent other threads from
// going to serial mode, but this probably is too much additional complexity
// just to optimize this TM method.
// gtm_thread::shared_state is used to store a transaction's current
// snapshot time (or commit time). The serial lock uses ~0 for inactive
// transactions and 0 for active ones. Thus, we always have a meaningful
// timestamp in shared_state that can be used to implement quiescence-based
// privatization safety. This even holds if a writing transaction has the
// lock bit set in its shared_state because this is fine for both the serial
// lock (the value will be smaller than ~0) and privatization safety (we
// validate that no other update transaction committed before we acquired the
// orec, so we have the most recent timestamp and no other transaction can
// commit until we have committed).
// However, we therefore depend on shared_state not being modified by the
// serial lock during upgrades to serial mode, which is ensured by
// gtm_thread::serialirr_mode by not calling gtm_rwlock::write_upgrade_finish
// before we have committed or rolled back.
class gl_wt_dispatch : public abi_dispatch
{
protected:
  static void pre_write(const void *addr, size_t len,
      gtm_thread *tx = gtm_thr())
  {
    gtm_word v = tx->shared_state.load(memory_order_relaxed);
    if (unlikely(!gl_mg::is_locked(v)))
      {
	// Check for and handle version number overflow.
	if (unlikely(v >= gl_mg::VERSION_MAX))
	  tx->restart(RESTART_INIT_METHOD_GROUP);

	// This validates that we have a consistent snapshot, which is also
	// for making privatization safety work (see the class' comments).
	// Note that this check here will be performed by the subsequent CAS
	// again, so relaxed memory order is fine.
	gtm_word now = o_gl_mg.orec.load(memory_order_relaxed);
	if (now != v)
	  tx->restart(RESTART_VALIDATE_WRITE);

	// CAS global orec from our snapshot time to the locked state.
        // We need acquire memory order here to synchronize with other
        // (ownership) releases of the orec.  We do not need acq_rel order
        // because whenever another thread reads from this CAS'
        // modification, then it will abort anyway and does not rely on
        // any further happens-before relation to be established.
	// Also note that unlike in ml_wt's increase of the global time
	// base (remember that the global orec is used as time base), we do
	// not need require memory order here because we do not need to make
	// prior orec acquisitions visible to other threads that try to
	// extend their snapshot time.
	if (!o_gl_mg.orec.compare_exchange_strong (now, gl_mg::set_locked(now),
						   memory_order_acquire))
	  tx->restart(RESTART_LOCKED_WRITE);

	// We use an explicit fence here to avoid having to use release
	// memory order for all subsequent data stores.  This fence will
	// synchronize with loads of the data with acquire memory order.  See
	// validate() for why this is necessary.
        // Adding require memory order to the prior CAS is not sufficient,
        // at least according to the Batty et al. formalization of the
        // memory model.
	atomic_thread_fence(memory_order_release);

	// Set shared_state to new value.
	tx->shared_state.store(gl_mg::set_locked(now), memory_order_release);
      }

    tx->undolog.log(addr, len);
  }

  static void validate(gtm_thread *tx = gtm_thr())
  {
    // Check that snapshot is consistent.  We expect the previous data load to
    // have acquire memory order, or be atomic and followed by an acquire
    // fence.
    // As a result, the data load will synchronize with the release fence
    // issued by the transactions whose data updates the data load has read
    // from.  This forces the orec load to read from a visible sequence of side
    // effects that starts with the other updating transaction's store that
    // acquired the orec and set it to locked.
    // We therefore either read a value with the locked bit set (and restart)
    // or read an orec value that was written after the data had been written.
    // Either will allow us to detect inconsistent reads because it will have
    // a higher/different value.
    gtm_word l = o_gl_mg.orec.load(memory_order_relaxed);
    if (l != tx->shared_state.load(memory_order_relaxed))
      tx->restart(RESTART_VALIDATE_READ);
  }

  template <typename V> static V load(const V* addr, ls_modifier mod)
  {
    // Read-for-write should be unlikely, but we need to handle it or will
    // break later WaW optimizations.
    if (unlikely(mod == RfW))
      {
	pre_write(addr, sizeof(V));
	return *addr;
      }
    if (unlikely(mod == RaW))
      return *addr;

    // We do not have acquired the orec, so we need to load a value and then
    // validate that this was consistent.
    // This needs to have acquire memory order (see validate()).
    // Alternatively, we can put an acquire fence after the data load but this
    // is probably less efficient.
    // FIXME We would need an atomic load with acquire memory order here but
    // we can't just forge an atomic load for nonatomic data because this
    // might not work on all implementations of atomics.  However, we need
    // the acquire memory order and we can only establish this if we link
    // it to the matching release using a reads-from relation between atomic
    // loads.  Also, the compiler is allowed to optimize nonatomic accesses
    // differently than atomic accesses (e.g., if the load would be moved to
    // after the fence, we potentially don't synchronize properly anymore).
    // Instead of the following, just use an ordinary load followed by an
    // acquire fence, and hope that this is good enough for now:
    // V v = atomic_load_explicit((atomic<V>*)addr, memory_order_acquire);
    V v = *addr;
    atomic_thread_fence(memory_order_acquire);
    validate();
    return v;
  }

  template <typename V> static void store(V* addr, const V value,
      ls_modifier mod)
  {
    if (likely(mod != WaW))
      pre_write(addr, sizeof(V));
    // FIXME We would need an atomic store here but we can't just forge an
    // atomic load for nonatomic data because this might not work on all
    // implementations of atomics.  However, we need this store to link the
    // release fence in pre_write() to the acquire operation in load, which
    // is only guaranteed if we have a reads-from relation between atomic
    // accesses.  Also, the compiler is allowed to optimize nonatomic accesses
    // differently than atomic accesses (e.g., if the store would be moved
    // to before the release fence in pre_write(), things could go wrong).
    // atomic_store_explicit((atomic<V>*)addr, value, memory_order_relaxed);
    *addr = value;
  }

public:
  static void memtransfer_static(void *dst, const void* src, size_t size,
      bool may_overlap, ls_modifier dst_mod, ls_modifier src_mod)
  {
    gtm_thread *tx = gtm_thr();
    if (dst_mod != WaW && dst_mod != NONTXNAL)
      pre_write(dst, size, tx);
    // We need at least undo-logging for an RfW src region because we might
    // subsequently write there with WaW.
    if (src_mod == RfW)
      pre_write(src, size, tx);

    // FIXME We should use atomics here (see store()).  Let's just hope that
    // memcpy/memmove are good enough.
    if (!may_overlap)
      ::memcpy(dst, src, size);
    else
      ::memmove(dst, src, size);

    if (src_mod != RfW && src_mod != RaW && src_mod != NONTXNAL
	&& dst_mod != WaW)
      validate(tx);
  }

  static void memset_static(void *dst, int c, size_t size, ls_modifier mod)
  {
    if (mod != WaW)
      pre_write(dst, size);
    // FIXME We should use atomics here (see store()).  Let's just hope that
    // memset is good enough.
    ::memset(dst, c, size);
  }

  virtual gtm_restart_reason begin_or_restart()
  {
    // We don't need to do anything for nested transactions.
    gtm_thread *tx = gtm_thr();
    if (tx->parent_txns.size() > 0)
      return NO_RESTART;

    // Spin until global orec is not locked.
    // TODO This is not necessary if there are no pure loads (check txn props).
    unsigned i = 0;
    gtm_word v;
    while (1)
      {
        // We need acquire memory order here so that this load will
        // synchronize with the store that releases the orec in trycommit().
        // In turn, this makes sure that subsequent data loads will read from
        // a visible sequence of side effects that starts with the most recent
        // store to the data right before the release of the orec.
        v = o_gl_mg.orec.load(memory_order_acquire);
        if (!gl_mg::is_locked(v))
	  break;
	// TODO need method-specific max spin count
	if (++i > gtm_spin_count_var)
	  return RESTART_VALIDATE_READ;
	cpu_relax();
      }

    // Everything is okay, we have a snapshot time.
    // We don't need to enforce any ordering for the following store. There
    // are no earlier data loads in this transaction, so the store cannot
    // become visible before those (which could lead to the violation of
    // privatization safety). The store can become visible after later loads
    // but this does not matter because the previous value will have been
    // smaller or equal (the serial lock will set shared_state to zero when
    // marking the transaction as active, and restarts enforce immediate
    // visibility of a smaller or equal value with a barrier (see
    // rollback()).
    tx->shared_state.store(v, memory_order_relaxed);
    return NO_RESTART;
  }

  virtual bool trycommit(gtm_word& priv_time)
  {
    gtm_thread* tx = gtm_thr();
    gtm_word v = tx->shared_state.load(memory_order_relaxed);

    // Release the orec but do not reset shared_state, which will be modified
    // by the serial lock right after our commit anyway. Also, resetting
    // shared state here would interfere with the serial lock's use of this
    // location.
    if (gl_mg::is_locked(v))
      {
	// Release the global orec, increasing its version number / timestamp.
        // See begin_or_restart() for why we need release memory order here.
	v = gl_mg::clear_locked(v) + 1;
	o_gl_mg.orec.store(v, memory_order_release);
      }

    // Need to ensure privatization safety. Every other transaction must have
    // a snapshot time that is at least as high as our commit time (i.e., our
    // commit must be visible to them).  Because of proxy privatization, we
    // must ensure that even if we are a read-only transaction.  See
    // ml_wt_dispatch::trycommit() for details: We can't get quite the same
    // set of problems because we just use one orec and thus, for example,
    // there cannot be concurrent writers -- but we can still get pending
    // loads to privatized data when not ensuring privatization safety, which
    // is problematic if the program unmaps the privatized memory.
    priv_time = v;
    return true;
  }

  virtual void rollback(gtm_transaction_cp *cp)
  {
    // We don't do anything for rollbacks of nested transactions.
    if (cp != 0)
      return;

    gtm_thread *tx = gtm_thr();
    gtm_word v = tx->shared_state.load(memory_order_relaxed);

    // Release lock and increment version number to prevent dirty reads.
    // Also reset shared state here, so that begin_or_restart() can expect a
    // value that is correct wrt. privatization safety.
    if (gl_mg::is_locked(v))
      {
	// With our rollback, global time increases.
	v = gl_mg::clear_locked(v) + 1;

	// First reset the timestamp published via shared_state.  Release
	// memory order will make this happen after undoing prior data writes.
	// This must also happen before we actually release the global orec
	// next, so that future update transactions in other threads observe
	// a meaningful snapshot time for our transaction; otherwise, they
	// could read a shared_store value with the LOCK_BIT set, which can
	// break privatization safety because it's larger than the actual
	// snapshot time.  Note that we only need to consider other update
	// transactions because only those will potentially privatize data.
	tx->shared_state.store(v, memory_order_release);

	// Release the global orec, increasing its version number / timestamp.
	// See begin_or_restart() for why we need release memory order here,
	// and we also need it to make future update transactions read the
	// prior update to shared_state too (update transactions acquire the
	// global orec with acquire memory order).
	o_gl_mg.orec.store(v, memory_order_release);
      }

  }

  virtual bool snapshot_most_recent()
  {
    // This is the same check as in validate() except that we do not restart
    // on failure but simply return the result.
    return o_gl_mg.orec.load(memory_order_relaxed)
	== gtm_thr()->shared_state.load(memory_order_relaxed);
  }


  CREATE_DISPATCH_METHODS(virtual, )
  CREATE_DISPATCH_METHODS_MEM()

  gl_wt_dispatch() : abi_dispatch(false, true, false, false, 0, &o_gl_mg)
  { }
};

} // anon namespace

static const gl_wt_dispatch o_gl_wt_dispatch;

abi_dispatch *
GTM::dispatch_gl_wt ()
{
  return const_cast<gl_wt_dispatch *>(&o_gl_wt_dispatch);
}
