Skip to content

Commit

Permalink
Merge 10.4 into 10.5
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-m committed May 19, 2020
2 parents 49b29e3 + fa03978 commit d2e96e4
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 45 deletions.
45 changes: 0 additions & 45 deletions include/my_atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,49 +169,4 @@
#define my_atomic_casptr_strong_explicit(P, E, D, S, F) \
my_atomic_casptr((P), (E), (D))
#endif

#ifdef __cplusplus
#include <atomic>
/**
A wrapper for std::atomic, defaulting to std::memory_order_relaxed.
When it comes to atomic loads or stores at std::memory_order_relaxed
on IA-32 or AMD64, this wrapper is only introducing some constraints
to the C++ compiler, to prevent some optimizations of loads or
stores.
On POWER and ARM, atomic loads and stores involve different instructions
from normal loads and stores and will thus incur some overhead.
Because atomic read-modify-write operations will always incur
overhead, we intentionally do not define
operator++(), operator--(), operator+=(), operator-=(), or similar,
to make the overhead stand out in the users of this code.
*/
template <typename Type> class Atomic_relaxed
{
std::atomic<Type> m;
public:
Atomic_relaxed(const Atomic_relaxed<Type> &rhs)
{ m.store(rhs, std::memory_order_relaxed); }
Atomic_relaxed(Type val) : m(val) {}
Atomic_relaxed() {}

operator Type() const { return m.load(std::memory_order_relaxed); }
Type operator=(const Type val)
{ m.store(val, std::memory_order_relaxed); return val; }
Type operator=(const Atomic_relaxed<Type> &rhs) { return *this= Type{rhs}; }
Type fetch_add(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.fetch_add(i, o); }
Type fetch_sub(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.fetch_sub(i, o); }
bool compare_exchange_strong(Type& i1, const Type i2,
std::memory_order o1= std::memory_order_relaxed,
std::memory_order o2= std::memory_order_relaxed)
{ return m.compare_exchange_strong(i1, i2, o1, o2); }
Type exchange(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.exchange(i, o); }
};
#endif /* __cplusplus */

#endif /* MY_ATOMIC_INCLUDED */
58 changes: 58 additions & 0 deletions include/my_atomic_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* Copyright (c) 2020, MariaDB
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 St, Fifth Floor, Boston, MA 02110-1335 USA */

#ifdef __cplusplus
#include <atomic>
/**
A wrapper for std::atomic, defaulting to std::memory_order_relaxed.
When it comes to atomic loads or stores at std::memory_order_relaxed
on IA-32 or AMD64, this wrapper is only introducing some constraints
to the C++ compiler, to prevent some optimizations of loads or
stores.
On POWER and ARM, atomic loads and stores involve different instructions
from normal loads and stores and will thus incur some overhead.
Because atomic read-modify-write operations will always incur
overhead, we intentionally do not define
operator++(), operator--(), operator+=(), operator-=(), or similar,
to make the overhead stand out in the users of this code.
*/
template <typename Type> class Atomic_relaxed
{
std::atomic<Type> m;
public:
Atomic_relaxed(const Atomic_relaxed<Type> &rhs)
{ m.store(rhs, std::memory_order_relaxed); }
Atomic_relaxed(Type val) : m(val) {}
Atomic_relaxed() {}

operator Type() const { return m.load(std::memory_order_relaxed); }
Type operator=(const Type val)
{ m.store(val, std::memory_order_relaxed); return val; }
Type operator=(const Atomic_relaxed<Type> &rhs) { return *this= Type{rhs}; }
Type fetch_add(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.fetch_add(i, o); }
Type fetch_sub(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.fetch_sub(i, o); }
bool compare_exchange_strong(Type& i1, const Type i2,
std::memory_order o1= std::memory_order_relaxed,
std::memory_order o2= std::memory_order_relaxed)
{ return m.compare_exchange_strong(i1, i2, o1, o2); }
Type exchange(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.exchange(i, o); }
};
#endif /* __cplusplus */
13 changes: 13 additions & 0 deletions mysql-test/main/table_value_constr.result
Original file line number Diff line number Diff line change
Expand Up @@ -2621,3 +2621,16 @@ EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE;
ERROR HY000: 'ignore' is not allowed in this context
EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT;
ERROR HY000: 'default' is not allowed in this context
#
# MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT))
#
VALUES (DEFAULT) UNION VALUES (DEFAULT);
ERROR HY000: 'default' is not allowed in this context
VALUES (IGNORE) UNION VALUES (IGNORE);
ERROR HY000: 'ignore' is not allowed in this context
CREATE TABLE t1 (a INT DEFAULT 10);
INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT));
ERROR HY000: 'default' is not allowed in this context
INSERT INTO t1 (VALUES (IGNORE) UNION VALUES (IGNORE));
ERROR HY000: 'ignore' is not allowed in this context
DROP TABLE t1;
16 changes: 16 additions & 0 deletions mysql-test/main/table_value_constr.test
Original file line number Diff line number Diff line change
Expand Up @@ -1353,3 +1353,19 @@ VALUES (DEFAULT);
EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE;
--error ER_NOT_ALLOWED_IN_THIS_CONTEXT
EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT;


--echo #
--echo # MDEV-22610 Crash in INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT))
--echo #

--error ER_NOT_ALLOWED_IN_THIS_CONTEXT
VALUES (DEFAULT) UNION VALUES (DEFAULT);
--error ER_NOT_ALLOWED_IN_THIS_CONTEXT
VALUES (IGNORE) UNION VALUES (IGNORE);
CREATE TABLE t1 (a INT DEFAULT 10);
--error ER_NOT_ALLOWED_IN_THIS_CONTEXT
INSERT INTO t1 (VALUES (DEFAULT) UNION VALUES (DEFAULT));
--error ER_NOT_ALLOWED_IN_THIS_CONTEXT
INSERT INTO t1 (VALUES (IGNORE) UNION VALUES (IGNORE));
DROP TABLE t1;
1 change: 1 addition & 0 deletions storage/innobase/include/srv0mon.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Created 12/15/2009 Jimmy Yang

#include <stdint.h>
#include "my_atomic.h"
#include "my_atomic_wrapper.h"

/** Possible status values for "mon_status" in "struct monitor_value" */
enum monitor_running_status {
Expand Down

0 comments on commit d2e96e4

Please sign in to comment.