1/***************************************************************************** 2 3Copyright (c) 2013, 2021, Oracle and/or its affiliates. 4 5Portions of this file contain modifications contributed and copyrighted by 6Google, Inc. Those modifications are gratefully acknowledged and are described 7briefly in the InnoDB documentation. The contributions by Google are 8incorporated with their permission, and subject to the conditions contained in 9the file COPYING.Google. 10 11This program is free software; you can redistribute it and/or modify 12it under the terms of the GNU General Public License, version 2.0, 13as published by the Free Software Foundation. 14 15This program is also distributed with certain software (including 16but not limited to OpenSSL) that is licensed under separate terms, 17as designated in a particular file or component or in included license 18documentation. The authors of MySQL hereby grant you an additional 19permission to link the program and your derivative works with the 20separately licensed software that they have included with MySQL. 21 22This program is distributed in the hope that it will be useful, 23but WITHOUT ANY WARRANTY; without even the implied warranty of 24MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25GNU General Public License, version 2.0, for more details. 26 27You should have received a copy of the GNU General Public License along with 28this program; if not, write to the Free Software Foundation, Inc., 2951 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 30 31*****************************************************************************/ 32 33/**************************************************//** 34@file include/ut0mutex.ic 35Mutex implementation include file 36 37Created 2012/08/21 Sunny Bains 38*******************************************************/ 39 40#include "sync0arr.h" 41#include "sync0debug.h" 42 43/** 44Wait in the sync array. 45@return true if the mutex acquisition was successful. */ 46 47template <template <typename> class Policy> 48bool 49TTASEventMutex<Policy>::wait( 50 const char* filename, 51 uint32_t line, 52 uint32_t spin) 53 UNIV_NOTHROW 54{ 55 sync_cell_t* cell; 56 sync_array_t* sync_arr; 57 58 sync_arr = sync_array_get_and_reserve_cell( 59 this, 60 (m_policy.get_id() == LATCH_ID_BUF_BLOCK_MUTEX 61 || m_policy.get_id() == LATCH_ID_BUF_POOL_ZIP) 62 ? SYNC_BUF_BLOCK 63 : SYNC_MUTEX, 64 filename, line, &cell); 65 66 /* The memory order of the array reservation and 67 the change in the waiters field is important: when 68 we suspend a thread, we first reserve the cell and 69 then set waiters field to 1. When threads are released 70 in mutex_exit, the waiters field is first set to zero 71 and then the event is set to the signaled state. */ 72 73 set_waiters(); 74 75 /* Try to reserve still a few times. */ 76 77 for (uint32_t i = 0; i < spin; ++i) { 78 79 if (try_lock()) { 80 81 sync_array_free_cell(sync_arr, cell); 82 83 /* Note that in this case we leave 84 the waiters field set to 1. We cannot 85 reset it to zero, as we do not know if 86 there are other waiters. */ 87 88 return(true); 89 } 90 } 91 92 /* Now we know that there has been some thread 93 holding the mutex after the change in the wait 94 array and the waiters field was made. Now there 95 is no risk of infinite wait on the event. */ 96 97 sync_array_wait_event(sync_arr, cell); 98 99 return(false); 100} 101 102 103/** Wakeup any waiting thread(s). */ 104 105template <template <typename> class Policy> 106void 107TTASEventMutex<Policy>::signal() UNIV_NOTHROW 108{ 109 clear_waiters(); 110 111 /* The memory order of resetting the waiters field and 112 signaling the object is important. See LEMMA 1 above. */ 113 os_event_set(m_event); 114 115 sync_array_object_signalled(); 116} 117