From: vasil.dimov Date: July 22 2010 8:17am Subject: bzr commit into mysql-next-mr-innodb branch (vasil.dimov:3241) List-Archive: http://lists.mysql.com/commits/114115 Message-Id: <20100722081803.A559F2E0AA@mail.v5d.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3708764054710606892==" --===============3708764054710606892== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///usr/local/devel/bzrroot/server/mysql-next-mr-innodb/ based on revid:vasil.dimov@stripped 3241 Vasil Dimov 2010-07-22 [merge] Merge mysql-trunk-innodb -> mysql-next-mr-innodb modified: storage/innobase/CMakeLists.txt storage/innobase/include/os0file.h storage/innobase/include/os0sync.h storage/innobase/include/os0sync.ic storage/innobase/include/srv0srv.h storage/innobase/mtr/mtr0mtr.c storage/innobase/os/os0file.c storage/innobase/os/os0sync.c storage/innobase/os/os0thread.c storage/innobase/srv/srv0srv.c storage/innobase/srv/srv0start.c storage/innobase/sync/sync0arr.c storage/innobase/sync/sync0sync.c === modified file 'storage/innobase/CMakeLists.txt' --- a/storage/innobase/CMakeLists.txt revid:vasil.dimov@stripped +++ b/storage/innobase/CMakeLists.txt revid:vasil.dimov@stripped @@ -188,11 +188,7 @@ IF(SIZEOF_PTHREAD_T) ENDIF() IF(MSVC) - # Windows atomics do not perform well. Disable Windows atomics by default. - # See bug#52102 for details. - - #ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION) - ADD_DEFINITIONS(-DHAVE_IB_PAUSE_INSTRUCTION) + ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION) ENDIF() === modified file 'storage/innobase/include/os0file.h' --- a/storage/innobase/include/os0file.h revid:vasil.dimov@stripped +++ b/storage/innobase/include/os0file.h revid:vasil.dimov@stripped @@ -177,6 +177,13 @@ log. */ #define OS_WIN95 2 /*!< Microsoft Windows 95 */ #define OS_WINNT 3 /*!< Microsoft Windows NT 3.x */ #define OS_WIN2000 4 /*!< Microsoft Windows 2000 */ +#define OS_WINXP 5 /*!< Microsoft Windows XP + or Windows Server 2003 */ +#define OS_WINVISTA 6 /*!< Microsoft Windows Vista + or Windows Server 2008 */ +#define OS_WIN7 7 /*!< Microsoft Windows 7 + or Windows Server 2008 R2 */ + extern ulint os_n_file_reads; extern ulint os_n_file_writes; @@ -368,7 +375,8 @@ typedef DIR* os_file_dir_t; /*!< directo /***********************************************************************//** Gets the operating system version. Currently works only on Windows. -@return OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */ +@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA, +OS_WIN7. */ UNIV_INTERN ulint os_get_os_version(void); === modified file 'storage/innobase/include/os0sync.h' --- a/storage/innobase/include/os0sync.h revid:vasil.dimov@stripped +++ b/storage/innobase/include/os0sync.h revid:vasil.dimov@stripped @@ -38,28 +38,18 @@ Created 9/6/1995 Heikki Tuuri #include "ut0lst.h" #ifdef __WIN__ - +/** Native event (slow)*/ +typedef HANDLE os_native_event_t; /** Native mutex */ -#define os_fast_mutex_t CRITICAL_SECTION - -/** Native event */ -typedef HANDLE os_native_event_t; - -/** Operating system event */ -typedef struct os_event_struct os_event_struct_t; -/** Operating system event handle */ -typedef os_event_struct_t* os_event_t; - -/** An asynchronous signal sent between threads */ -struct os_event_struct { - os_native_event_t handle; - /*!< Windows event */ - UT_LIST_NODE_T(os_event_struct_t) os_event_list; - /*!< list of all created events */ -}; +typedef CRITICAL_SECTION os_fast_mutex_t; +/** Native condition variable. */ +typedef CONDITION_VARIABLE os_cond_t; #else /** Native mutex */ -typedef pthread_mutex_t os_fast_mutex_t; +typedef pthread_mutex_t os_fast_mutex_t; +/** Native condition variable */ +typedef pthread_cond_t os_cond_t; +#endif /** Operating system event */ typedef struct os_event_struct os_event_struct_t; @@ -68,6 +58,10 @@ typedef os_event_struct_t* os_event_t; /** An asynchronous signal sent between threads */ struct os_event_struct { +#ifdef __WIN__ + HANDLE handle; /*!< kernel event object, slow, + used on older Windows */ +#endif os_fast_mutex_t os_mutex; /*!< this mutex protects the next fields */ ibool is_set; /*!< this is TRUE when the event is @@ -76,24 +70,17 @@ struct os_event_struct { this event */ ib_int64_t signal_count; /*!< this is incremented each time the event becomes signaled */ - pthread_cond_t cond_var; /*!< condition variable is used in + os_cond_t cond_var; /*!< condition variable is used in waiting for the event */ UT_LIST_NODE_T(os_event_struct_t) os_event_list; /*!< list of all created events */ }; -#endif /** Operating system mutex */ typedef struct os_mutex_struct os_mutex_str_t; /** Operating system mutex handle */ typedef os_mutex_str_t* os_mutex_t; -/** Denotes an infinite delay for os_event_wait_time() */ -#define OS_SYNC_INFINITE_TIME ((ulint)(-1)) - -/** Return value of os_event_wait_time() when the time is exceeded */ -#define OS_SYNC_TIME_EXCEEDED 1 - /** Mutex protecting counts and the event and OS 'slow' mutex lists */ extern os_mutex_t os_sync_mutex; @@ -187,42 +174,14 @@ os_event_wait_low( #define os_event_wait(event) os_event_wait_low(event, 0) -/**********************************************************//** -Waits for an event object until it is in the signaled state or -a timeout is exceeded. In Unix the timeout is always infinite. -@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ -UNIV_INTERN -ulint -os_event_wait_time( -/*===============*/ - os_event_t event, /*!< in: event to wait */ - ulint time); /*!< in: timeout in microseconds, or - OS_SYNC_INFINITE_TIME */ -#ifdef __WIN__ -/**********************************************************//** -Waits for any event in an OS native event array. Returns if even a single -one is signaled or becomes signaled. -@return index of the event which was signaled */ -UNIV_INTERN -ulint -os_event_wait_multiple( -/*===================*/ - ulint n, /*!< in: number of events in the - array */ - os_native_event_t* native_event_array); - /*!< in: pointer to an array of event - handles */ -#endif /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. @return the mutex handle */ UNIV_INTERN os_mutex_t -os_mutex_create( -/*============*/ - const char* name); /*!< in: the name of the mutex, if NULL - the mutex is created without a name */ +os_mutex_create(void); +/*=================*/ /**********************************************************//** Acquires ownership of a mutex semaphore. */ UNIV_INTERN === modified file 'storage/innobase/include/os0sync.ic' --- a/storage/innobase/include/os0sync.ic revid:vasil.dimov@stripped +++ b/storage/innobase/include/os0sync.ic revid:vasil.dimov@stripped @@ -28,8 +28,7 @@ Created 9/6/1995 Heikki Tuuri #endif /**********************************************************//** -Acquires ownership of a fast mutex. Currently in Windows this is the same -as os_fast_mutex_lock! +Acquires ownership of a fast mutex. @return 0 if success, != 0 if was reserved by another thread */ UNIV_INLINE ulint @@ -38,9 +37,13 @@ os_fast_mutex_trylock( os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */ { #ifdef __WIN__ - EnterCriticalSection(fast_mutex); + if (TryEnterCriticalSection(fast_mutex)) { - return(0); + return(0); + } else { + + return(1); + } #else /* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock so that it returns 0 on success. In the operating system === modified file 'storage/innobase/include/srv0srv.h' --- a/storage/innobase/include/srv0srv.h revid:vasil.dimov@stripped +++ b/storage/innobase/include/srv0srv.h revid:vasil.dimov@stripped @@ -112,6 +112,9 @@ OS (provided we compiled Innobase with i use simulated aio we build below with threads. Currently we support native aio on windows and linux */ extern my_bool srv_use_native_aio; +#ifdef __WIN__ +extern ibool srv_use_native_conditions; +#endif extern ulint srv_n_data_files; extern char** srv_data_file_names; extern ulint* srv_data_file_sizes; === modified file 'storage/innobase/mtr/mtr0mtr.c' --- a/storage/innobase/mtr/mtr0mtr.c revid:vasil.dimov@stripped +++ b/storage/innobase/mtr/mtr0mtr.c revid:vasil.dimov@stripped @@ -337,9 +337,12 @@ mtr_memo_release( slot = dyn_array_get_element(memo, offset); if (object == slot->object && type == slot->type) { - if (mtr->modifications) { - mtr_memo_slot_note_modification(mtr, slot); - } + + /* We cannot release a page that has been written + to in the middle of a mini-transaction. */ + + ut_ad(!(mtr->modifications + && slot->type == MTR_MEMO_PAGE_X_FIX)); mtr_memo_slot_release(mtr, slot); === modified file 'storage/innobase/os/os0file.c' --- a/storage/innobase/os/os0file.c revid:vasil.dimov@stripped +++ b/storage/innobase/os/os0file.c revid:vasil.dimov@stripped @@ -184,7 +184,7 @@ struct os_aio_slot_struct{ which pending aio operation was completed */ #ifdef WIN_ASYNC_IO - os_event_t event; /*!< event object we need in the + HANDLE handle; /*!< handle object we need in the OVERLAPPED struct */ OVERLAPPED control; /*!< Windows control block for the aio request */ @@ -226,7 +226,7 @@ struct os_aio_array_struct{ aio array outside the ibuf segment */ os_aio_slot_t* slots; /*!< Pointer to the slots in the array */ #ifdef __WIN__ - os_native_event_t* native_events; + HANDLE* handles; /*!< Pointer to an array of OS native event handles where we copied the handles from slots, in the same @@ -305,7 +305,8 @@ UNIV_INTERN ulint os_n_pending_reads = 0 /***********************************************************************//** Gets the operating system version. Currently works only on Windows. -@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */ +@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA, +OS_WIN7. */ UNIV_INTERN ulint os_get_os_version(void) @@ -323,10 +324,18 @@ os_get_os_version(void) } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { return(OS_WIN95); } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) { - if (os_info.dwMajorVersion <= 4) { - return(OS_WINNT); - } else { - return(OS_WIN2000); + switch (os_info.dwMajorVersion) { + case 3: + case 4: + return OS_WINNT; + case 5: + return (os_info.dwMinorVersion == 0) ? OS_WIN2000 + : OS_WINXP; + case 6: + return (os_info.dwMinorVersion == 0) ? OS_WINVISTA + : OS_WIN7; + default: + return OS_WIN7; } } else { ut_error; @@ -674,10 +683,10 @@ os_io_init_simple(void) { ulint i; - os_file_count_mutex = os_mutex_create(NULL); + os_file_count_mutex = os_mutex_create(); for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) { - os_file_seek_mutexes[i] = os_mutex_create(NULL); + os_file_seek_mutexes[i] = os_mutex_create(); } } @@ -3235,7 +3244,7 @@ os_aio_array_create( array = ut_malloc(sizeof(os_aio_array_t)); - array->mutex = os_mutex_create(NULL); + array->mutex = os_mutex_create(); array->not_full = os_event_create(NULL); array->is_empty = os_event_create(NULL); @@ -3247,7 +3256,7 @@ os_aio_array_create( array->cur_seg = 0; array->slots = ut_malloc(n * sizeof(os_aio_slot_t)); #ifdef __WIN__ - array->native_events = ut_malloc(n * sizeof(os_native_event_t)); + array->handles = ut_malloc(n * sizeof(HANDLE)); #endif #if defined(LINUX_NATIVE_AIO) @@ -3291,13 +3300,13 @@ skip_native_aio: slot->pos = i; slot->reserved = FALSE; #ifdef WIN_ASYNC_IO - slot->event = os_event_create(NULL); + slot->handle = CreateEvent(NULL,TRUE, FALSE, NULL); over = &(slot->control); - over->hEvent = slot->event->handle; + over->hEvent = slot->handle; - *((array->native_events) + i) = over->hEvent; + *((array->handles) + i) = over->hEvent; #elif defined(LINUX_NATIVE_AIO) @@ -3323,12 +3332,12 @@ os_aio_array_free( for (i = 0; i < array->n_slots; i++) { os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i); - os_event_free(slot->event); + CloseHandle(slot->handle); } #endif /* WIN_ASYNC_IO */ #ifdef __WIN__ - ut_free(array->native_events); + ut_free(array->handles); #endif /* __WIN__ */ os_mutex_free(array->mutex); os_event_free(array->not_full); @@ -3481,7 +3490,7 @@ os_aio_array_wake_win_aio_at_shutdown( for (i = 0; i < array->n_slots; i++) { - os_event_set((array->slots + i)->event); + SetEvent((array->slots + i)->handle); } } #endif @@ -3720,7 +3729,7 @@ found: control = &(slot->control); control->Offset = (DWORD)offset; control->OffsetHigh = (DWORD)offset_high; - os_event_reset(slot->event); + ResetEvent(slot->handle); #elif defined(LINUX_NATIVE_AIO) @@ -3792,7 +3801,7 @@ os_aio_array_free_slot( #ifdef WIN_ASYNC_IO - os_event_reset(slot->event); + ResetEvent(slot->handle); #elif defined(LINUX_NATIVE_AIO) @@ -4226,13 +4235,20 @@ os_aio_windows_handle( n = array->n_slots / array->n_segments; if (array == os_aio_sync_array) { - os_event_wait(os_aio_array_get_nth_slot(array, pos)->event); + WaitForSingleObject( + os_aio_array_get_nth_slot(array, pos)->handle, + INFINITE); i = pos; } else { srv_set_io_thread_op_info(orig_seg, "wait Windows aio"); - i = os_event_wait_multiple(n, - (array->native_events) - + segment * n); + i = WaitForMultipleObjects((DWORD) n, + array->handles + segment * n, + FALSE, + INFINITE); + } + + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + os_thread_exit(NULL); } os_mutex_enter(array->mutex); === modified file 'storage/innobase/os/os0sync.c' --- a/storage/innobase/os/os0sync.c revid:vasil.dimov@stripped +++ b/storage/innobase/os/os0sync.c revid:vasil.dimov@stripped @@ -35,6 +35,7 @@ Created 9/6/1995 Heikki Tuuri #include "ut0mem.h" #include "srv0start.h" +#include "srv0srv.h" /* Type definition for an operating system mutex struct */ struct os_mutex_struct{ @@ -76,6 +77,155 @@ event embedded inside a mutex, on free, 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 +} + +/*********************************************************//** +Wait on condition variable */ +UNIV_INLINE +void +os_cond_wait( +/*=========*/ + os_cond_t* cond, /*!< in: condition variable. */ + os_fast_mutex_t* mutex) /*!< in: fast 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 +} + +/*********************************************************//** +Wakes one thread waiting for condition variable */ +UNIV_INLINE +void +os_cond_signal( +/*==========*/ + os_cond_t* cond) /*!< in: condition variable. */ +{ + ut_a(cond); + +#ifdef __WIN__ + ut_a(wake_condition_variable != NULL); + wake_condition_variable(cond); +#else + ut_a(pthread_cond_signal(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 @@ -89,7 +239,10 @@ os_sync_init(void) os_sync_mutex = NULL; os_sync_mutex_inited = FALSE; - os_sync_mutex = os_mutex_create(NULL); + /* Now for Windows only */ + os_cond_module_init(); + + os_sync_mutex = os_mutex_create(); os_sync_mutex_inited = TRUE; } @@ -143,42 +296,45 @@ os_event_create( const char* name) /*!< in: the name of the event, if NULL the event is created without a name */ { + os_event_t event; + #ifdef __WIN__ - os_event_t event; + if(!srv_use_native_conditions) { - event = ut_malloc(sizeof(struct os_event_struct)); + event = ut_malloc(sizeof(struct os_event_struct)); - event->handle = CreateEvent(NULL, /* No security attributes */ - TRUE, /* Manual reset */ - FALSE, /* Initial state nonsignaled */ - (LPCTSTR) name); - if (!event->handle) { - fprintf(stderr, - "InnoDB: Could not create a Windows event semaphore;" - " Windows error %lu\n", - (ulong) GetLastError()); - } -#else /* Unix */ - os_event_t event; + event->handle = CreateEvent(NULL, + TRUE, + FALSE, + (LPCTSTR) name); + 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 - UT_NOT_USED(name); + { + UT_NOT_USED(name); - event = ut_malloc(sizeof(struct os_event_struct)); + event = ut_malloc(sizeof(struct os_event_struct)); - os_fast_mutex_init(&(event->os_mutex)); + os_fast_mutex_init(&(event->os_mutex)); - ut_a(0 == pthread_cond_init(&(event->cond_var), NULL)); + os_cond_init(&(event->cond_var)); - event->is_set = FALSE; + 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; -#endif /* __WIN__ */ + /* 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 @@ -208,10 +364,15 @@ os_event_set( /*=========*/ os_event_t event) /*!< in: event to set */ { -#ifdef __WIN__ ut_a(event); - ut_a(SetEvent(event->handle)); -#else + +#ifdef __WIN__ + if (!srv_use_native_conditions) { + ut_a(SetEvent(event->handle)); + return; + } +#endif + ut_a(event); os_fast_mutex_lock(&(event->os_mutex)); @@ -221,11 +382,10 @@ os_event_set( } else { event->is_set = TRUE; event->signal_count += 1; - ut_a(0 == pthread_cond_broadcast(&(event->cond_var))); + os_cond_broadcast(&(event->cond_var)); } os_fast_mutex_unlock(&(event->os_mutex)); -#endif } /**********************************************************//** @@ -244,12 +404,14 @@ os_event_reset( { ib_int64_t ret = 0; -#ifdef __WIN__ ut_a(event); - ut_a(ResetEvent(event->handle)); -#else - 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)); @@ -261,7 +423,6 @@ os_event_reset( ret = event->signal_count; os_fast_mutex_unlock(&(event->os_mutex)); -#endif return(ret); } @@ -274,19 +435,21 @@ os_event_free_internal( os_event_t event) /*!< in: event to free */ { #ifdef __WIN__ - ut_a(event); + if(!srv_use_native_conditions) { + ut_a(event); + ut_a(CloseHandle(event->handle)); + } else +#endif + { + ut_a(event); - ut_a(CloseHandle(event->handle)); -#else - ut_a(event); + /* This is to avoid freeing the mutex twice */ + os_fast_mutex_free(&(event->os_mutex)); - /* This is to avoid freeing the mutex twice */ - os_fast_mutex_free(&(event->os_mutex)); + os_cond_destroy(&(event->cond_var)); + } - ut_a(0 == pthread_cond_destroy(&(event->cond_var))); -#endif /* Remove from the list of events */ - UT_LIST_REMOVE(os_event_list, os_event_list, event); os_event_count--; @@ -303,18 +466,19 @@ os_event_free( os_event_t event) /*!< in: event to free */ { -#ifdef __WIN__ 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)); - ut_a(CloseHandle(event->handle)); -#else - ut_a(event); + os_cond_destroy(&(event->cond_var)); + } - os_fast_mutex_free(&(event->os_mutex)); - ut_a(0 == pthread_cond_destroy(&(event->cond_var))); -#endif /* Remove from the list of events */ - os_mutex_enter(os_sync_mutex); UT_LIST_REMOVE(os_event_list, os_event_list, event); @@ -355,23 +519,27 @@ os_event_wait_low( returned by previous call of os_event_reset(). */ { + ib_int64_t old_signal_count; + #ifdef __WIN__ - DWORD err; + if(!srv_use_native_conditions) { + DWORD err; - ut_a(event); + ut_a(event); - UT_NOT_USED(reset_sig_count); + UT_NOT_USED(reset_sig_count); - /* Specify an infinite time limit for waiting */ - err = WaitForSingleObject(event->handle, INFINITE); + /* Specify an infinite wait */ + err = WaitForSingleObject(event->handle, INFINITE); - ut_a(err == WAIT_OBJECT_0); + ut_a(err == WAIT_OBJECT_0); - if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { - os_thread_exit(NULL); + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + os_thread_exit(NULL); + } + return; } -#else - ib_int64_t old_signal_count; +#endif os_fast_mutex_lock(&(event->os_mutex)); @@ -396,123 +564,29 @@ os_event_wait_low( return; } - pthread_cond_wait(&(event->cond_var), &(event->os_mutex)); + 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 */ } -#endif } -/**********************************************************//** -Waits for an event object until it is in the signaled state or -a timeout is exceeded. In Unix the timeout is always infinite. -@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ -UNIV_INTERN -ulint -os_event_wait_time( -/*===============*/ - os_event_t event, /*!< in: event to wait */ - ulint time) /*!< in: timeout in microseconds, or - OS_SYNC_INFINITE_TIME */ -{ -#ifdef __WIN__ - DWORD err; - - ut_a(event); - - if (time != OS_SYNC_INFINITE_TIME) { - err = WaitForSingleObject(event->handle, (DWORD) time / 1000); - } else { - err = WaitForSingleObject(event->handle, INFINITE); - } - - if (err == WAIT_OBJECT_0) { - - return(0); - } else if (err == WAIT_TIMEOUT) { - - return(OS_SYNC_TIME_EXCEEDED); - } else { - ut_error; - return(1000000); /* dummy value to eliminate compiler warn. */ - } -#else - UT_NOT_USED(time); - - /* In Posix this is just an ordinary, infinite wait */ - - os_event_wait(event); - - return(0); -#endif -} - -#ifdef __WIN__ -/**********************************************************//** -Waits for any event in an OS native event array. Returns if even a single -one is signaled or becomes signaled. -@return index of the event which was signaled */ -UNIV_INTERN -ulint -os_event_wait_multiple( -/*===================*/ - ulint n, /*!< in: number of events in the - array */ - os_native_event_t* native_event_array) - /*!< in: pointer to an array of event - handles */ -{ - DWORD index; - - ut_a(native_event_array); - ut_a(n > 0); - - index = WaitForMultipleObjects((DWORD) n, native_event_array, - FALSE, /* Wait for any 1 event */ - INFINITE); /* Infinite wait time - limit */ - ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */ - ut_a(index < WAIT_OBJECT_0 + n); - - if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { - os_thread_exit(NULL); - } - - return(index - WAIT_OBJECT_0); -} -#endif - /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. @return the mutex handle */ UNIV_INTERN os_mutex_t -os_mutex_create( -/*============*/ - const char* name) /*!< in: the name of the mutex, if NULL - the mutex is created without a name */ +os_mutex_create(void) +/*=================*/ { -#ifdef __WIN__ - HANDLE mutex; - os_mutex_t mutex_str; - - mutex = CreateMutex(NULL, /* No security attributes */ - FALSE, /* Initial state: no owner */ - (LPCTSTR) name); - ut_a(mutex); -#else os_fast_mutex_t* mutex; os_mutex_t mutex_str; - UT_NOT_USED(name); - mutex = ut_malloc(sizeof(os_fast_mutex_t)); os_fast_mutex_init(mutex); -#endif mutex_str = ut_malloc(sizeof(os_mutex_str_t)); mutex_str->handle = mutex; @@ -543,25 +617,11 @@ os_mutex_enter( /*===========*/ os_mutex_t mutex) /*!< in: mutex to acquire */ { -#ifdef __WIN__ - DWORD err; - - ut_a(mutex); - - /* Specify infinite time limit for waiting */ - err = WaitForSingleObject(mutex->handle, INFINITE); - - ut_a(err == WAIT_OBJECT_0); - - (mutex->count)++; - ut_a(mutex->count == 1); -#else os_fast_mutex_lock(mutex->handle); (mutex->count)++; ut_a(mutex->count == 1); -#endif } /**********************************************************//** @@ -577,11 +637,7 @@ os_mutex_exit( ut_a(mutex->count == 1); (mutex->count)--; -#ifdef __WIN__ - ut_a(ReleaseMutex(mutex->handle)); -#else os_fast_mutex_unlock(mutex->handle); -#endif } /**********************************************************//** @@ -610,15 +666,9 @@ os_mutex_free( os_mutex_exit(os_sync_mutex); } -#ifdef __WIN__ - ut_a(CloseHandle(mutex->handle)); - - ut_free(mutex); -#else os_fast_mutex_free(mutex->handle); ut_free(mutex->handle); ut_free(mutex); -#endif } /*********************************************************//** === modified file 'storage/innobase/os/os0thread.c' --- a/storage/innobase/os/os0thread.c revid:vasil.dimov@stripped +++ b/storage/innobase/os/os0thread.c revid:vasil.dimov@stripped @@ -242,7 +242,7 @@ os_thread_yield(void) /*=================*/ { #if defined(__WIN__) - Sleep(0); + SwitchToThread(); #elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H)) sched_yield(); #elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG) === modified file 'storage/innobase/srv/srv0srv.c' --- a/storage/innobase/srv/srv0srv.c revid:vasil.dimov@stripped +++ b/storage/innobase/srv/srv0srv.c revid:vasil.dimov@stripped @@ -143,6 +143,21 @@ use simulated aio we build below with th Currently we support native aio on windows and linux */ UNIV_INTERN my_bool srv_use_native_aio = TRUE; +#ifdef __WIN__ +/* Windows native condition variables. We use runtime loading / function +pointers, because they are not available on Windows Server 2003 and +Windows XP/2000. + +We use condition for events on Windows if possible, even if os_event +resembles Windows kernel event object well API-wise. The reason is +performance, kernel objects are heavyweights and WaitForSingleObject() is a +performance killer causing calling thread to context switch. Besides, Innodb +is preallocating large number (often millions) of os_events. With kernel event +objects it takes a big chunk out of non-paged pool, which is better suited +for tasks like IO than for storing idle event objects. */ +UNIV_INTERN ibool srv_use_native_conditions = FALSE; +#endif /* __WIN__ */ + UNIV_INTERN ulint srv_n_data_files = 0; UNIV_INTERN char** srv_data_file_names = NULL; /* size in database pages */ @@ -3035,6 +3050,8 @@ srv_purge_thread( slot_no = srv_table_reserve_slot(SRV_WORKER); + slot = srv_table_get_nth_slot(slot_no); + ++srv_n_threads_active[SRV_WORKER]; mutex_exit(&kernel_mutex); @@ -3086,20 +3103,16 @@ srv_purge_thread( mutex_enter(&kernel_mutex); + ut_ad(srv_table_get_nth_slot(slot_no) == slot); + /* Decrement the active count. */ srv_suspend_thread(); - mutex_exit(&kernel_mutex); + slot->in_use = FALSE; /* Free the thread local memory. */ thr_local_free(os_thread_get_curr_id()); - mutex_enter(&kernel_mutex); - - /* Free the slot for reuse. */ - slot = srv_table_get_nth_slot(slot_no); - slot->in_use = FALSE; - mutex_exit(&kernel_mutex); #ifdef UNIV_DEBUG_THREAD_CREATION === modified file 'storage/innobase/srv/srv0start.c' --- a/storage/innobase/srv/srv0start.c revid:vasil.dimov@stripped +++ b/storage/innobase/srv/srv0start.c revid:vasil.dimov@stripped @@ -1160,9 +1160,17 @@ innobase_start_or_create_for_mysql(void) srv_use_native_aio = FALSE; break; + + case OS_WIN2000: + case OS_WINXP: + /* On 2000 and XP, async IO is available. */ + srv_use_native_aio = TRUE; + break; + default: - /* On Win 2000 and XP use async i/o */ + /* Vista and later have both async IO and condition variables */ srv_use_native_aio = TRUE; + srv_use_native_conditions = TRUE; break; } @@ -1695,20 +1703,6 @@ innobase_start_or_create_for_mysql(void) /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ - /* Create the thread which watches the timeouts for lock waits */ - os_thread_create(&srv_lock_timeout_thread, NULL, - thread_ids + 2 + SRV_MAX_N_IO_THREADS); - - /* Create the thread which warns of long semaphore waits */ - os_thread_create(&srv_error_monitor_thread, NULL, - thread_ids + 3 + SRV_MAX_N_IO_THREADS); - - /* Create the thread which prints InnoDB monitor info */ - os_thread_create(&srv_monitor_thread, NULL, - thread_ids + 4 + SRV_MAX_N_IO_THREADS); - - srv_is_being_started = FALSE; - if (trx_doublewrite == NULL) { /* Create the doublewrite buffer to a new tablespace */ @@ -1721,8 +1715,29 @@ innobase_start_or_create_for_mysql(void) We create the new segments only if it's a new database or the database was shutdown cleanly. */ + /* Note: When creating the extra rollback segments during an upgrade + we violate the latching order, even if the change buffer is empty. + We make an exception in sync0sync.c and check srv_is_being_started + for that violation. It cannot create a deadlock because we are still + running in single threaded mode essentially. Only the IO threads + should be running at this stage. */ + trx_sys_create_rsegs(TRX_SYS_N_RSEGS - 1); + /* Create the thread which watches the timeouts for lock waits */ + os_thread_create(&srv_lock_timeout_thread, NULL, + thread_ids + 2 + SRV_MAX_N_IO_THREADS); + + /* Create the thread which warns of long semaphore waits */ + os_thread_create(&srv_error_monitor_thread, NULL, + thread_ids + 3 + SRV_MAX_N_IO_THREADS); + + /* Create the thread which prints InnoDB monitor info */ + os_thread_create(&srv_monitor_thread, NULL, + thread_ids + 4 + SRV_MAX_N_IO_THREADS); + + srv_is_being_started = FALSE; + err = dict_create_or_check_foreign_constraint_tables(); if (err != DB_SUCCESS) { === modified file 'storage/innobase/sync/sync0arr.c' --- a/storage/innobase/sync/sync0arr.c revid:vasil.dimov@stripped +++ b/storage/innobase/sync/sync0arr.c revid:vasil.dimov@stripped @@ -250,7 +250,7 @@ sync_array_create( /* Then create the mutex to protect the wait array complex */ if (protection == SYNC_ARRAY_OS_MUTEX) { - arr->os_mutex = os_mutex_create(NULL); + arr->os_mutex = os_mutex_create(); } else if (protection == SYNC_ARRAY_MUTEX) { mutex_create(syn_arr_mutex_key, &arr->mutex, SYNC_NO_ORDER_CHECK); === modified file 'storage/innobase/sync/sync0sync.c' --- a/storage/innobase/sync/sync0sync.c revid:vasil.dimov@stripped +++ b/storage/innobase/sync/sync0sync.c revid:vasil.dimov@stripped @@ -40,6 +40,9 @@ Created 9/5/1995 Heikki Tuuri #include "srv0srv.h" #include "buf0types.h" #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */ +#ifdef UNIV_SYNC_DEBUG +# include "srv0start.h" /* srv_is_being_started */ +#endif /* UNIV_SYNC_DEBUG */ /* REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX @@ -1152,6 +1155,13 @@ sync_thread_add_level( case SYNC_TREE_NODE_FROM_HASH: /* Do no order checking */ break; + case SYNC_TRX_SYS_HEADER: + if (srv_is_being_started) { + /* This is violated during trx_sys_create_rsegs() + when creating additional rollback segments when + upgrading in innobase_start_or_create_for_mysql(). */ + break; + } case SYNC_MEM_POOL: case SYNC_MEM_HASH: case SYNC_RECV: @@ -1160,7 +1170,6 @@ sync_thread_add_level( case SYNC_LOG_FLUSH_ORDER: case SYNC_THR_LOCAL: case SYNC_ANY_LATCH: - case SYNC_TRX_SYS_HEADER: case SYNC_FILE_FORMAT_TAG: case SYNC_DOUBLEWRITE: case SYNC_SEARCH_SYS: @@ -1222,8 +1231,12 @@ sync_thread_add_level( ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1, TRUE)); } else { - ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP, - TRUE)); + /* This is violated during trx_sys_create_rsegs() + when creating additional rollback segments when + upgrading in innobase_start_or_create_for_mysql(). */ + ut_a(srv_is_being_started + || sync_thread_levels_g(array, SYNC_IBUF_BITMAP, + TRUE)); } break; case SYNC_FSP_PAGE: --===============3708764054710606892== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/vasil.dimov@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: vasil.dimov@stripped # target_branch: file:///usr/local/devel/bzrroot/server/mysql-next-mr-\ # innodb/ # testament_sha1: b995d293651ad93967c7789972c5bdb363b96e19 # timestamp: 2010-07-22 11:18:03 +0300 # source_branch: file:///usr/local/devel/bzrroot/server/mysql-next-mr-\ # bugfixing/ # base_revision_id: vasil.dimov@stripped\ # te8w3j88juuou2pq # # Begin bundle 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 --===============3708764054710606892==--