106 lines
3.6 KiB
Plaintext
106 lines
3.6 KiB
Plaintext
/*****************************************************************************
|
|
|
|
Copyright (c) 2013, 2018, Oracle and/or its affiliates. All Rights Reserved.
|
|
|
|
Portions of this file contain modifications contributed and copyrighted by
|
|
Google, Inc. Those modifications are gratefully acknowledged and are described
|
|
briefly in the InnoDB documentation. The contributions by Google are
|
|
incorporated with their permission, and subject to the conditions contained in
|
|
the file COPYING.Google.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License, version 2.0, as published by the
|
|
Free Software Foundation.
|
|
|
|
This program is also distributed with certain software (including but not
|
|
limited to OpenSSL) that is licensed under separate terms, as designated in a
|
|
particular file or component or in included license documentation. The authors
|
|
of MySQL hereby grant you an additional permission to link the program and
|
|
your derivative works with the separately licensed software that they have
|
|
included with MySQL.
|
|
|
|
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, version 2.0,
|
|
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-1301 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/** @file include/ut0mutex.ic
|
|
Mutex implementation include file
|
|
|
|
Created 2012/08/21 Sunny Bains
|
|
*******************************************************/
|
|
|
|
#include "sync0arr.h"
|
|
#include "sync0debug.h"
|
|
|
|
/**
|
|
Wait in the sync array.
|
|
@return true if the mutex acquisition was successful. */
|
|
|
|
template <template <typename> class Policy>
|
|
bool TTASEventMutex<Policy>::wait(const char *filename, uint32_t line,
|
|
uint32_t spin) UNIV_NOTHROW {
|
|
sync_cell_t *cell;
|
|
sync_array_t *sync_arr;
|
|
|
|
sync_arr = sync_array_get_and_reserve_cell(
|
|
this,
|
|
(m_policy.get_id() == LATCH_ID_BUF_BLOCK_MUTEX ||
|
|
m_policy.get_id() == LATCH_ID_BUF_POOL_ZIP)
|
|
? SYNC_BUF_BLOCK
|
|
: SYNC_MUTEX,
|
|
filename, line, &cell);
|
|
|
|
/* The memory order of the array reservation and
|
|
the change in the waiters field is important: when
|
|
we suspend a thread, we first reserve the cell and
|
|
then set waiters field to 1. When threads are released
|
|
in mutex_exit, the waiters field is first set to zero
|
|
and then the event is set to the signaled state. */
|
|
|
|
set_waiters();
|
|
|
|
/* Try to reserve still a few times. */
|
|
|
|
for (uint32_t i = 0; i < spin; ++i) {
|
|
if (try_lock()) {
|
|
sync_array_free_cell(sync_arr, cell);
|
|
|
|
/* Note that in this case we leave
|
|
the waiters field set to 1. We cannot
|
|
reset it to zero, as we do not know if
|
|
there are other waiters. */
|
|
|
|
return (true);
|
|
}
|
|
}
|
|
|
|
/* Now we know that there has been some thread
|
|
holding the mutex after the change in the wait
|
|
array and the waiters field was made. Now there
|
|
is no risk of infinite wait on the event. */
|
|
|
|
sync_array_wait_event(sync_arr, cell);
|
|
|
|
return (false);
|
|
}
|
|
|
|
/** Wakeup any waiting thread(s). */
|
|
|
|
template <template <typename> class Policy>
|
|
void TTASEventMutex<Policy>::signal() UNIV_NOTHROW {
|
|
clear_waiters();
|
|
|
|
/* The memory order of resetting the waiters field and
|
|
signaling the object is important. See LEMMA 1 above. */
|
|
os_event_set(m_event);
|
|
|
|
sync_array_object_signalled();
|
|
}
|