diff options
author | Sergei Golubchik <serg@mariadb.org> | 2016-06-21 15:27:09 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-06-21 15:27:09 +0200 |
commit | b3f4cf7c1325ff1ca771a44ae25616d80605e8e7 (patch) | |
tree | dbd559f57db7ad20f9b9ecf1b4c2e143de32c986 /storage/xtradb/include/os0sync.h | |
parent | a79d46c3a4839fa15c9f78dc2d5858ef948add18 (diff) | |
parent | b42664e85e2cd512245de4fde94237a502fdbedb (diff) | |
download | mariadb-git-b3f4cf7c1325ff1ca771a44ae25616d80605e8e7.tar.gz |
Merge branch 'merge-xtradb-5.6' into 0.0
Diffstat (limited to 'storage/xtradb/include/os0sync.h')
-rw-r--r-- | storage/xtradb/include/os0sync.h | 128 |
1 files changed, 89 insertions, 39 deletions
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index db996b096bb..9bbb0bb7b5f 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -42,7 +42,6 @@ Created 9/6/1995 Heikki Tuuri || defined _M_X64 || defined __WIN__ #define IB_STRONG_MEMORY_MODEL -#undef HAVE_IB_GCC_ATOMIC_TEST_AND_SET // Quick-and-dirty fix for bug 1519094 #endif /* __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__ */ @@ -94,16 +93,62 @@ struct os_event { #endif os_fast_mutex_t os_mutex; /*!< this mutex protects the next fields */ - ibool is_set; /*!< this is TRUE when the event is - in the signaled state, i.e., a thread - does not stop if it tries to wait for - this event */ - ib_int64_t signal_count; /*!< this is incremented each time - the event becomes signaled */ +private: + /** Masks for the event signal count and set flag in the count_and_set + field */ + enum { count_mask = 0x7fffffffffffffffULL, + set_mask = 0x8000000000000000ULL}; + + /** The MSB is set whenever when the event is in the signaled state, + i.e. a thread does not stop if it tries to wait for this event. Lower + bits are incremented each time the event becomes signaled. */ + ib_uint64_t count_and_set; +public: os_cond_t cond_var; /*!< condition variable is used in waiting for the event */ - UT_LIST_NODE_T(os_event_t) os_event_list; - /*!< list of all created events */ + + /** Initialise count_and_set field */ + void init_count_and_set(void) + { + /* We return this value in os_event_reset(), which can then be + be used to pass to the os_event_wait_low(). The value of zero + is reserved in os_event_wait_low() for the case when the + caller does not want to pass any signal_count value. To + distinguish between the two cases we initialize signal_count + to 1 here. */ + count_and_set = 1; + } + + /** Mark this event as set */ + void set(void) + { + count_and_set |= set_mask; + } + + /** Unmark this event as set */ + void reset(void) + { + count_and_set &= count_mask; + } + + /** Return true if this event is set */ + bool is_set(void) const + { + return count_and_set & set_mask; + } + + /** Bump signal count for this event */ + void inc_signal_count(void) + { + ut_ad(static_cast<ib_uint64_t>(signal_count()) < count_mask); + count_and_set++; + } + + /** Return how many times this event has been signalled */ + ib_int64_t signal_count(void) const + { + return (count_and_set & count_mask); + } }; /** Denotes an infinite delay for os_event_wait_time() */ @@ -115,8 +160,7 @@ struct os_event { /** Operating system mutex handle */ typedef struct os_mutex_t* os_ib_mutex_t; -/** Mutex protecting counts and the event and OS 'slow' mutex lists */ -extern os_ib_mutex_t os_sync_mutex; +// All the os_*_count variables are accessed atomically /** This is incremented by 1 in os_thread_create and decremented by 1 in os_thread_exit */ @@ -132,12 +176,15 @@ UNIV_INTERN void os_sync_init(void); /*==============*/ -/*********************************************************//** -Frees created events and OS 'slow' mutexes. */ + +/** Create an event semaphore, i.e., a semaphore which may just have two +states: signaled and nonsignaled. The created event is manual reset: it must be +reset explicitly by calling sync_os_reset_event. +@param[in,out] event memory block where to create the event */ UNIV_INTERN void -os_sync_free(void); -/*==============*/ +os_event_create(os_event_t event); + /*********************************************************//** Creates an event semaphore, i.e., a semaphore which may just have two states: signaled and nonsignaled. The created event is manual reset: it must be reset @@ -173,7 +220,10 @@ UNIV_INTERN void os_event_free( /*==========*/ - os_event_t event); /*!< in: event to free */ + os_event_t event, /*!< in: event to free */ + bool free_memory = true); + /*!< in: if true, deallocate the event memory + block too */ /**********************************************************//** Waits for an event object until it is in the signaled state. @@ -467,28 +517,7 @@ amount to decrement. */ # define os_atomic_decrement_uint64(ptr, amount) \ os_atomic_decrement(ptr, amount) -# if defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) - -/** Do an atomic test-and-set. -@param[in,out] ptr Memory location to set to non-zero -@return the previous value */ -inline -lock_word_t -os_atomic_test_and_set(volatile lock_word_t* ptr) -{ - return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); -} - -/** Do an atomic clear. -@param[in,out] ptr Memory location to set to zero */ -inline -void -os_atomic_clear(volatile lock_word_t* ptr) -{ - __atomic_clear(ptr, __ATOMIC_RELEASE); -} - -# elif defined(HAVE_ATOMIC_BUILTINS) +# if defined(HAVE_ATOMIC_BUILTINS) /** Do an atomic test and set. @param[in,out] ptr Memory location to set to non-zero @@ -517,6 +546,27 @@ os_atomic_clear(volatile lock_word_t* ptr) return(__sync_lock_test_and_set(ptr, 0)); } +# elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) + +/** Do an atomic test-and-set. +@param[in,out] ptr Memory location to set to non-zero +@return the previous value */ +inline +lock_word_t +os_atomic_test_and_set(volatile lock_word_t* ptr) +{ + return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); +} + +/** Do an atomic clear. +@param[in,out] ptr Memory location to set to zero */ +inline +void +os_atomic_clear(volatile lock_word_t* ptr) +{ + __atomic_clear(ptr, __ATOMIC_RELEASE); +} + # else # error "Unsupported platform" |