From: Vladislav Vaintroub Date: September 11 2010 8:35pm Subject: bzr commit into mysql-5.5-bugfixing branch (vvaintroub:3207) Bug#56585 List-Archive: http://lists.mysql.com/commits/118038 X-Bug: 56585 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0424287422==" --===============0424287422== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///H:/bzr-new/55bf/ based on revid:tor.didriksen@stripped 3207 Vladislav Vaintroub 2010-09-11 Bug#56585 : Slowdown on Windows in readonly benchmark. Yet another take on this problem: implement rwlock using 2 critical sections and event. This implementation is cheaper than general one on based on condition variables,because it has less overhead compared to general one. For writer-mostly scenarios, the lock is equivalent to critical section, with just Enter/LeaveCriticalSection per rwlock/rwunlock pair. For concurent reader scenarios, the overhead is the same as in general implementation (critical section enter/leave pair for both lock and unlock). plus there is extra overhead to wait or release the writer for the first entering and last existing reader). Compared to implementation on other platforms: 1) reader and writer critical sections are split (so there is less contention) 2) Less critical section lock/unlock operations for the writer. Performance-wise this lock seems to bring a lot, outperforming even native reader-writer locks, as in the table below, under column ("no fix" is 5.5, "srwlock" is native Vista RW lock, thislock is implementation in this patch) ------------------------------------------------- benchmark | no fix srwlock thislock ----------------------------------------------- simple_ranges | 14051 17996 18459 ----------------------------------------------- point_select | 20576 29120 29309 Besides,this lock implements correctly (in Dmitri's sense of it) "prefer readers", e.g writer does not enter or block newly incoming readers and waits until count of all (pending and active readers goes down to 0). Also, this lock is recursive, for both readers and writers. modified: include/my_pthread.h mysys/thr_rwlock.c === modified file 'include/my_pthread.h' --- a/include/my_pthread.h 2010-08-10 21:12:01 +0000 +++ b/include/my_pthread.h 2010-09-11 20:35:24 +0000 @@ -632,6 +632,25 @@ extern int rw_pr_init(rw_pr_lock_t *); /* Otherwise we have to use our own implementation of read/write locks. */ #define NEED_MY_RW_LOCK 1 struct st_my_rw_lock_t; + +#ifdef _WIN32 +typedef struct _win_prlock +{ + CRITICAL_SECTION reader_cs; + CRITICAL_SECTION writer_cs; + volatile LONG reader_count; /*readers (all, pending and active) */ + int writer_recursion_count; /* recursion count for writer lock */ + HANDLE allow_writer; +}rw_pr_lock_t; + +extern int rw_pr_init(rw_pr_lock_t *); +extern int rw_pr_rdlock(rw_pr_lock_t *); +extern int rw_pr_wrlock(rw_pr_lock_t *); +extern int rw_pr_tryrdlock(rw_pr_lock_t *); +extern int rw_pr_trywrlock(rw_pr_lock_t *); +extern int rw_pr_unlock(rw_pr_lock_t *); +extern int rw_pr_destroy(rw_pr_lock_t *); +#else #define rw_pr_lock_t my_rw_lock_t extern int rw_pr_init(struct st_my_rw_lock_t *); #define rw_pr_rdlock(A) my_rw_rdlock((A)) @@ -643,7 +662,7 @@ extern int rw_pr_init(struct st_my_rw_lo #define rw_pr_lock_assert_write_owner(A) my_rw_lock_assert_write_owner((A)) #define rw_pr_lock_assert_not_write_owner(A) my_rw_lock_assert_not_write_owner((A)) #endif /* defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) */ - +#endif #ifdef NEED_MY_RW_LOCK /* === modified file 'mysys/thr_rwlock.c' --- a/mysys/thr_rwlock.c 2010-08-12 13:50:23 +0000 +++ b/mysys/thr_rwlock.c 2010-09-11 20:35:24 +0000 @@ -192,12 +192,13 @@ int my_rw_unlock(my_rw_lock_t *rwp) return(0); } - +#ifndef _WIN32 int rw_pr_init(struct st_my_rw_lock_t *rwlock) { my_bool prefer_readers_attr= TRUE; return my_rw_init(rwlock, &prefer_readers_attr); } +#endif #else @@ -218,4 +219,123 @@ int rw_pr_init(rw_pr_lock_t *rwlock) } #endif /* defined(NEED_MY_RW_LOCK) */ + +#ifdef _WIN32 +int rw_pr_init(rw_pr_lock_t *rwl) +{ + InitializeCriticalSection(&rwl->reader_cs); + InitializeCriticalSection(&rwl->writer_cs); + rwl->allow_writer= CreateEvent(NULL, TRUE, TRUE, NULL); + rwl->reader_count= 0; + rwl->writer_recursion_count= 0; + if(!rwl->allow_writer) + return ENOMEM; + return 0; +} + +int rw_pr_rdlock(rw_pr_lock_t *rwl) +{ + EnterCriticalSection(&rwl->reader_cs); + rwl->reader_count++; + if (rwl->reader_count == 1) + { + /* + First reader waits for possible writer to complete + (during this time it blocks other readers that are waiting on reader_cs) + After that, it will disallows other writers until all readers finish + via ResetEvent(). + */ + EnterCriticalSection(&rwl->writer_cs); + ResetEvent(rwl->allow_writer); + LeaveCriticalSection(&rwl->writer_cs); + } + LeaveCriticalSection(&rwl->reader_cs); + return 0; +} + + +int rw_pr_wrlock(rw_pr_lock_t *rwl) +{ + EnterCriticalSection(&rwl->writer_cs); + if(rwl->reader_count > 0) + WaitForSingleObject(rwl->allow_writer, INFINITE); + rwl->writer_recursion_count++; + return 0; +} + + +int rw_pr_unlock(rw_pr_lock_t *rwl) +{ + if(rwl->writer_recursion_count > 0) + { + /* Unlock writer */ + rwl->writer_recursion_count--; + LeaveCriticalSection(&rwl->writer_cs); + } + else + { + EnterCriticalSection(&rwl->reader_cs); + rwl->reader_count--; + if(rwl->reader_count == 0) + { + /* + Last reader exits, allow writers to run + */ + SetEvent(rwl->allow_writer); + } + LeaveCriticalSection(&rwl->reader_cs); + } + return 0; +} + +int rw_pr_tryrdlock(rw_pr_lock_t *rwl) +{ + EnterCriticalSection(&rwl->reader_cs); + rwl->reader_count++; + if (rwl->reader_count == 1) + { + /* Wait for possible writer to complete, disallow other writers */ + if(TryEnterCriticalSection(&rwl->writer_cs)) + { + ResetEvent(rwl->allow_writer); + LeaveCriticalSection(&rwl->writer_cs); + } + else + { + rwl->reader_count--; + LeaveCriticalSection(&rwl->reader_cs); + return EBUSY; + } + } + LeaveCriticalSection(&rwl->reader_cs); + return 0; +} + +int rw_pr_trywrlock(rw_pr_lock_t *rwl) +{ + if(!TryEnterCriticalSection(&rwl->writer_cs)) + return EBUSY; + + if(rwl->reader_count > 0) + { + if(WaitForSingleObject(rwl->allow_writer, 0) != WAIT_OBJECT_0) + { + LeaveCriticalSection(&rwl->writer_cs); + return EBUSY; + } + } + + rwl->writer_recursion_count++; + return 0; +} + +int rw_pr_destroy(rw_pr_lock_t *rwl) +{ + DeleteCriticalSection(&rwl->reader_cs); + DeleteCriticalSection(&rwl->writer_cs); + CloseHandle(rwl->allow_writer); + return 0; +} +#endif /* _WIN32 */ + #endif /* defined(THREAD) */ --===============0424287422== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/vvaintroub@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: vvaintroub@stripped # target_branch: file:///H:/bzr-new/55bf/ # testament_sha1: 8a367c1137cf6e962adf94533d0f4146d24c98c7 # timestamp: 2010-09-11 22:35:31 +0200 # base_revision_id: tor.didriksen@stripped\ # eamj03nas42bt2e3 # # Begin bundle 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 --===============0424287422==--