From 73be875c8ec65744a56465bf88ad99e336dcd62a Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 17 Jun 2019 21:54:44 +0100 Subject: [PATCH] MDEV-19773 : simplify implementation of Windows rwlock No need to do dynamic loading and fallbacks anymore. We can safely assume Windows 7, and availability of all SRWLock functions. --- include/my_pthread.h | 33 ++-------- mysys/thr_rwlock.c | 139 +++++++------------------------------------ 2 files changed, 27 insertions(+), 145 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index 8650ed626c3..ff892863800 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -581,36 +581,13 @@ extern int rw_pr_destroy(rw_pr_lock_t *); /** Implementation of Windows rwlock. - We use native (slim) rwlocks on Win7 and later, and fallback to portable - implementation on earlier Windows. - - slim rwlock are also available on Vista/WS2008, but we do not use it - ("trylock" APIs are missing on Vista) + We use native (slim) rwlocks on Windows, which requires Win7 + or later. */ -typedef union +typedef struct _my_rwlock_t { - /* Native rwlock (is_srwlock == TRUE) */ - struct - { - SRWLOCK srwlock; /* native reader writer lock */ - BOOL have_exclusive_srwlock; /* used for unlock */ - }; - - /* - Portable implementation (is_srwlock == FALSE) - Fields are identical with Unix my_rw_lock_t fields. - */ - struct - { - pthread_mutex_t lock; /* lock for structure */ - pthread_cond_t readers; /* waiting readers */ - pthread_cond_t writers; /* waiting writers */ - int state; /* -1:writer,0:free,>0:readers */ - int waiters; /* number of waiting writers */ -#ifdef SAFE_MUTEX - pthread_t write_thread; -#endif - }; + SRWLOCK srwlock; /* native reader writer lock */ + BOOL have_exclusive_srwlock; /* used for unlock */ } my_rw_lock_t; diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c index ea8b73bf8f5..a8711d517f9 100644 --- a/mysys/thr_rwlock.c +++ b/mysys/thr_rwlock.c @@ -21,116 +21,66 @@ #ifdef _WIN32 -static BOOL have_srwlock= FALSE; -/* Prototypes and function pointers for windows functions */ -typedef VOID (WINAPI* srw_func) (PSRWLOCK SRWLock); -typedef BOOLEAN (WINAPI* srw_bool_func) (PSRWLOCK SRWLock); - -static srw_func my_InitializeSRWLock; -static srw_func my_AcquireSRWLockExclusive; -static srw_func my_ReleaseSRWLockExclusive; -static srw_func my_AcquireSRWLockShared; -static srw_func my_ReleaseSRWLockShared; - -static srw_bool_func my_TryAcquireSRWLockExclusive; -static srw_bool_func my_TryAcquireSRWLockShared; - -/** - Check for presence of Windows slim reader writer lock function. - Load function pointers. -*/ - -static void check_srwlock_availability(void) +int my_rw_init(my_rw_lock_t *rwp) { - HMODULE module= GetModuleHandle("kernel32"); - - my_InitializeSRWLock= (srw_func) GetProcAddress(module, - "InitializeSRWLock"); - my_AcquireSRWLockExclusive= (srw_func) GetProcAddress(module, - "AcquireSRWLockExclusive"); - my_AcquireSRWLockShared= (srw_func) GetProcAddress(module, - "AcquireSRWLockShared"); - my_ReleaseSRWLockExclusive= (srw_func) GetProcAddress(module, - "ReleaseSRWLockExclusive"); - my_ReleaseSRWLockShared= (srw_func) GetProcAddress(module, - "ReleaseSRWLockShared"); - my_TryAcquireSRWLockExclusive= (srw_bool_func) GetProcAddress(module, - "TryAcquireSRWLockExclusive"); - my_TryAcquireSRWLockShared= (srw_bool_func) GetProcAddress(module, - "TryAcquireSRWLockShared"); - - /* - We currently require TryAcquireSRWLockExclusive. This API is missing on - Vista, this means SRWLock are only used starting with Win7. - - If "trylock" usage for rwlocks is eliminated from server codebase (it is used - in a single place currently, in query cache), then SRWLock can be enabled on - Vista too. In this case condition below needs to be changed to e.g check - for my_InitializeSRWLock. - */ - - if (my_TryAcquireSRWLockExclusive) - have_srwlock= TRUE; - -} - - -static int srw_init(my_rw_lock_t *rwp) -{ - my_InitializeSRWLock(&rwp->srwlock); + InitializeSRWLock(&rwp->srwlock); rwp->have_exclusive_srwlock = FALSE; return 0; } -static int srw_rdlock(my_rw_lock_t *rwp) +int my_rw_rdlock(my_rw_lock_t *rwp) { - my_AcquireSRWLockShared(&rwp->srwlock); + AcquireSRWLockShared(&rwp->srwlock); return 0; } -static int srw_tryrdlock(my_rw_lock_t *rwp) +int my_rw_tryrdlock(my_rw_lock_t *rwp) { - - if (!my_TryAcquireSRWLockShared(&rwp->srwlock)) + if (!TryAcquireSRWLockShared(&rwp->srwlock)) return EBUSY; return 0; } -static int srw_wrlock(my_rw_lock_t *rwp) +int my_rw_wrlock(my_rw_lock_t *rwp) { - my_AcquireSRWLockExclusive(&rwp->srwlock); + AcquireSRWLockExclusive(&rwp->srwlock); rwp->have_exclusive_srwlock= TRUE; return 0; } - -static int srw_trywrlock(my_rw_lock_t *rwp) +int my_rw_trywrlock(my_rw_lock_t *rwp) { - if (!my_TryAcquireSRWLockExclusive(&rwp->srwlock)) + if (!TryAcquireSRWLockExclusive(&rwp->srwlock)) return EBUSY; rwp->have_exclusive_srwlock= TRUE; return 0; } -static int srw_unlock(my_rw_lock_t *rwp) +int my_rw_unlock(my_rw_lock_t *rwp) { if (rwp->have_exclusive_srwlock) { rwp->have_exclusive_srwlock= FALSE; - my_ReleaseSRWLockExclusive(&rwp->srwlock); + ReleaseSRWLockExclusive(&rwp->srwlock); } else { - my_ReleaseSRWLockShared(&rwp->srwlock); + ReleaseSRWLockShared(&rwp->srwlock); } return 0; } -#endif /*_WIN32 */ +int my_rw_destroy(my_rw_lock_t* rwp) +{ + DBUG_ASSERT(!rwp->have_exclusive_srwlock); + return 0; +} + +#else /* Source base from Sun Microsystems SPILT, simplified for MySQL use @@ -175,22 +125,6 @@ int my_rw_init(my_rw_lock_t *rwp) { pthread_condattr_t cond_attr; -#ifdef _WIN32 - /* - Once initialization is used here rather than in my_init(), in order to - - avoid my_init() pitfalls- (undefined order in which initialization should - run) - - be potentially useful C++ (static constructors) - - just to simplify the API. - Also, the overhead is of my_pthread_once is very small. - */ - static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT; - my_pthread_once(&once_control, check_srwlock_availability); - - if (have_srwlock) - return srw_init(rwp); -#endif - pthread_mutex_init( &rwp->lock, MY_MUTEX_INIT_FAST); pthread_condattr_init( &cond_attr ); pthread_cond_init( &rwp->readers, &cond_attr ); @@ -209,10 +143,6 @@ int my_rw_init(my_rw_lock_t *rwp) int my_rw_destroy(my_rw_lock_t *rwp) { -#ifdef _WIN32 - if (have_srwlock) - return 0; /* no destroy function */ -#endif DBUG_ASSERT(rwp->state == 0); pthread_mutex_destroy( &rwp->lock ); pthread_cond_destroy( &rwp->readers ); @@ -223,11 +153,6 @@ int my_rw_destroy(my_rw_lock_t *rwp) int my_rw_rdlock(my_rw_lock_t *rwp) { -#ifdef _WIN32 - if (have_srwlock) - return srw_rdlock(rwp); -#endif - pthread_mutex_lock(&rwp->lock); /* active or queued writers */ @@ -242,12 +167,6 @@ int my_rw_rdlock(my_rw_lock_t *rwp) int my_rw_tryrdlock(my_rw_lock_t *rwp) { int res; - -#ifdef _WIN32 - if (have_srwlock) - return srw_tryrdlock(rwp); -#endif - pthread_mutex_lock(&rwp->lock); if ((rwp->state < 0 ) || rwp->waiters) res= EBUSY; /* Can't get lock */ @@ -263,11 +182,6 @@ int my_rw_tryrdlock(my_rw_lock_t *rwp) int my_rw_wrlock(my_rw_lock_t *rwp) { -#ifdef _WIN32 - if (have_srwlock) - return srw_wrlock(rwp); -#endif - pthread_mutex_lock(&rwp->lock); rwp->waiters++; /* another writer queued */ @@ -289,11 +203,6 @@ int my_rw_trywrlock(my_rw_lock_t *rwp) { int res; -#ifdef _WIN32 - if (have_srwlock) - return srw_trywrlock(rwp); -#endif - pthread_mutex_lock(&rwp->lock); if (rwp->state) res= EBUSY; /* Can't get lock */ @@ -312,11 +221,6 @@ int my_rw_trywrlock(my_rw_lock_t *rwp) int my_rw_unlock(my_rw_lock_t *rwp) { -#ifdef _WIN32 - if (have_srwlock) - return srw_unlock(rwp); -#endif - DBUG_PRINT("rw_unlock", ("state: %d waiters: %d", rwp->state, rwp->waiters)); pthread_mutex_lock(&rwp->lock); @@ -347,7 +251,8 @@ int my_rw_unlock(my_rw_lock_t *rwp) return(0); } -#endif /* defined(NEED_MY_RW_LOCK) */ +#endif /* !defined _WIN32 */ +#endif /* NEED_MY_RW_LOCK*/ int rw_pr_init(rw_pr_lock_t *rwlock)