summaryrefslogtreecommitdiff
path: root/storage/innobase/os/os0sync.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/os/os0sync.cc')
-rw-r--r--storage/innobase/os/os0sync.cc935
1 files changed, 0 insertions, 935 deletions
diff --git a/storage/innobase/os/os0sync.cc b/storage/innobase/os/os0sync.cc
deleted file mode 100644
index 03c53848832..00000000000
--- a/storage/innobase/os/os0sync.cc
+++ /dev/null
@@ -1,935 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-
-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 Street, Suite 500, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file os/os0sync.cc
-The interface to the operating system
-synchronization primitives.
-
-Created 9/6/1995 Heikki Tuuri
-*******************************************************/
-
-#include "os0sync.h"
-#ifdef UNIV_NONINL
-#include "os0sync.ic"
-#endif
-
-#ifdef __WIN__
-#include <windows.h>
-#endif
-
-#include "ut0mem.h"
-#include "srv0start.h"
-#include "srv0srv.h"
-
-/* Type definition for an operating system mutex struct */
-struct os_mutex_t{
- os_event_t event; /*!< Used by sync0arr.cc for queing threads */
- void* handle; /*!< OS handle to mutex */
- ulint count; /*!< we use this counter to check
- that the same thread does not
- recursively lock the mutex: we
- do not assume that the OS mutex
- supports recursive locking, though
- NT seems to do that */
- UT_LIST_NODE_T(os_mutex_t) os_mutex_list;
- /* list of all 'slow' OS mutexes created */
-};
-
-/** Mutex protecting counts and the lists of OS mutexes and events */
-UNIV_INTERN os_ib_mutex_t os_sync_mutex;
-/** TRUE if os_sync_mutex has been initialized */
-static ibool os_sync_mutex_inited = FALSE;
-/** TRUE when os_sync_free() is being executed */
-static ibool os_sync_free_called = FALSE;
-
-/** This is incremented by 1 in os_thread_create and decremented by 1 in
-os_thread_exit */
-UNIV_INTERN ulint os_thread_count = 0;
-
-/** The list of all events created */
-static UT_LIST_BASE_NODE_T(os_event) os_event_list;
-
-/** The list of all OS 'slow' mutexes */
-static UT_LIST_BASE_NODE_T(os_mutex_t) os_mutex_list;
-
-UNIV_INTERN ulint os_event_count = 0;
-UNIV_INTERN ulint os_mutex_count = 0;
-UNIV_INTERN ulint os_fast_mutex_count = 0;
-
-/* The number of microsecnds in a second. */
-static const ulint MICROSECS_IN_A_SECOND = 1000000;
-
-#ifdef UNIV_PFS_MUTEX
-UNIV_INTERN mysql_pfs_key_t event_os_mutex_key;
-UNIV_INTERN mysql_pfs_key_t os_mutex_key;
-#endif
-
-/* Because a mutex is embedded inside an event and there is an
-event embedded inside a mutex, on free, this generates a recursive call.
-This version of the free event function doesn't acquire the global lock */
-static void os_event_free_internal(os_event_t event);
-
-/* On Windows (Vista and later), load function pointers for condition
-variable handling. Those functions are not available in prior versions,
-so we have to use them via runtime loading, as long as we support XP. */
-static void os_cond_module_init(void);
-
-#ifdef __WIN__
-/* Prototypes and function pointers for condition variable functions */
-typedef VOID (WINAPI* InitializeConditionVariableProc)
- (PCONDITION_VARIABLE ConditionVariable);
-static InitializeConditionVariableProc initialize_condition_variable;
-
-typedef BOOL (WINAPI* SleepConditionVariableCSProc)
- (PCONDITION_VARIABLE ConditionVariable,
- PCRITICAL_SECTION CriticalSection,
- DWORD dwMilliseconds);
-static SleepConditionVariableCSProc sleep_condition_variable;
-
-typedef VOID (WINAPI* WakeAllConditionVariableProc)
- (PCONDITION_VARIABLE ConditionVariable);
-static WakeAllConditionVariableProc wake_all_condition_variable;
-
-typedef VOID (WINAPI* WakeConditionVariableProc)
- (PCONDITION_VARIABLE ConditionVariable);
-static WakeConditionVariableProc wake_condition_variable;
-#endif
-
-/*********************************************************//**
-Initialitze condition variable */
-UNIV_INLINE
-void
-os_cond_init(
-/*=========*/
- os_cond_t* cond) /*!< in: condition variable. */
-{
- ut_a(cond);
-
-#ifdef __WIN__
- ut_a(initialize_condition_variable != NULL);
- initialize_condition_variable(cond);
-#else
- ut_a(pthread_cond_init(cond, NULL) == 0);
-#endif
-}
-
-/*********************************************************//**
-Do a timed wait on condition variable.
-@return TRUE if timed out, FALSE otherwise */
-UNIV_INLINE
-ibool
-os_cond_wait_timed(
-/*===============*/
- os_cond_t* cond, /*!< in: condition variable. */
- os_fast_mutex_t* fast_mutex, /*!< in: fast mutex */
-#ifndef __WIN__
- const struct timespec* abstime /*!< in: timeout */
-#else
- DWORD time_in_ms /*!< in: timeout in
- milliseconds*/
-#endif /* !__WIN__ */
-)
-{
- fast_mutex_t* mutex = &fast_mutex->mutex;
-#ifdef __WIN__
- BOOL ret;
- DWORD err;
-
- ut_a(sleep_condition_variable != NULL);
-
- ret = sleep_condition_variable(cond, mutex, time_in_ms);
-
- if (!ret) {
- err = GetLastError();
- /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx,
- "Condition variables are subject to spurious wakeups
- (those not associated with an explicit wake) and stolen wakeups
- (another thread manages to run before the woken thread)."
- Check for both types of timeouts.
- Conditions are checked by the caller.*/
- if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
- return(TRUE);
- }
- }
-
- ut_a(ret);
-
- return(FALSE);
-#else
- int ret;
-
- ret = pthread_cond_timedwait(cond, mutex, abstime);
-
- switch (ret) {
- case 0:
- case ETIMEDOUT:
- /* We play it safe by checking for EINTR even though
- according to the POSIX documentation it can't return EINTR. */
- case EINTR:
- break;
-
- default:
- fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: "
- "%d: abstime={%lu,%lu}\n",
- ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec);
- ut_error;
- }
-
- return(ret == ETIMEDOUT);
-#endif
-}
-/*********************************************************//**
-Wait on condition variable */
-UNIV_INLINE
-void
-os_cond_wait(
-/*=========*/
- os_cond_t* cond, /*!< in: condition variable. */
- os_fast_mutex_t* fast_mutex)/*!< in: fast mutex */
-{
- fast_mutex_t* mutex = &fast_mutex->mutex;
- ut_a(cond);
- ut_a(mutex);
-
-#ifdef __WIN__
- ut_a(sleep_condition_variable != NULL);
- ut_a(sleep_condition_variable(cond, mutex, INFINITE));
-#else
- ut_a(pthread_cond_wait(cond, mutex) == 0);
-#endif
-}
-
-/*********************************************************//**
-Wakes all threads waiting for condition variable */
-UNIV_INLINE
-void
-os_cond_broadcast(
-/*==============*/
- os_cond_t* cond) /*!< in: condition variable. */
-{
- ut_a(cond);
-
-#ifdef __WIN__
- ut_a(wake_all_condition_variable != NULL);
- wake_all_condition_variable(cond);
-#else
- ut_a(pthread_cond_broadcast(cond) == 0);
-#endif
-}
-
-/*********************************************************//**
-Destroys condition variable */
-UNIV_INLINE
-void
-os_cond_destroy(
-/*============*/
- os_cond_t* cond) /*!< in: condition variable. */
-{
-#ifdef __WIN__
- /* Do nothing */
-#else
- ut_a(pthread_cond_destroy(cond) == 0);
-#endif
-}
-
-/*********************************************************//**
-On Windows (Vista and later), load function pointers for condition variable
-handling. Those functions are not available in prior versions, so we have to
-use them via runtime loading, as long as we support XP. */
-static
-void
-os_cond_module_init(void)
-/*=====================*/
-{
-#ifdef __WIN__
- HMODULE h_dll;
-
- if (!srv_use_native_conditions)
- return;
-
- h_dll = GetModuleHandle("kernel32");
-
- initialize_condition_variable = (InitializeConditionVariableProc)
- GetProcAddress(h_dll, "InitializeConditionVariable");
- sleep_condition_variable = (SleepConditionVariableCSProc)
- GetProcAddress(h_dll, "SleepConditionVariableCS");
- wake_all_condition_variable = (WakeAllConditionVariableProc)
- GetProcAddress(h_dll, "WakeAllConditionVariable");
- wake_condition_variable = (WakeConditionVariableProc)
- GetProcAddress(h_dll, "WakeConditionVariable");
-
- /* When using native condition variables, check function pointers */
- ut_a(initialize_condition_variable);
- ut_a(sleep_condition_variable);
- ut_a(wake_all_condition_variable);
- ut_a(wake_condition_variable);
-#endif
-}
-
-/*********************************************************//**
-Initializes global event and OS 'slow' mutex lists. */
-UNIV_INTERN
-void
-os_sync_init(void)
-/*==============*/
-{
- UT_LIST_INIT(os_event_list);
- UT_LIST_INIT(os_mutex_list);
-
- os_sync_mutex = NULL;
- os_sync_mutex_inited = FALSE;
-
- /* Now for Windows only */
- os_cond_module_init();
-
- os_sync_mutex = os_mutex_create();
-
- os_sync_mutex_inited = TRUE;
-}
-
-/*********************************************************//**
-Frees created events and OS 'slow' mutexes. */
-UNIV_INTERN
-void
-os_sync_free(void)
-/*==============*/
-{
- os_event_t event;
- os_ib_mutex_t mutex;
-
- os_sync_free_called = TRUE;
- event = UT_LIST_GET_FIRST(os_event_list);
-
- while (event) {
-
- os_event_free(event);
-
- event = UT_LIST_GET_FIRST(os_event_list);
- }
-
- mutex = UT_LIST_GET_FIRST(os_mutex_list);
-
- while (mutex) {
- if (mutex == os_sync_mutex) {
- /* Set the flag to FALSE so that we do not try to
- reserve os_sync_mutex any more in remaining freeing
- operations in shutdown */
- os_sync_mutex_inited = FALSE;
- }
-
- os_mutex_free(mutex);
-
- mutex = UT_LIST_GET_FIRST(os_mutex_list);
- }
- os_sync_free_called = FALSE;
-}
-
-/*********************************************************//**
-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 explicitly by calling sync_os_reset_event.
-@return the event handle */
-UNIV_INTERN
-os_event_t
-os_event_create(void)
-/*==================*/
-{
- os_event_t event;
-
-#ifdef __WIN__
- if(!srv_use_native_conditions) {
-
- event = static_cast<os_event_t>(ut_malloc(sizeof(*event)));
-
- event->handle = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!event->handle) {
- fprintf(stderr,
- "InnoDB: Could not create a Windows event"
- " semaphore; Windows error %lu\n",
- (ulong) GetLastError());
- }
- } else /* Windows with condition variables */
-#endif
- {
- event = static_cast<os_event_t>(ut_malloc(sizeof *event));
-
-#ifndef PFS_SKIP_EVENT_MUTEX
- os_fast_mutex_init(event_os_mutex_key, &event->os_mutex);
-#else
- os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &event->os_mutex);
-#endif
-
- os_cond_init(&(event->cond_var));
-
- event->is_set = FALSE;
-
- /* 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. */
- event->signal_count = 1;
- }
-
- /* The os_sync_mutex can be NULL because during startup an event
- can be created [ because it's embedded in the mutex/rwlock ] before
- this module has been initialized */
- if (os_sync_mutex != NULL) {
- os_mutex_enter(os_sync_mutex);
- }
-
- /* Put to the list of events */
- UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
-
- os_event_count++;
-
- if (os_sync_mutex != NULL) {
- os_mutex_exit(os_sync_mutex);
- }
-
- return(event);
-}
-
-/**********************************************************//**
-Sets an event semaphore to the signaled state: lets waiting threads
-proceed. */
-UNIV_INTERN
-void
-os_event_set(
-/*=========*/
- os_event_t event) /*!< in: event to set */
-{
- ut_a(event);
-
-#ifdef __WIN__
- if (!srv_use_native_conditions) {
- ut_a(SetEvent(event->handle));
- return;
- }
-#endif
-
- os_fast_mutex_lock(&(event->os_mutex));
-
- if (event->is_set) {
- /* Do nothing */
- } else {
- event->is_set = TRUE;
- event->signal_count += 1;
- os_cond_broadcast(&(event->cond_var));
- }
-
- os_fast_mutex_unlock(&(event->os_mutex));
-}
-
-/**********************************************************//**
-Resets an event semaphore to the nonsignaled state. Waiting threads will
-stop to wait for the event.
-The return value should be passed to os_even_wait_low() if it is desired
-that this thread should not wait in case of an intervening call to
-os_event_set() between this os_event_reset() and the
-os_event_wait_low() call. See comments for os_event_wait_low().
-@return current signal_count. */
-UNIV_INTERN
-ib_int64_t
-os_event_reset(
-/*===========*/
- os_event_t event) /*!< in: event to reset */
-{
- ib_int64_t ret = 0;
-
- ut_a(event);
-
-#ifdef __WIN__
- if(!srv_use_native_conditions) {
- ut_a(ResetEvent(event->handle));
- return(0);
- }
-#endif
-
- os_fast_mutex_lock(&(event->os_mutex));
-
- if (!event->is_set) {
- /* Do nothing */
- } else {
- event->is_set = FALSE;
- }
- ret = event->signal_count;
-
- os_fast_mutex_unlock(&(event->os_mutex));
- return(ret);
-}
-
-/**********************************************************//**
-Frees an event object, without acquiring the global lock. */
-static
-void
-os_event_free_internal(
-/*===================*/
- os_event_t event) /*!< in: event to free */
-{
-#ifdef __WIN__
- if(!srv_use_native_conditions) {
- ut_a(event);
- ut_a(CloseHandle(event->handle));
- } else
-#endif
- {
- ut_a(event);
-
- /* This is to avoid freeing the mutex twice */
- os_fast_mutex_free(&(event->os_mutex));
-
- os_cond_destroy(&(event->cond_var));
- }
-
- /* Remove from the list of events */
- UT_LIST_REMOVE(os_event_list, os_event_list, event);
-
- os_event_count--;
-
- ut_free(event);
-}
-
-/**********************************************************//**
-Frees an event object. */
-UNIV_INTERN
-void
-os_event_free(
-/*==========*/
- os_event_t event) /*!< in: event to free */
-
-{
- ut_a(event);
-#ifdef __WIN__
- if(!srv_use_native_conditions){
- ut_a(CloseHandle(event->handle));
- } else /*Windows with condition variables */
-#endif
- {
- os_fast_mutex_free(&(event->os_mutex));
-
- os_cond_destroy(&(event->cond_var));
- }
-
- /* Remove from the list of events */
- os_mutex_enter(os_sync_mutex);
-
- UT_LIST_REMOVE(os_event_list, os_event_list, event);
-
- os_event_count--;
-
- os_mutex_exit(os_sync_mutex);
-
- ut_free(event);
-}
-
-/**********************************************************//**
-Waits for an event object until it is in the signaled state.
-
-Typically, if the event has been signalled after the os_event_reset()
-we'll return immediately because event->is_set == TRUE.
-There are, however, situations (e.g.: sync_array code) where we may
-lose this information. For example:
-
-thread A calls os_event_reset()
-thread B calls os_event_set() [event->is_set == TRUE]
-thread C calls os_event_reset() [event->is_set == FALSE]
-thread A calls os_event_wait() [infinite wait!]
-thread C calls os_event_wait() [infinite wait!]
-
-Where such a scenario is possible, to avoid infinite wait, the
-value returned by os_event_reset() should be passed in as
-reset_sig_count. */
-UNIV_INTERN
-void
-os_event_wait_low(
-/*==============*/
- os_event_t event, /*!< in: event to wait */
- ib_int64_t reset_sig_count)/*!< in: zero or the value
- returned by previous call of
- os_event_reset(). */
-{
-#ifdef __WIN__
- if(!srv_use_native_conditions) {
- DWORD err;
-
- ut_a(event);
-
- UT_NOT_USED(reset_sig_count);
-
- /* Specify an infinite wait */
- err = WaitForSingleObject(event->handle, INFINITE);
-
- ut_a(err == WAIT_OBJECT_0);
- return;
- }
-#endif
-
- os_fast_mutex_lock(&event->os_mutex);
-
- if (!reset_sig_count) {
- reset_sig_count = event->signal_count;
- }
-
- while (!event->is_set && event->signal_count == reset_sig_count) {
- os_cond_wait(&(event->cond_var), &(event->os_mutex));
-
- /* Solaris manual said that spurious wakeups may occur: we
- have to check if the event really has been signaled after
- we came here to wait */
- }
-
- os_fast_mutex_unlock(&event->os_mutex);
-}
-
-/**********************************************************//**
-Waits for an event object until it is in the signaled state or
-a timeout is exceeded.
-@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
-UNIV_INTERN
-ulint
-os_event_wait_time_low(
-/*===================*/
- os_event_t event, /*!< in: event to wait */
- ulint time_in_usec, /*!< in: timeout in
- microseconds, or
- OS_SYNC_INFINITE_TIME */
- ib_int64_t reset_sig_count) /*!< in: zero or the value
- returned by previous call of
- os_event_reset(). */
-{
- ibool timed_out = FALSE;
-
-#ifdef __WIN__
- DWORD time_in_ms;
-
- if (!srv_use_native_conditions) {
- DWORD err;
-
- ut_a(event);
-
- if (time_in_usec != OS_SYNC_INFINITE_TIME) {
- time_in_ms = static_cast<DWORD>(time_in_usec / 1000);
- err = WaitForSingleObject(event->handle, time_in_ms);
- } else {
- err = WaitForSingleObject(event->handle, INFINITE);
- }
-
- if (err == WAIT_OBJECT_0) {
- return(0);
- } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
- return(OS_SYNC_TIME_EXCEEDED);
- }
-
- ut_error;
- /* Dummy value to eliminate compiler warning. */
- return(42);
- } else {
- ut_a(sleep_condition_variable != NULL);
-
- if (time_in_usec != OS_SYNC_INFINITE_TIME) {
- time_in_ms = static_cast<DWORD>(time_in_usec / 1000);
- } else {
- time_in_ms = INFINITE;
- }
- }
-#else
- struct timespec abstime;
-
- if (time_in_usec != OS_SYNC_INFINITE_TIME) {
- struct timeval tv;
- int ret;
- ulint sec;
- ulint usec;
-
- ret = ut_usectime(&sec, &usec);
- ut_a(ret == 0);
-
- tv.tv_sec = sec;
- tv.tv_usec = usec;
-
- tv.tv_usec += time_in_usec;
-
- if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
- tv.tv_sec += tv.tv_usec / MICROSECS_IN_A_SECOND;
- tv.tv_usec %= MICROSECS_IN_A_SECOND;
- }
-
- abstime.tv_sec = tv.tv_sec;
- abstime.tv_nsec = tv.tv_usec * 1000;
- } else {
- abstime.tv_nsec = 999999999;
- abstime.tv_sec = (time_t) ULINT_MAX;
- }
-
- ut_a(abstime.tv_nsec <= 999999999);
-
-#endif /* __WIN__ */
-
- os_fast_mutex_lock(&event->os_mutex);
-
- if (!reset_sig_count) {
- reset_sig_count = event->signal_count;
- }
-
- do {
- if (event->is_set || event->signal_count != reset_sig_count) {
-
- break;
- }
-
- timed_out = os_cond_wait_timed(
- &event->cond_var, &event->os_mutex,
-#ifndef __WIN__
- &abstime
-#else
- time_in_ms
-#endif /* !__WIN__ */
- );
-
- } while (!timed_out);
-
- os_fast_mutex_unlock(&event->os_mutex);
-
- return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
-}
-
-/*********************************************************//**
-Creates an operating system mutex semaphore. Because these are slow, the
-mutex semaphore of InnoDB itself (ib_mutex_t) should be used where possible.
-@return the mutex handle */
-UNIV_INTERN
-os_ib_mutex_t
-os_mutex_create(void)
-/*=================*/
-{
- os_fast_mutex_t* mutex;
- os_ib_mutex_t mutex_str;
-
- mutex = static_cast<os_fast_mutex_t*>(
- ut_malloc(sizeof(os_fast_mutex_t)));
-
- os_fast_mutex_init(os_mutex_key, mutex);
-
- mutex_str = static_cast<os_ib_mutex_t>(ut_malloc(sizeof *mutex_str));
-
- mutex_str->handle = mutex;
- mutex_str->count = 0;
- mutex_str->event = os_event_create();
-
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- /* When creating os_sync_mutex itself we cannot reserve it */
- os_mutex_enter(os_sync_mutex);
- }
-
- UT_LIST_ADD_FIRST(os_mutex_list, os_mutex_list, mutex_str);
-
- os_mutex_count++;
-
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- os_mutex_exit(os_sync_mutex);
- }
-
- return(mutex_str);
-}
-
-/**********************************************************//**
-Acquires ownership of a mutex semaphore. */
-UNIV_INTERN
-void
-os_mutex_enter(
-/*===========*/
- os_ib_mutex_t mutex) /*!< in: mutex to acquire */
-{
- os_fast_mutex_lock(static_cast<os_fast_mutex_t*>(mutex->handle));
-
- (mutex->count)++;
-
- ut_a(mutex->count == 1);
-}
-
-/**********************************************************//**
-Releases ownership of a mutex. */
-UNIV_INTERN
-void
-os_mutex_exit(
-/*==========*/
- os_ib_mutex_t mutex) /*!< in: mutex to release */
-{
- ut_a(mutex);
-
- ut_a(mutex->count == 1);
-
- (mutex->count)--;
- os_fast_mutex_unlock(static_cast<os_fast_mutex_t*>(mutex->handle));
-}
-
-/**********************************************************//**
-Frees a mutex object. */
-UNIV_INTERN
-void
-os_mutex_free(
-/*==========*/
- os_ib_mutex_t mutex) /*!< in: mutex to free */
-{
- ut_a(mutex);
-
- if (UNIV_LIKELY(!os_sync_free_called)) {
- os_event_free_internal(mutex->event);
- }
-
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- os_mutex_enter(os_sync_mutex);
- }
-
- UT_LIST_REMOVE(os_mutex_list, os_mutex_list, mutex);
-
- os_mutex_count--;
-
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- os_mutex_exit(os_sync_mutex);
- }
-
- os_fast_mutex_free(static_cast<os_fast_mutex_t*>(mutex->handle));
- ut_free(mutex->handle);
- ut_free(mutex);
-}
-
-/*********************************************************//**
-Initializes an operating system fast mutex semaphore. */
-UNIV_INTERN
-void
-os_fast_mutex_init_func(
-/*====================*/
- fast_mutex_t* fast_mutex) /*!< in: fast mutex */
-{
-#ifdef __WIN__
- ut_a(fast_mutex);
-
- InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
-#else
- ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
-#endif
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- /* When creating os_sync_mutex itself (in Unix) we cannot
- reserve it */
-
- os_mutex_enter(os_sync_mutex);
- }
-
- os_fast_mutex_count++;
-
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- os_mutex_exit(os_sync_mutex);
- }
-}
-
-/**********************************************************//**
-Acquires ownership of a fast mutex. */
-UNIV_INTERN
-void
-os_fast_mutex_lock_func(
-/*====================*/
- fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
-{
-#ifdef __WIN__
- EnterCriticalSection((LPCRITICAL_SECTION) fast_mutex);
-#else
- pthread_mutex_lock(fast_mutex);
-#endif
-}
-
-/**********************************************************//**
-Releases ownership of a fast mutex. */
-UNIV_INTERN
-void
-os_fast_mutex_unlock_func(
-/*======================*/
- fast_mutex_t* fast_mutex) /*!< in: mutex to release */
-{
-#ifdef __WIN__
- LeaveCriticalSection(fast_mutex);
-#else
- pthread_mutex_unlock(fast_mutex);
-#endif
-}
-
-/**********************************************************//**
-Releases ownership of a fast mutex. Implies a full memory barrier even on
-platforms such as PowerPC where this is not normally required. */
-UNIV_INTERN
-void
-os_fast_mutex_unlock_full_barrier(
-/*=================*/
- os_fast_mutex_t* fast_mutex) /*!< in: mutex to release */
-{
-#ifdef __WIN__
- LeaveCriticalSection(&fast_mutex->mutex);
-#else
- pthread_mutex_unlock(&fast_mutex->mutex);
-#ifdef __powerpc__
- os_mb;
-#endif
-#endif
-}
-
-/**********************************************************//**
-Frees a mutex object. */
-UNIV_INTERN
-void
-os_fast_mutex_free_func(
-/*====================*/
- fast_mutex_t* fast_mutex) /*!< in: mutex to free */
-{
-#ifdef __WIN__
- ut_a(fast_mutex);
-
- DeleteCriticalSection((LPCRITICAL_SECTION) fast_mutex);
-#else
- int ret;
-
- ret = pthread_mutex_destroy(fast_mutex);
-
- if (UNIV_UNLIKELY(ret != 0)) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: error: return value %lu when calling\n"
- "InnoDB: pthread_mutex_destroy().\n", (ulint) ret);
- fprintf(stderr,
- "InnoDB: Byte contents of the pthread mutex at %p:\n",
- (void*) fast_mutex);
- ut_print_buf(stderr, fast_mutex, sizeof(os_fast_mutex_t));
- putc('\n', stderr);
- }
-#endif
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- /* When freeing the last mutexes, we have
- already freed os_sync_mutex */
-
- os_mutex_enter(os_sync_mutex);
- }
-
- ut_ad(os_fast_mutex_count > 0);
- os_fast_mutex_count--;
-
- if (UNIV_LIKELY(os_sync_mutex_inited)) {
- os_mutex_exit(os_sync_mutex);
- }
-}