/*****************************************************************************
Copyright ( c ) 2021 , MariaDB Corporation .
This program 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 ; version 2 of the License .
This program 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 .
You should have received a copy of the GNU General Public License along with
this program ; if not , write to the Free Software Foundation , Inc . ,
51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1335 USA
*****************************************************************************/
#pragma once
#if defined __powerpc64__
#elif defined __s390__
#elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) && !defined (__clang__)
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
# if __GNUC__ >= 8
# elif defined __clang_major__ && __clang_major__ > 6
# else
# define NO_ELISION
# endif
#else /* Transactional memory has not been implemented for this ISA */
# define NO_ELISION
#endif
#ifdef NO_ELISION
constexpr bool have_transactional_memory= false ;
# ifdef UNIV_DEBUG
static inline bool xtest() { return false ; }
# endif
# define TRANSACTIONAL_TARGET /* nothing */
# define TRANSACTIONAL_INLINE /* nothing */
#else
# if defined __i386__||defined __x86_64__||defined _M_IX86||defined _M_X64
extern bool have_transactional_memory;
bool transactional_lock_enabled() noexcept;
# include <immintrin.h>
# if defined __GNUC__ && !defined __INTEL_COMPILER
# define TRANSACTIONAL_TARGET __attribute__((target("rtm" ),hot))
# define TRANSACTIONAL_INLINE __attribute__((target("rtm" ),hot,always_inline))
# else
# define TRANSACTIONAL_TARGET /* nothing */
# define TRANSACTIONAL_INLINE /* nothing */
# endif
TRANSACTIONAL_INLINE static inline bool xbegin() noexcept
{
return have_transactional_memory && _xbegin() == _XBEGIN_STARTED;
}
# ifdef UNIV_DEBUG
# ifdef __GNUC__
/** @return whether a memory transaction is active */
bool xtest() noexcept;
# else
static inline bool xtest() noexcept { return have_transactional_memory && _xtest(); }
# endif
# endif
TRANSACTIONAL_INLINE static inline void xabort() noexcept { _xabort(0 ); }
TRANSACTIONAL_INLINE static inline void xend() noexcept { _xend(); }
# elif defined __powerpc64__ || defined __s390__
extern bool have_transactional_memory;
bool transactional_lock_enabled() noexcept;
# define TRANSACTIONAL_TARGET __attribute__((hot))
# define TRANSACTIONAL_INLINE __attribute__((hot,always_inline))
/**
Newer gcc compilers only provide _ _ builtin_ { htm }
functions when the - mhtm CFLAG is actually provided . So
we ' ve got the option of including it globally , or
pushing down the inclusion of htmxlintrin . h to one
file with - mhtm enabled and removing the inline
optimization .
Per FIXME in s390x ' s htmxlintrin . h , the _ _ TM_simple_begin
isn ' t always_inline resulting in duplicate definitions if
it where included more than once . While xabort and xend
could be implemented here , we keep the implementation the
same as ppc64 .
*/
TRANSACTIONAL_TARGET bool xbegin() noexcept;
TRANSACTIONAL_TARGET void xabort() noexcept;
TRANSACTIONAL_TARGET void xend() noexcept;
# ifdef UNIV_DEBUG
bool xtest() noexcept;
# endif
# endif
#endif
template <class mutex>
class transactional_lock_guard
{
mutex &m;
public :
TRANSACTIONAL_INLINE transactional_lock_guard(mutex &m) noexcept : m(m)
{
#ifndef NO_ELISION
if (xbegin())
{
if (was_elided())
return ;
xabort();
}
#endif
m.lock();
}
transactional_lock_guard(const transactional_lock_guard &) noexcept= delete ;
TRANSACTIONAL_INLINE ~transactional_lock_guard() noexcept
{
#ifndef NO_ELISION
if (was_elided()) xend(); else
#endif
m.unlock();
}
#ifndef NO_ELISION
bool was_elided() const noexcept { return !m.is_locked_or_waiting(); }
#else
bool was_elided() const noexcept { return false ; }
#endif
};
template <class mutex>
class transactional_shared_lock_guard
{
mutex &m;
#ifndef NO_ELISION
bool elided;
#else
static constexpr bool elided= false ;
#endif
public :
TRANSACTIONAL_INLINE transactional_shared_lock_guard(mutex &m) noexcept : m(m)
{
#ifndef NO_ELISION
if (xbegin())
{
if (!m.is_write_locked())
{
elided= true ;
return ;
}
xabort();
}
elided= false ;
#endif
m.lock_shared();
}
transactional_shared_lock_guard(const transactional_shared_lock_guard &) noexcept=
delete ;
TRANSACTIONAL_INLINE ~transactional_shared_lock_guard() noexcept
{
#ifndef NO_ELISION
if (was_elided()) xend(); else
#endif
m.unlock_shared();
}
bool was_elided() const noexcept { return elided; }
};
Messung V0.5 in Prozent C=96 H=100 G=97
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-10-08)
¤
*© Formatika GbR, Deutschland