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();
 | |
| }
 |