mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
Merge port of Google SMP patch to Solaris
This commit is contained in:
parent
84e311c81c
commit
7e065ee9ae
14 changed files with 78 additions and 51 deletions
|
@ -389,8 +389,8 @@ static SHOW_VAR innodb_status_variables[]= {
|
|||
(char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
|
||||
{"dblwr_writes",
|
||||
(char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
|
||||
{"have_atomic_builtins",
|
||||
(char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL},
|
||||
{"have_sync_atomic",
|
||||
(char*) &export_vars.innodb_have_sync_atomic, SHOW_BOOL},
|
||||
{"heap_enabled",
|
||||
(char*) &export_vars.innodb_heap_enabled, SHOW_BOOL},
|
||||
{"log_waits",
|
||||
|
|
|
@ -12,6 +12,10 @@ Created 9/6/1995 Heikki Tuuri
|
|||
#include "univ.i"
|
||||
#include "ut0lst.h"
|
||||
|
||||
#ifdef HAVE_SOLARIS_ATOMIC
|
||||
#include <atomic.h>
|
||||
#endif
|
||||
|
||||
#ifdef __WIN__
|
||||
|
||||
#define os_fast_mutex_t CRITICAL_SECTION
|
||||
|
@ -261,7 +265,7 @@ os_fast_mutex_free(
|
|||
/*===============*/
|
||||
os_fast_mutex_t* fast_mutex); /* in: mutex to free */
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
/**************************************************************
|
||||
Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins. */
|
||||
UNIV_INLINE
|
||||
|
@ -272,6 +276,7 @@ os_compare_and_swap(
|
|||
volatile lint* ptr, /* in: pointer to target */
|
||||
lint oldVal, /* in: value to compare to */
|
||||
lint newVal); /* in: value to swap in */
|
||||
|
||||
/**************************************************************
|
||||
Atomic increment for InnoDB. Currently requires GCC atomic builtins. */
|
||||
UNIV_INLINE
|
||||
|
@ -282,7 +287,7 @@ os_atomic_increment(
|
|||
volatile lint* ptr, /* in: pointer to target */
|
||||
lint amount); /* in: amount of increment */
|
||||
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "os0sync.ic"
|
||||
|
|
|
@ -45,9 +45,10 @@ os_fast_mutex_trylock(
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
/**************************************************************
|
||||
Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins. */
|
||||
Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins
|
||||
or Solaris atomic_* functions. */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
os_compare_and_swap(
|
||||
|
@ -57,11 +58,15 @@ os_compare_and_swap(
|
|||
lint oldVal, /* in: value to compare to */
|
||||
lint newVal) /* in: value to swap in */
|
||||
{
|
||||
if(__sync_bool_compare_and_swap(ptr, oldVal, newVal)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
#ifdef HAVE_GCC_ATOMIC_BULTINS
|
||||
return (__sync_bool_compare_and_swap(ptr, oldVal, newVal));
|
||||
#elif HAVE_SOLARIS_ATOMIC
|
||||
lint retVal = (lint)atomic_cas_ulong((volatile ulong_t *)ptr,
|
||||
oldVal, newVal);
|
||||
return (retVal == oldVal);
|
||||
#else
|
||||
#error "Need support for atomic ops"
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
|
@ -74,8 +79,13 @@ os_atomic_increment(
|
|||
volatile lint* ptr, /* in: pointer to target */
|
||||
lint amount) /* in: amount of increment */
|
||||
{
|
||||
lint newVal = __sync_add_and_fetch(ptr, amount);
|
||||
return newVal;
|
||||
#ifdef HAVE_GCC_ATOMIC_BULTINS
|
||||
return (__sync_add_and_fetch(ptr, amount));
|
||||
#elif HAVE_SOLARIS_ATOMIC
|
||||
return ((lint)atomic_add_long_nv((volatile ulong_t *)ptr, amount));
|
||||
#else
|
||||
#error "Need support for atomic ops"
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
|
|
|
@ -523,7 +523,7 @@ struct export_var_struct{
|
|||
ulint innodb_buffer_pool_read_ahead_rnd;
|
||||
ulint innodb_dblwr_pages_written;
|
||||
ulint innodb_dblwr_writes;
|
||||
ibool innodb_have_atomic_builtins;
|
||||
ibool innodb_have_sync_atomic;
|
||||
ibool innodb_heap_enabled;
|
||||
ulint innodb_log_waits;
|
||||
ulint innodb_log_write_requests;
|
||||
|
|
|
@ -460,9 +460,9 @@ struct rw_lock_struct {
|
|||
os_event_t wait_ex_event;
|
||||
/* Event for next-writer to wait on. A thread
|
||||
must decrement lock_word before waiting. */
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
mutex_t mutex; /* The mutex protecting rw_lock_struct */
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
UT_LIST_NODE_T(rw_lock_t) list;
|
||||
/* All allocated rw locks are put into a
|
||||
|
|
|
@ -103,7 +103,7 @@ rw_lock_get_reader_count(
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
UNIV_INLINE
|
||||
mutex_t*
|
||||
rw_lock_get_mutex(
|
||||
|
@ -146,7 +146,7 @@ rw_lock_lock_word_decr(
|
|||
ulint amount) /* in: amount of decrement */
|
||||
{
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
|
||||
lint local_lock_word = lock->lock_word;
|
||||
while (local_lock_word > 0) {
|
||||
|
@ -159,7 +159,7 @@ rw_lock_lock_word_decr(
|
|||
}
|
||||
return(FALSE);
|
||||
|
||||
#else /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#else /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
ibool success = FALSE;
|
||||
mutex_enter(&(lock->mutex));
|
||||
|
@ -170,7 +170,7 @@ rw_lock_lock_word_decr(
|
|||
mutex_exit(&(lock->mutex));
|
||||
return success;
|
||||
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
}
|
||||
|
||||
|
@ -186,11 +186,11 @@ rw_lock_lock_word_incr(
|
|||
ulint amount) /* in: amount of increment */
|
||||
{
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
|
||||
return(os_atomic_increment(&(lock->lock_word), amount));
|
||||
|
||||
#else /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#else /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
lint local_lock_word;
|
||||
|
||||
|
@ -203,7 +203,7 @@ rw_lock_lock_word_incr(
|
|||
|
||||
return local_lock_word;
|
||||
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
}
|
||||
|
||||
|
@ -352,7 +352,7 @@ rw_lock_x_lock_func_nowait(
|
|||
|
||||
ibool success;
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
success = os_compare_and_swap(&(lock->lock_word), X_LOCK_DECR, 0);
|
||||
#else
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ Created 9/5/1995 Heikki Tuuri
|
|||
#include "os0thread.h"
|
||||
#include "os0sync.h"
|
||||
#include "sync0arr.h"
|
||||
#include "my_atomic.h"
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
extern my_bool timed_mutexes;
|
||||
|
@ -476,7 +477,10 @@ struct mutex_struct {
|
|||
test-and-set instruction in Win32 and
|
||||
x86 32/64 with GCC 4.1.0 or later version */
|
||||
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
|
||||
#elif defined(MY_ATOMIC_NOLOCK)
|
||||
/* We have my_atomic_* routines that are
|
||||
intrinsically atomic, so no need for the
|
||||
mutex. */
|
||||
#else
|
||||
os_fast_mutex_t
|
||||
os_fast_mutex; /* In other systems we use this OS mutex
|
||||
|
|
|
@ -88,8 +88,9 @@ mutex_test_and_set(
|
|||
/* mutex_fence(); */
|
||||
|
||||
return(res);
|
||||
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
|
||||
return __sync_lock_test_and_set(&(mutex->lock_word), 1);
|
||||
#elif defined(MY_ATOMIC_NOLOCK)
|
||||
return ((byte)my_atomic_swap8(
|
||||
(int8 volatile *)&(mutex->lock_word), 1));
|
||||
#else
|
||||
ibool ret;
|
||||
|
||||
|
@ -126,11 +127,11 @@ mutex_reset_lock_word(
|
|||
__asm MOV EDX, 0
|
||||
__asm MOV ECX, lw
|
||||
__asm XCHG DL, BYTE PTR [ECX]
|
||||
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
|
||||
#elif defined(MY_ATOMIC_NOLOCK)
|
||||
/* In theory __sync_lock_release should be used to release the lock.
|
||||
Unfortunately, it does not work properly alone. The workaround is
|
||||
that more conservative __sync_lock_test_and_set is used instead. */
|
||||
__sync_lock_test_and_set(&(mutex->lock_word), 0);
|
||||
(void)my_atomic_swap8((int8 volatile *)&(mutex->lock_word), 0);
|
||||
#else
|
||||
mutex->lock_word = 0;
|
||||
|
||||
|
|
|
@ -123,6 +123,13 @@ by one. */
|
|||
/* Use malloc instead of innodb additional memory pool (great with tcmalloc) */
|
||||
#define UNIV_DISABLE_MEM_POOL
|
||||
|
||||
#if defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_SOLARIS_ATOMIC)
|
||||
/*
|
||||
* We have a full set of atomic ops available - we will use them
|
||||
*/
|
||||
#define UNIV_SYNC_ATOMIC
|
||||
#endif
|
||||
|
||||
/*
|
||||
#define UNIV_SQL_DEBUG
|
||||
#define UNIV_LOG_DEBUG
|
||||
|
|
|
@ -1900,10 +1900,10 @@ srv_export_innodb_status(void)
|
|||
export_vars.innodb_buffer_pool_pages_misc = buf_pool->max_size
|
||||
- UT_LIST_GET_LEN(buf_pool->LRU)
|
||||
- UT_LIST_GET_LEN(buf_pool->free);
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
export_vars.innodb_have_atomic_builtins = 1;
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
export_vars.innodb_have_sync_atomic = 1;
|
||||
#else
|
||||
export_vars.innodb_have_atomic_builtins = 0;
|
||||
export_vars.innodb_have_sync_atomic = 0;
|
||||
#endif
|
||||
#ifdef UNIV_DISABLE_MEM_POOL
|
||||
export_vars.innodb_heap_enabled = 0;
|
||||
|
|
|
@ -1068,9 +1068,9 @@ innobase_start_or_create_for_mysql(void)
|
|||
"InnoDB: The InnoDB memory heap has been disabled.\n");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
fprintf(stderr,
|
||||
"InnoDB: Mutex and rw_lock use GCC atomic builtins.\n");
|
||||
"InnoDB: Mutex and rw_lock use atomics.\n");
|
||||
#endif
|
||||
|
||||
/* Since InnoDB does not currently clean up all its internal data
|
||||
|
|
|
@ -834,8 +834,8 @@ sync_array_object_signalled(
|
|||
/*========================*/
|
||||
sync_array_t* arr) /* in: wait array */
|
||||
{
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
__sync_fetch_and_add(&(arr->sg_count),1);
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
(void)os_atomic_increment((volatile lint *)&(arr->sg_count), 1);
|
||||
#else
|
||||
sync_array_enter(arr);
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ rw_lock_create_func(
|
|||
/* If this is the very first time a synchronization object is
|
||||
created, then the following call initializes the sync system. */
|
||||
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
|
||||
|
||||
lock->mutex.cfile_name = cfile_name;
|
||||
|
@ -206,7 +206,7 @@ rw_lock_create_func(
|
|||
lock->mutex.mutex_type = 1;
|
||||
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
lock->lock_word = X_LOCK_DECR;
|
||||
rw_lock_set_waiters(lock, 0);
|
||||
|
@ -260,9 +260,9 @@ rw_lock_free(
|
|||
|
||||
lock->magic_n = 0;
|
||||
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
mutex_free(rw_lock_get_mutex(lock));
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
|
||||
mutex_enter(&rw_lock_list_mutex);
|
||||
os_event_free(lock->event);
|
||||
|
@ -413,13 +413,13 @@ rw_lock_x_lock_move_ownership(
|
|||
{
|
||||
ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
|
||||
|
||||
#ifdef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifdef UNIV_SYNC_ATOMIC
|
||||
os_thread_id_t local_writer_thread = lock->writer_thread;
|
||||
os_thread_id_t new_writer_thread = os_thread_get_curr_id();
|
||||
while (TRUE) {
|
||||
if ((int)local_writer_thread != -1) {
|
||||
if(os_compare_and_swap(
|
||||
&(lock->writer_thread),
|
||||
(volatile lint*)&(lock->writer_thread),
|
||||
local_writer_thread,
|
||||
new_writer_thread)) {
|
||||
break;
|
||||
|
@ -428,12 +428,12 @@ rw_lock_x_lock_move_ownership(
|
|||
local_writer_thread = lock->writer_thread;
|
||||
}
|
||||
lock->pass = 0;
|
||||
#else /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#else /* UNIV_SYNC_ATOMIC */
|
||||
mutex_enter(&(lock->mutex));
|
||||
lock->writer_thread = os_thread_get_curr_id();
|
||||
lock->pass = 0;
|
||||
mutex_exit(&(lock->mutex));
|
||||
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
|
||||
#endif /* UNIV_SYNC_ATOMIC */
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -883,7 +883,7 @@ rw_lock_list_print_info(
|
|||
|
||||
count++;
|
||||
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
mutex_enter(&(lock->mutex));
|
||||
#endif
|
||||
if (lock->lock_word != X_LOCK_DECR) {
|
||||
|
@ -902,7 +902,7 @@ rw_lock_list_print_info(
|
|||
info = UT_LIST_GET_NEXT(list, info);
|
||||
}
|
||||
}
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
mutex_exit(&(lock->mutex));
|
||||
#endif
|
||||
|
||||
|
@ -928,7 +928,7 @@ rw_lock_print(
|
|||
"RW-LATCH INFO\n"
|
||||
"RW-LATCH: %p ", (void*) lock);
|
||||
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
mutex_enter(&(lock->mutex));
|
||||
#endif
|
||||
if (lock->lock_word != X_LOCK_DECR) {
|
||||
|
@ -945,7 +945,7 @@ rw_lock_print(
|
|||
info = UT_LIST_GET_NEXT(list, info);
|
||||
}
|
||||
}
|
||||
#ifndef HAVE_GCC_ATOMIC_BUILTINS
|
||||
#ifndef UNIV_SYNC_ATOMIC
|
||||
mutex_exit(&(lock->mutex));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ mutex_create_func(
|
|||
{
|
||||
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
mutex_reset_lock_word(mutex);
|
||||
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
|
||||
#elif defined(MY_ATOMIC_NOLOCK)
|
||||
mutex_reset_lock_word(mutex);
|
||||
#else
|
||||
os_fast_mutex_init(&(mutex->os_fast_mutex));
|
||||
|
@ -331,7 +331,7 @@ mutex_free(
|
|||
os_event_free(mutex->event);
|
||||
|
||||
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
|
||||
#elif defined(MY_ATOMIC_NOLOCK)
|
||||
#else
|
||||
os_fast_mutex_free(&(mutex->os_fast_mutex));
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue