Merge lp:~laurynas-biveinis/percona-server/xtradb-thread-priority-flag into lp:percona-server/5.6

Proposed by Laurynas Biveinis
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 435
Proposed branch: lp:~laurynas-biveinis/percona-server/xtradb-thread-priority-flag
Merge into: lp:percona-server/5.6
Diff against target: 4053 lines (+2141/-303)
48 files modified
Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_cleaner_basic.result (+31/-0)
Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_io_basic.result (+31/-0)
Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_master_basic.result (+31/-0)
Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_purge_basic.result (+31/-0)
Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_cleaner_basic.test (+40/-0)
Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_io_basic.test (+40/-0)
Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_master_basic.test (+40/-0)
Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_purge_basic.test (+40/-0)
Percona-Server/storage/innobase/btr/btr0sea.cc (+3/-3)
Percona-Server/storage/innobase/buf/buf0buddy.cc (+1/-1)
Percona-Server/storage/innobase/buf/buf0buf.cc (+12/-12)
Percona-Server/storage/innobase/buf/buf0flu.cc (+4/-2)
Percona-Server/storage/innobase/buf/buf0lru.cc (+6/-6)
Percona-Server/storage/innobase/buf/buf0rea.cc (+3/-3)
Percona-Server/storage/innobase/fil/fil0fil.cc (+2/-2)
Percona-Server/storage/innobase/fsp/fsp0fsp.cc (+11/-11)
Percona-Server/storage/innobase/ha/hash0hash.cc (+15/-15)
Percona-Server/storage/innobase/handler/ha_innodb.cc (+31/-0)
Percona-Server/storage/innobase/include/btr0sea.h (+1/-1)
Percona-Server/storage/innobase/include/btr0sea.ic (+1/-1)
Percona-Server/storage/innobase/include/btr0types.h (+1/-1)
Percona-Server/storage/innobase/include/buf0buf.h (+4/-4)
Percona-Server/storage/innobase/include/buf0buf.ic (+4/-4)
Percona-Server/storage/innobase/include/dict0dict.h (+2/-2)
Percona-Server/storage/innobase/include/dict0dict.ic (+1/-1)
Percona-Server/storage/innobase/include/dict0mem.h (+2/-2)
Percona-Server/storage/innobase/include/fil0fil.h (+1/-1)
Percona-Server/storage/innobase/include/ha0ha.ic (+2/-2)
Percona-Server/storage/innobase/include/hash0hash.h (+10/-9)
Percona-Server/storage/innobase/include/hash0hash.ic (+4/-4)
Percona-Server/storage/innobase/include/log0log.h (+1/-1)
Percona-Server/storage/innobase/include/mtr0mtr.h (+3/-3)
Percona-Server/storage/innobase/include/mtr0mtr.ic (+3/-3)
Percona-Server/storage/innobase/include/srv0srv.h (+12/-0)
Percona-Server/storage/innobase/include/sync0rw.h (+350/-70)
Percona-Server/storage/innobase/include/sync0rw.ic (+527/-61)
Percona-Server/storage/innobase/include/sync0sync.h (+187/-0)
Percona-Server/storage/innobase/include/sync0sync.ic (+235/-6)
Percona-Server/storage/innobase/include/sync0types.h (+13/-0)
Percona-Server/storage/innobase/include/trx0purge.h (+1/-1)
Percona-Server/storage/innobase/include/trx0trx.h (+1/-1)
Percona-Server/storage/innobase/include/univ.i (+7/-0)
Percona-Server/storage/innobase/mtr/mtr0mtr.cc (+2/-2)
Percona-Server/storage/innobase/srv/srv0srv.cc (+22/-0)
Percona-Server/storage/innobase/srv/srv0start.cc (+1/-0)
Percona-Server/storage/innobase/sync/sync0arr.cc (+92/-21)
Percona-Server/storage/innobase/sync/sync0rw.cc (+197/-41)
Percona-Server/storage/innobase/sync/sync0sync.cc (+82/-6)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/xtradb-thread-priority-flag
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+187773@code.launchpad.net

This proposal supersedes a proposal from 2013-09-20.

Description of the change

2nd MP:

Thread priority flag, priority mutex, priority free list refill, priority rw latch.

Jenkins http://jenkins.percona.com/job/percona-server-5.6-param/313/. All the yellow dots due to an unfortunate forgotten fprintf(stderr), which fails innodb-log-file-size-1. Will of course remove in the next push.

Additionally tested by making sync_arr_wake_threads_if_sema_free() a no-op, in order to catch any missed wake up events.

Thread priority flag changes from the original MP:

    - UNIV_THREAD_LOCAL defined to __thread under UNIV_LINUX instead
      of __GNUC__, and as no-op elsewhere. The original suggestion to define it as
      0 on other platforms was not used because lvalue is needed.
    - The thread-priority setting system variables are exposed only
      under UNIV_LINUX too.

1st MP:

Implement thread priority flag
(https://blueprints.launchpad.net/percona-server/+spec/xtradb-thread-priority-flag)
that would be available for InnoDB threads to check whether they
should acquire some shared resource with priority or no. The actual
uses of this flag will be in follow-up.

This flag srv_current_thread_priority is implemented through
thread-local storage. There were two other alternatives considered
for its implementation.
1. Passing the flag value from the DECLARE_THREAD functions to its use
   sites through the callstacks. But such callstacks would be very
   deep and would require patching dozens of InnoDB functions to
   include this new arg.
2. pthread_setspecific()/pthread_getspecific(). This would have the
   advantage of being slightly more portable than TLS, but it's more
   complicated to use: 1) the flag would have to be allocated in
   heap. 2) pthread_key_create() calls through pthread_once() would
   be necessary, moreover they'd have to be placed in mysys instead of
   InnoDB and any affected non-mysys-initializing threads in InnoDB
   would have to be converted to initialize mysys. 3)
   pthread_getspecific() calls would have to happen in very hot code
   paths, such as mutex locking/unlocking code.

Thus TLS appears to be the best option.

Means to change the flag value for individual InnoDB utility threads
are provided for UNIV_PERF_DEBUG or UNIV_DEBUG builds through the new
global dynamic variables innodb_priority_purge, innodb_priority_io,
innodb_priority_cleaner, innodb_priority_master. Added sys_vars tests
for them.

http://jenkins.percona.com/job/percona-server-5.6-param/281/

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote : Posted in a previous version of this proposal

Just make it Linux-specific for now, i.e. so that the system variables only appear in UNIV_LINUX builds, and srv_current_thread_priority is #define'd to 0 otherwise.

Making it truly portable is more complex than just #ifdef __GNUC__, and I will address it later.

But I also don't like reviewing this change in isolation. Please resubmit with the code that actually makes use of srv_current_thread_priority.

review: Needs Resubmitting
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal

Yes, UNIV_LINUX makes more sense than __GNUC__.

Re. isolation. The whole set of changes would be as follows, in the smallest parts:
- This MP.
- Priority mutex implementation.
- Specific buffer pool free list mutex conversion to priority.
- Non-specific mutex conversion to priority: dict_sys, LRU list, rseg, log.
- Priority rwlatch implementation.
- Non-specific rwlatch conversion to priority: fsp, page_hash, AHI, index, purge.

How this should be distributed among MPs? One big one with everything? Are separate commits OK or one big commit too?

Thanks.

Revision history for this message
Alexey Kopytov (akopytov) wrote : Posted in a previous version of this proposal

1 MP, multiple commits should be fine.

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Repushed. Removed fprintf, and fixed a typo in the last rw_lock_higher_prio_waiters_exist() call in rw_lock_s_lock_spin(), where true was incorrectly passed instead of priority_lock.

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :
Revision history for this message
Alexey Kopytov (akopytov) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_cleaner_basic.result'
--- Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_cleaner_basic.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_cleaner_basic.result 2013-09-26 14:59:13 +0000
@@ -0,0 +1,31 @@
1SET @start_value = @@GLOBAL.innodb_priority_cleaner;
2SELECT @@GLOBAL.innodb_priority_cleaner;
3@@GLOBAL.innodb_priority_cleaner
40
5SELECT @@SESSION.innodb_priority_cleaner;
6ERROR HY000: Variable 'innodb_priority_cleaner' is a GLOBAL variable
7SET GLOBAL innodb_priority_cleaner='OFF';
8SELECT @@GLOBAL.innodb_priority_cleaner;
9@@GLOBAL.innodb_priority_cleaner
100
11SET GLOBAL innodb_priority_cleaner='ON';
12SELECT @@GLOBAL.innodb_priority_cleaner;
13@@GLOBAL.innodb_priority_cleaner
141
15SET GLOBAL innodb_priority_cleaner=0;
16SELECT @@GLOBAL.innodb_priority_cleaner;
17@@GLOBAL.innodb_priority_cleaner
180
19SET GLOBAL innodb_priority_cleaner=1;
20SELECT @@GLOBAL.innodb_priority_cleaner;
21@@GLOBAL.innodb_priority_cleaner
221
23SET GLOBAL innodb_priority_cleaner=1.1;
24ERROR 42000: Incorrect argument type to variable 'innodb_priority_cleaner'
25SET GLOBAL innodb_priority_cleaner=1e1;
26ERROR 42000: Incorrect argument type to variable 'innodb_priority_cleaner'
27SET GLOBAL innodb_priority_cleaner=2;
28ERROR 42000: Variable 'innodb_priority_cleaner' can't be set to the value of '2'
29SET GLOBAL innodb_priority_cleaner='foo';
30ERROR 42000: Variable 'innodb_priority_cleaner' can't be set to the value of 'foo'
31SET GLOBAL innodb_priority_cleaner = @start_value;
032
=== added file 'Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_io_basic.result'
--- Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_io_basic.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_io_basic.result 2013-09-26 14:59:13 +0000
@@ -0,0 +1,31 @@
1SET @start_value = @@GLOBAL.innodb_priority_io;
2SELECT @@GLOBAL.innodb_priority_io;
3@@GLOBAL.innodb_priority_io
40
5SELECT @@SESSION.innodb_priority_io;
6ERROR HY000: Variable 'innodb_priority_io' is a GLOBAL variable
7SET GLOBAL innodb_priority_io='OFF';
8SELECT @@GLOBAL.innodb_priority_io;
9@@GLOBAL.innodb_priority_io
100
11SET GLOBAL innodb_priority_io='ON';
12SELECT @@GLOBAL.innodb_priority_io;
13@@GLOBAL.innodb_priority_io
141
15SET GLOBAL innodb_priority_io=0;
16SELECT @@GLOBAL.innodb_priority_io;
17@@GLOBAL.innodb_priority_io
180
19SET GLOBAL innodb_priority_io=1;
20SELECT @@GLOBAL.innodb_priority_io;
21@@GLOBAL.innodb_priority_io
221
23SET GLOBAL innodb_priority_io=1.1;
24ERROR 42000: Incorrect argument type to variable 'innodb_priority_io'
25SET GLOBAL innodb_priority_io=1e1;
26ERROR 42000: Incorrect argument type to variable 'innodb_priority_io'
27SET GLOBAL innodb_priority_io=2;
28ERROR 42000: Variable 'innodb_priority_io' can't be set to the value of '2'
29SET GLOBAL innodb_priority_io='foo';
30ERROR 42000: Variable 'innodb_priority_io' can't be set to the value of 'foo'
31SET GLOBAL innodb_priority_io = @start_value;
032
=== added file 'Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_master_basic.result'
--- Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_master_basic.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_master_basic.result 2013-09-26 14:59:13 +0000
@@ -0,0 +1,31 @@
1SET @start_value = @@GLOBAL.innodb_priority_master;
2SELECT @@GLOBAL.innodb_priority_master;
3@@GLOBAL.innodb_priority_master
40
5SELECT @@SESSION.innodb_priority_master;
6ERROR HY000: Variable 'innodb_priority_master' is a GLOBAL variable
7SET GLOBAL innodb_priority_master='OFF';
8SELECT @@GLOBAL.innodb_priority_master;
9@@GLOBAL.innodb_priority_master
100
11SET GLOBAL innodb_priority_master='ON';
12SELECT @@GLOBAL.innodb_priority_master;
13@@GLOBAL.innodb_priority_master
141
15SET GLOBAL innodb_priority_master=0;
16SELECT @@GLOBAL.innodb_priority_master;
17@@GLOBAL.innodb_priority_master
180
19SET GLOBAL innodb_priority_master=1;
20SELECT @@GLOBAL.innodb_priority_master;
21@@GLOBAL.innodb_priority_master
221
23SET GLOBAL innodb_priority_master=1.1;
24ERROR 42000: Incorrect argument type to variable 'innodb_priority_master'
25SET GLOBAL innodb_priority_master=1e1;
26ERROR 42000: Incorrect argument type to variable 'innodb_priority_master'
27SET GLOBAL innodb_priority_master=2;
28ERROR 42000: Variable 'innodb_priority_master' can't be set to the value of '2'
29SET GLOBAL innodb_priority_master='foo';
30ERROR 42000: Variable 'innodb_priority_master' can't be set to the value of 'foo'
31SET GLOBAL innodb_priority_master = @start_value;
032
=== added file 'Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_purge_basic.result'
--- Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_purge_basic.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/r/innodb_priority_purge_basic.result 2013-09-26 14:59:13 +0000
@@ -0,0 +1,31 @@
1SET @start_value = @@GLOBAL.innodb_priority_purge;
2SELECT @@GLOBAL.innodb_priority_purge;
3@@GLOBAL.innodb_priority_purge
40
5SELECT @@SESSION.innodb_priority_purge;
6ERROR HY000: Variable 'innodb_priority_purge' is a GLOBAL variable
7SET GLOBAL innodb_priority_purge='OFF';
8SELECT @@GLOBAL.innodb_priority_purge;
9@@GLOBAL.innodb_priority_purge
100
11SET GLOBAL innodb_priority_purge='ON';
12SELECT @@GLOBAL.innodb_priority_purge;
13@@GLOBAL.innodb_priority_purge
141
15SET GLOBAL innodb_priority_purge=0;
16SELECT @@GLOBAL.innodb_priority_purge;
17@@GLOBAL.innodb_priority_purge
180
19SET GLOBAL innodb_priority_purge=1;
20SELECT @@GLOBAL.innodb_priority_purge;
21@@GLOBAL.innodb_priority_purge
221
23SET GLOBAL innodb_priority_purge=1.1;
24ERROR 42000: Incorrect argument type to variable 'innodb_priority_purge'
25SET GLOBAL innodb_priority_purge=1e1;
26ERROR 42000: Incorrect argument type to variable 'innodb_priority_purge'
27SET GLOBAL innodb_priority_purge=2;
28ERROR 42000: Variable 'innodb_priority_purge' can't be set to the value of '2'
29SET GLOBAL innodb_priority_purge='foo';
30ERROR 42000: Variable 'innodb_priority_purge' can't be set to the value of 'foo'
31SET GLOBAL innodb_priority_purge = @start_value;
032
=== added file 'Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_cleaner_basic.test'
--- Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_cleaner_basic.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_cleaner_basic.test 2013-09-26 14:59:13 +0000
@@ -0,0 +1,40 @@
1--source include/have_debug.inc
2--source include/have_innodb.inc
3
4if (`SELECT @@version_compile_os LIKE "Linux" = 0`)
5{
6 skip Needs Linux;
7}
8
9# A dynamic, global variable
10
11SET @start_value = @@GLOBAL.innodb_priority_cleaner;
12
13# Default value
14SELECT @@GLOBAL.innodb_priority_cleaner;
15
16# Global only
17--error ER_INCORRECT_GLOBAL_LOCAL_VAR
18SELECT @@SESSION.innodb_priority_cleaner;
19
20# Correct values
21SET GLOBAL innodb_priority_cleaner='OFF';
22SELECT @@GLOBAL.innodb_priority_cleaner;
23SET GLOBAL innodb_priority_cleaner='ON';
24SELECT @@GLOBAL.innodb_priority_cleaner;
25SET GLOBAL innodb_priority_cleaner=0;
26SELECT @@GLOBAL.innodb_priority_cleaner;
27SET GLOBAL innodb_priority_cleaner=1;
28SELECT @@GLOBAL.innodb_priority_cleaner;
29
30# Incorrect values
31--error ER_WRONG_TYPE_FOR_VAR
32SET GLOBAL innodb_priority_cleaner=1.1;
33--error ER_WRONG_TYPE_FOR_VAR
34SET GLOBAL innodb_priority_cleaner=1e1;
35--error ER_WRONG_VALUE_FOR_VAR
36SET GLOBAL innodb_priority_cleaner=2;
37--error ER_WRONG_VALUE_FOR_VAR
38SET GLOBAL innodb_priority_cleaner='foo';
39
40SET GLOBAL innodb_priority_cleaner = @start_value;
041
=== added file 'Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_io_basic.test'
--- Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_io_basic.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_io_basic.test 2013-09-26 14:59:13 +0000
@@ -0,0 +1,40 @@
1--source include/have_debug.inc
2--source include/have_innodb.inc
3
4if (`SELECT @@version_compile_os LIKE "Linux" = 0`)
5{
6 skip Needs Linux;
7}
8
9# A dynamic, global variable
10
11SET @start_value = @@GLOBAL.innodb_priority_io;
12
13# Default value
14SELECT @@GLOBAL.innodb_priority_io;
15
16# Global only
17--error ER_INCORRECT_GLOBAL_LOCAL_VAR
18SELECT @@SESSION.innodb_priority_io;
19
20# Correct values
21SET GLOBAL innodb_priority_io='OFF';
22SELECT @@GLOBAL.innodb_priority_io;
23SET GLOBAL innodb_priority_io='ON';
24SELECT @@GLOBAL.innodb_priority_io;
25SET GLOBAL innodb_priority_io=0;
26SELECT @@GLOBAL.innodb_priority_io;
27SET GLOBAL innodb_priority_io=1;
28SELECT @@GLOBAL.innodb_priority_io;
29
30# Incorrect values
31--error ER_WRONG_TYPE_FOR_VAR
32SET GLOBAL innodb_priority_io=1.1;
33--error ER_WRONG_TYPE_FOR_VAR
34SET GLOBAL innodb_priority_io=1e1;
35--error ER_WRONG_VALUE_FOR_VAR
36SET GLOBAL innodb_priority_io=2;
37--error ER_WRONG_VALUE_FOR_VAR
38SET GLOBAL innodb_priority_io='foo';
39
40SET GLOBAL innodb_priority_io = @start_value;
041
=== added file 'Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_master_basic.test'
--- Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_master_basic.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_master_basic.test 2013-09-26 14:59:13 +0000
@@ -0,0 +1,40 @@
1--source include/have_debug.inc
2--source include/have_innodb.inc
3
4if (`SELECT @@version_compile_os LIKE "Linux" = 0`)
5{
6 skip Needs Linux;
7}
8
9# A dynamic, global variable
10
11SET @start_value = @@GLOBAL.innodb_priority_master;
12
13# Default value
14SELECT @@GLOBAL.innodb_priority_master;
15
16# Global only
17--error ER_INCORRECT_GLOBAL_LOCAL_VAR
18SELECT @@SESSION.innodb_priority_master;
19
20# Correct values
21SET GLOBAL innodb_priority_master='OFF';
22SELECT @@GLOBAL.innodb_priority_master;
23SET GLOBAL innodb_priority_master='ON';
24SELECT @@GLOBAL.innodb_priority_master;
25SET GLOBAL innodb_priority_master=0;
26SELECT @@GLOBAL.innodb_priority_master;
27SET GLOBAL innodb_priority_master=1;
28SELECT @@GLOBAL.innodb_priority_master;
29
30# Incorrect values
31--error ER_WRONG_TYPE_FOR_VAR
32SET GLOBAL innodb_priority_master=1.1;
33--error ER_WRONG_TYPE_FOR_VAR
34SET GLOBAL innodb_priority_master=1e1;
35--error ER_WRONG_VALUE_FOR_VAR
36SET GLOBAL innodb_priority_master=2;
37--error ER_WRONG_VALUE_FOR_VAR
38SET GLOBAL innodb_priority_master='foo';
39
40SET GLOBAL innodb_priority_master = @start_value;
041
=== added file 'Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_purge_basic.test'
--- Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_purge_basic.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/t/innodb_priority_purge_basic.test 2013-09-26 14:59:13 +0000
@@ -0,0 +1,40 @@
1--source include/have_debug.inc
2--source include/have_innodb.inc
3
4if (`SELECT @@version_compile_os LIKE "Linux" = 0`)
5{
6 skip Needs Linux;
7}
8
9# A dynamic, global variable
10
11SET @start_value = @@GLOBAL.innodb_priority_purge;
12
13# Default value
14SELECT @@GLOBAL.innodb_priority_purge;
15
16# Global only
17--error ER_INCORRECT_GLOBAL_LOCAL_VAR
18SELECT @@SESSION.innodb_priority_purge;
19
20# Correct values
21SET GLOBAL innodb_priority_purge='OFF';
22SELECT @@GLOBAL.innodb_priority_purge;
23SET GLOBAL innodb_priority_purge='ON';
24SELECT @@GLOBAL.innodb_priority_purge;
25SET GLOBAL innodb_priority_purge=0;
26SELECT @@GLOBAL.innodb_priority_purge;
27SET GLOBAL innodb_priority_purge=1;
28SELECT @@GLOBAL.innodb_priority_purge;
29
30# Incorrect values
31--error ER_WRONG_TYPE_FOR_VAR
32SET GLOBAL innodb_priority_purge=1.1;
33--error ER_WRONG_TYPE_FOR_VAR
34SET GLOBAL innodb_priority_purge=1e1;
35--error ER_WRONG_VALUE_FOR_VAR
36SET GLOBAL innodb_priority_purge=2;
37--error ER_WRONG_VALUE_FOR_VAR
38SET GLOBAL innodb_priority_purge='foo';
39
40SET GLOBAL innodb_priority_purge = @start_value;
041
=== modified file 'Percona-Server/storage/innobase/btr/btr0sea.cc'
--- Percona-Server/storage/innobase/btr/btr0sea.cc 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/btr/btr0sea.cc 2013-09-26 14:59:13 +0000
@@ -72,7 +72,7 @@
72being updated in-place! We can use fact (1) to perform unique searches to72being updated in-place! We can use fact (1) to perform unique searches to
73indexes. */73indexes. */
7474
75UNIV_INTERN rw_lock_t* btr_search_latch_arr;75UNIV_INTERN prio_rw_lock_t* btr_search_latch_arr;
7676
77/** padding to prevent other memory update hotspots from residing on77/** padding to prevent other memory update hotspots from residing on
78the same memory cache line */78the same memory cache line */
@@ -184,8 +184,8 @@
184 /* btr_search_index_num is constrained to machine word size for184 /* btr_search_index_num is constrained to machine word size for
185 historical reasons. This limitation can be easily removed later. */185 historical reasons. This limitation can be easily removed later. */
186186
187 btr_search_latch_arr = (rw_lock_t *)187 btr_search_latch_arr = (prio_rw_lock_t *)
188 mem_alloc(sizeof(rw_lock_t) * btr_search_index_num);188 mem_alloc(sizeof(prio_rw_lock_t) * btr_search_index_num);
189189
190 btr_search_sys = (btr_search_sys_t*)190 btr_search_sys = (btr_search_sys_t*)
191 mem_alloc(sizeof(btr_search_sys_t));191 mem_alloc(sizeof(btr_search_sys_t));
192192
=== modified file 'Percona-Server/storage/innobase/buf/buf0buddy.cc'
--- Percona-Server/storage/innobase/buf/buf0buddy.cc 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/buf/buf0buddy.cc 2013-09-26 14:59:13 +0000
@@ -548,7 +548,7 @@
548 ib_mutex_t* mutex;548 ib_mutex_t* mutex;
549 ulint space;549 ulint space;
550 ulint offset;550 ulint offset;
551 rw_lock_t* hash_lock;551 prio_rw_lock_t* hash_lock;
552552
553 ut_ad(mutex_own(&buf_pool->zip_free_mutex));553 ut_ad(mutex_own(&buf_pool->zip_free_mutex));
554 ut_ad(!mutex_own(&buf_pool->zip_mutex));554 ut_ad(!mutex_own(&buf_pool->zip_mutex));
555555
=== modified file 'Percona-Server/storage/innobase/buf/buf0buf.cc'
--- Percona-Server/storage/innobase/buf/buf0buf.cc 2013-09-25 05:20:37 +0000
+++ Percona-Server/storage/innobase/buf/buf0buf.cc 2013-09-26 14:59:13 +0000
@@ -1640,7 +1640,7 @@
1640 buf_page_t* bpage;1640 buf_page_t* bpage;
1641 ulint i;1641 ulint i;
1642 buf_pool_t* buf_pool = buf_pool_get(space, offset);1642 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1643 rw_lock_t* hash_lock;1643 prio_rw_lock_t* hash_lock;
16441644
1645 hash_lock = buf_page_hash_lock_get(buf_pool, fold);1645 hash_lock = buf_page_hash_lock_get(buf_pool, fold);
16461646
@@ -1756,7 +1756,7 @@
1756{1756{
1757#ifdef UNIV_SYNC_DEBUG1757#ifdef UNIV_SYNC_DEBUG
1758 /* We must also own the appropriate hash_bucket mutex. */1758 /* We must also own the appropriate hash_bucket mutex. */
1759 rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);1759 prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);
1760 ut_ad(rw_lock_own(hash_lock, RW_LOCK_EX));1760 ut_ad(rw_lock_own(hash_lock, RW_LOCK_EX));
1761#endif /* UNIV_SYNC_DEBUG */1761#endif /* UNIV_SYNC_DEBUG */
17621762
@@ -1782,7 +1782,7 @@
1782 buf_page_t* bpage;1782 buf_page_t* bpage;
1783 buf_pool_t* buf_pool = buf_pool_get(space, offset);1783 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1784 ulint fold = buf_page_address_fold(space, offset);1784 ulint fold = buf_page_address_fold(space, offset);
1785 rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool,1785 prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool,
1786 fold);1786 fold);
17871787
1788 rw_lock_x_lock(hash_lock);1788 rw_lock_x_lock(hash_lock);
@@ -1828,7 +1828,7 @@
1828 buf_page_t* bpage;1828 buf_page_t* bpage;
1829 buf_pool_t* buf_pool = buf_pool_get(space, offset);1829 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1830 ulint fold = buf_page_address_fold(space, offset);1830 ulint fold = buf_page_address_fold(space, offset);
1831 rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool,1831 prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool,
1832 fold);1832 fold);
18331833
1834 rw_lock_s_lock(hash_lock);1834 rw_lock_s_lock(hash_lock);
@@ -1919,7 +1919,7 @@
1919{1919{
1920 buf_page_t* bpage;1920 buf_page_t* bpage;
1921 buf_pool_t* buf_pool = buf_pool_get(space, offset);1921 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1922 rw_lock_t* hash_lock;1922 prio_rw_lock_t* hash_lock;
19231923
1924 bpage = buf_page_hash_get_s_locked(buf_pool, space, offset,1924 bpage = buf_page_hash_get_s_locked(buf_pool, space, offset,
1925 &hash_lock);1925 &hash_lock);
@@ -1953,7 +1953,7 @@
1953{1953{
1954 buf_page_t* bpage;1954 buf_page_t* bpage;
1955 buf_pool_t* buf_pool = buf_pool_get(space, offset);1955 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1956 rw_lock_t* hash_lock;1956 prio_rw_lock_t* hash_lock;
19571957
1958 bpage = buf_page_hash_get_s_locked(buf_pool, space, offset,1958 bpage = buf_page_hash_get_s_locked(buf_pool, space, offset,
1959 &hash_lock);1959 &hash_lock);
@@ -2031,7 +2031,7 @@
2031{2031{
2032 buf_page_t* bpage;2032 buf_page_t* bpage;
2033 ib_mutex_t* block_mutex;2033 ib_mutex_t* block_mutex;
2034 rw_lock_t* hash_lock;2034 prio_rw_lock_t* hash_lock;
2035 ibool discard_attempted = FALSE;2035 ibool discard_attempted = FALSE;
2036 ibool must_read;2036 ibool must_read;
2037 trx_t* trx = NULL;2037 trx_t* trx = NULL;
@@ -2505,7 +2505,7 @@
2505 unsigned access_time;2505 unsigned access_time;
2506 ulint fix_type;2506 ulint fix_type;
2507 ibool must_read;2507 ibool must_read;
2508 rw_lock_t* hash_lock;2508 prio_rw_lock_t* hash_lock;
2509 ib_mutex_t* block_mutex;2509 ib_mutex_t* block_mutex;
2510 buf_page_t* hash_bpage;2510 buf_page_t* hash_bpage;
2511 ulint retries = 0;2511 ulint retries = 0;
@@ -3286,7 +3286,7 @@
3286 ibool success;3286 ibool success;
3287 ulint fix_type;3287 ulint fix_type;
3288 buf_pool_t* buf_pool = buf_pool_get(space_id, page_no);3288 buf_pool_t* buf_pool = buf_pool_get(space_id, page_no);
3289 rw_lock_t* hash_lock;3289 prio_rw_lock_t* hash_lock;
32903290
3291 ut_ad(mtr);3291 ut_ad(mtr);
3292 ut_ad(mtr->state == MTR_ACTIVE);3292 ut_ad(mtr->state == MTR_ACTIVE);
@@ -3498,7 +3498,7 @@
3498 buf_block_t* block;3498 buf_block_t* block;
3499 buf_page_t* bpage = NULL;3499 buf_page_t* bpage = NULL;
3500 buf_page_t* watch_page;3500 buf_page_t* watch_page;
3501 rw_lock_t* hash_lock;3501 prio_rw_lock_t* hash_lock;
3502 mtr_t mtr;3502 mtr_t mtr;
3503 ulint fold;3503 ulint fold;
3504 ibool lru = FALSE;3504 ibool lru = FALSE;
@@ -3751,7 +3751,7 @@
3751 ulint fold;3751 ulint fold;
3752 buf_block_t* free_block = NULL;3752 buf_block_t* free_block = NULL;
3753 buf_pool_t* buf_pool = buf_pool_get(space, offset);3753 buf_pool_t* buf_pool = buf_pool_get(space, offset);
3754 rw_lock_t* hash_lock;3754 prio_rw_lock_t* hash_lock;
37553755
3756 ut_ad(mtr);3756 ut_ad(mtr);
3757 ut_ad(mtr->state == MTR_ACTIVE);3757 ut_ad(mtr->state == MTR_ACTIVE);
@@ -4007,7 +4007,7 @@
4007 ibool ret = TRUE;4007 ibool ret = TRUE;
4008 const ulint fold = buf_page_address_fold(bpage->space,4008 const ulint fold = buf_page_address_fold(bpage->space,
4009 bpage->offset);4009 bpage->offset);
4010 rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);4010 prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);
40114011
4012 /* First unfix and release lock on the bpage */4012 /* First unfix and release lock on the bpage */
4013 mutex_enter(&buf_pool->LRU_list_mutex);4013 mutex_enter(&buf_pool->LRU_list_mutex);
40144014
=== modified file 'Percona-Server/storage/innobase/buf/buf0flu.cc'
--- Percona-Server/storage/innobase/buf/buf0flu.cc 2013-09-25 05:20:37 +0000
+++ Percona-Server/storage/innobase/buf/buf0flu.cc 2013-09-26 14:59:13 +0000
@@ -1141,7 +1141,7 @@
1141 buf_page_t* bpage;1141 buf_page_t* bpage;
1142 buf_pool_t* buf_pool = buf_pool_get(space, offset);1142 buf_pool_t* buf_pool = buf_pool_get(space, offset);
1143 bool ret;1143 bool ret;
1144 rw_lock_t* hash_lock;1144 prio_rw_lock_t* hash_lock;
1145 ib_mutex_t* block_mutex;1145 ib_mutex_t* block_mutex;
11461146
1147 ut_ad(flush_type == BUF_FLUSH_LRU1147 ut_ad(flush_type == BUF_FLUSH_LRU
@@ -1260,7 +1260,7 @@
1260 for (i = low; i < high; i++) {1260 for (i = low; i < high; i++) {
12611261
1262 buf_page_t* bpage;1262 buf_page_t* bpage;
1263 rw_lock_t* hash_lock;1263 prio_rw_lock_t* hash_lock;
1264 ib_mutex_t* block_mutex;1264 ib_mutex_t* block_mutex;
12651265
1266 if ((count + n_flushed) >= n_to_flush) {1266 if ((count + n_flushed) >= n_to_flush) {
@@ -2452,6 +2452,8 @@
24522452
2453 while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {2453 while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
24542454
2455 srv_current_thread_priority = srv_cleaner_thread_priority;
2456
2455 /* The page_cleaner skips sleep if the server is2457 /* The page_cleaner skips sleep if the server is
2456 idle and there are no pending IOs in the buffer pool2458 idle and there are no pending IOs in the buffer pool
2457 and there is work to do. */2459 and there is work to do. */
24582460
=== modified file 'Percona-Server/storage/innobase/buf/buf0lru.cc'
--- Percona-Server/storage/innobase/buf/buf0lru.cc 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/buf/buf0lru.cc 2013-09-26 14:59:13 +0000
@@ -751,7 +751,7 @@
751 bpage != NULL;751 bpage != NULL;
752 /* No op */) {752 /* No op */) {
753753
754 rw_lock_t* hash_lock;754 prio_rw_lock_t* hash_lock;
755 buf_page_t* prev_bpage;755 buf_page_t* prev_bpage;
756 ib_mutex_t* block_mutex = NULL;756 ib_mutex_t* block_mutex = NULL;
757757
@@ -1187,7 +1187,7 @@
1187{1187{
1188 buf_block_t* block;1188 buf_block_t* block;
11891189
1190 mutex_enter(&buf_pool->free_list_mutex);1190 mutex_enter_last(&buf_pool->free_list_mutex);
11911191
1192 block = (buf_block_t*) UT_LIST_GET_LAST(buf_pool->free);1192 block = (buf_block_t*) UT_LIST_GET_LAST(buf_pool->free);
11931193
@@ -1900,7 +1900,7 @@
1900 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);1900 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1901 const ulint fold = buf_page_address_fold(bpage->space,1901 const ulint fold = buf_page_address_fold(bpage->space,
1902 bpage->offset);1902 bpage->offset);
1903 rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);1903 prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);
19041904
1905 ib_mutex_t* block_mutex = buf_page_get_mutex(bpage);1905 ib_mutex_t* block_mutex = buf_page_get_mutex(bpage);
19061906
@@ -2228,7 +2228,7 @@
2228 page_zip_set_size(&block->page.zip, 0);2228 page_zip_set_size(&block->page.zip, 0);
2229 }2229 }
22302230
2231 mutex_enter(&buf_pool->free_list_mutex);2231 mutex_enter_first(&buf_pool->free_list_mutex);
2232 buf_block_set_state(block, BUF_BLOCK_NOT_USED);2232 buf_block_set_state(block, BUF_BLOCK_NOT_USED);
2233 UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));2233 UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
2234 ut_d(block->page.in_free_list = TRUE);2234 ut_d(block->page.in_free_list = TRUE);
@@ -2264,7 +2264,7 @@
2264 ulint fold;2264 ulint fold;
2265 const buf_page_t* hashed_bpage;2265 const buf_page_t* hashed_bpage;
2266 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);2266 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
2267 rw_lock_t* hash_lock;2267 prio_rw_lock_t* hash_lock;
22682268
2269 ut_ad(bpage);2269 ut_ad(bpage);
2270 ut_ad(mutex_own(&buf_pool->LRU_list_mutex));2270 ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
@@ -2513,7 +2513,7 @@
2513#ifdef UNIV_SYNC_DEBUG2513#ifdef UNIV_SYNC_DEBUG
2514 const ulint fold = buf_page_address_fold(bpage->space,2514 const ulint fold = buf_page_address_fold(bpage->space,
2515 bpage->offset);2515 bpage->offset);
2516 rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);2516 prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);
2517#endif2517#endif
2518 ib_mutex_t* block_mutex = buf_page_get_mutex(bpage);2518 ib_mutex_t* block_mutex = buf_page_get_mutex(bpage);
25192519
25202520
=== modified file 'Percona-Server/storage/innobase/buf/buf0rea.cc'
--- Percona-Server/storage/innobase/buf/buf0rea.cc 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/buf/buf0rea.cc 2013-09-26 14:59:13 +0000
@@ -65,7 +65,7 @@
65 == BUF_BLOCK_FILE_PAGE);65 == BUF_BLOCK_FILE_PAGE);
66 const ulint fold = buf_page_address_fold(bpage->space,66 const ulint fold = buf_page_address_fold(bpage->space,
67 bpage->offset);67 bpage->offset);
68 rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);68 prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold);
6969
70 mutex_enter(&buf_pool->LRU_list_mutex);70 mutex_enter(&buf_pool->LRU_list_mutex);
71 rw_lock_x_lock(hash_lock);71 rw_lock_x_lock(hash_lock);
@@ -347,7 +347,7 @@
347347
348 for (i = low; i < high; i++) {348 for (i = low; i < high; i++) {
349349
350 rw_lock_t* hash_lock;350 prio_rw_lock_t* hash_lock;
351351
352 const buf_page_t* bpage =352 const buf_page_t* bpage =
353 buf_page_hash_get_s_locked(buf_pool, space, i,353 buf_page_hash_get_s_locked(buf_pool, space, i,
@@ -642,7 +642,7 @@
642642
643 for (i = low; i < high; i++) {643 for (i = low; i < high; i++) {
644644
645 rw_lock_t* hash_lock;645 prio_rw_lock_t* hash_lock;
646646
647 bpage = buf_page_hash_get_s_locked(buf_pool, space, i,647 bpage = buf_page_hash_get_s_locked(buf_pool, space, i,
648 &hash_lock);648 &hash_lock);
649649
=== modified file 'Percona-Server/storage/innobase/fil/fil0fil.cc'
--- Percona-Server/storage/innobase/fil/fil0fil.cc 2013-09-09 14:20:25 +0000
+++ Percona-Server/storage/innobase/fil/fil0fil.cc 2013-09-26 14:59:13 +0000
@@ -238,7 +238,7 @@
238 hash_node_t hash; /*!< hash chain node */238 hash_node_t hash; /*!< hash chain node */
239 hash_node_t name_hash;/*!< hash chain the name_hash table */239 hash_node_t name_hash;/*!< hash chain the name_hash table */
240#ifndef UNIV_HOTBACKUP240#ifndef UNIV_HOTBACKUP
241 rw_lock_t latch; /*!< latch protecting the file space storage241 prio_rw_lock_t latch; /*!< latch protecting the file space storage
242 allocation */242 allocation */
243#endif /* !UNIV_HOTBACKUP */243#endif /* !UNIV_HOTBACKUP */
244 UT_LIST_NODE_T(fil_space_t) unflushed_spaces;244 UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
@@ -545,7 +545,7 @@
545Returns the latch of a file space.545Returns the latch of a file space.
546@return latch protecting storage allocation */546@return latch protecting storage allocation */
547UNIV_INTERN547UNIV_INTERN
548rw_lock_t*548prio_rw_lock_t*
549fil_space_get_latch(549fil_space_get_latch(
550/*================*/550/*================*/
551 ulint id, /*!< in: space id */551 ulint id, /*!< in: space id */
552552
=== modified file 'Percona-Server/storage/innobase/fsp/fsp0fsp.cc'
--- Percona-Server/storage/innobase/fsp/fsp0fsp.cc 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/fsp/fsp0fsp.cc 2013-09-26 14:59:13 +0000
@@ -2044,7 +2044,7 @@
2044 ib_id_t seg_id;2044 ib_id_t seg_id;
2045 buf_block_t* block = 0; /* remove warning */2045 buf_block_t* block = 0; /* remove warning */
2046 fseg_header_t* header = 0; /* remove warning */2046 fseg_header_t* header = 0; /* remove warning */
2047 rw_lock_t* latch;2047 prio_rw_lock_t* latch;
2048 ibool success;2048 ibool success;
2049 ulint n_reserved;2049 ulint n_reserved;
2050 ulint i;2050 ulint i;
@@ -2212,7 +2212,7 @@
2212 ulint space;2212 ulint space;
2213 ulint flags;2213 ulint flags;
2214 ulint zip_size;2214 ulint zip_size;
2215 rw_lock_t* latch;2215 prio_rw_lock_t* latch;
22162216
2217 space = page_get_space_id(page_align(header));2217 space = page_get_space_id(page_align(header));
2218 latch = fil_space_get_latch(space, &flags);2218 latch = fil_space_get_latch(space, &flags);
@@ -2632,7 +2632,7 @@
2632 ulint space;2632 ulint space;
2633 ulint flags;2633 ulint flags;
2634 ulint zip_size;2634 ulint zip_size;
2635 rw_lock_t* latch;2635 prio_rw_lock_t* latch;
2636 buf_block_t* block;2636 buf_block_t* block;
2637 ulint n_reserved;2637 ulint n_reserved;
26382638
@@ -2749,7 +2749,7 @@
2749 mtr_t* mtr) /*!< in/out: mini-transaction */2749 mtr_t* mtr) /*!< in/out: mini-transaction */
2750{2750{
2751 fsp_header_t* space_header;2751 fsp_header_t* space_header;
2752 rw_lock_t* latch;2752 prio_rw_lock_t* latch;
2753 ulint n_free_list_ext;2753 ulint n_free_list_ext;
2754 ulint free_limit;2754 ulint free_limit;
2755 ulint size;2755 ulint size;
@@ -2865,7 +2865,7 @@
2865 ulint n_free;2865 ulint n_free;
2866 ulint n_free_up;2866 ulint n_free_up;
2867 ulint reserve;2867 ulint reserve;
2868 rw_lock_t* latch;2868 prio_rw_lock_t* latch;
2869 mtr_t mtr;2869 mtr_t mtr;
28702870
2871 /* The convoluted mutex acquire is to overcome latching order2871 /* The convoluted mutex acquire is to overcome latching order
@@ -3195,7 +3195,7 @@
3195 ulint flags;3195 ulint flags;
3196 ulint zip_size;3196 ulint zip_size;
3197 fseg_inode_t* seg_inode;3197 fseg_inode_t* seg_inode;
3198 rw_lock_t* latch;3198 prio_rw_lock_t* latch;
31993199
3200 latch = fil_space_get_latch(space, &flags);3200 latch = fil_space_get_latch(space, &flags);
3201 zip_size = fsp_flags_get_zip_size(flags);3201 zip_size = fsp_flags_get_zip_size(flags);
@@ -3225,7 +3225,7 @@
3225 mtr_t mtr;3225 mtr_t mtr;
3226 ibool is_free;3226 ibool is_free;
3227 ulint flags;3227 ulint flags;
3228 rw_lock_t* latch;3228 prio_rw_lock_t* latch;
3229 xdes_t* descr;3229 xdes_t* descr;
3230 ulint zip_size;3230 ulint zip_size;
3231 fseg_inode_t* seg_inode;3231 fseg_inode_t* seg_inode;
@@ -3350,7 +3350,7 @@
3350 ulint flags;3350 ulint flags;
3351 ulint zip_size;3351 ulint zip_size;
3352 ulint header_page;3352 ulint header_page;
3353 rw_lock_t* latch;3353 prio_rw_lock_t* latch;
33543354
3355 space = page_get_space_id(page_align(header));3355 space = page_get_space_id(page_align(header));
3356 header_page = page_get_page_no(page_align(header));3356 header_page = page_get_page_no(page_align(header));
@@ -3438,7 +3438,7 @@
3438 ulint flags;3438 ulint flags;
3439 ulint zip_size;3439 ulint zip_size;
3440 ulint page_no;3440 ulint page_no;
3441 rw_lock_t* latch;3441 prio_rw_lock_t* latch;
34423442
3443 space = page_get_space_id(page_align(header));3443 space = page_get_space_id(page_align(header));
34443444
@@ -3755,7 +3755,7 @@
3755 fsp_header_t* header;3755 fsp_header_t* header;
3756 fseg_inode_t* seg_inode;3756 fseg_inode_t* seg_inode;
3757 page_t* seg_inode_page;3757 page_t* seg_inode_page;
3758 rw_lock_t* latch;3758 prio_rw_lock_t* latch;
3759 ulint size;3759 ulint size;
3760 ulint flags;3760 ulint flags;
3761 ulint zip_size;3761 ulint zip_size;
@@ -4007,7 +4007,7 @@
4007 fsp_header_t* header;4007 fsp_header_t* header;
4008 fseg_inode_t* seg_inode;4008 fseg_inode_t* seg_inode;
4009 page_t* seg_inode_page;4009 page_t* seg_inode_page;
4010 rw_lock_t* latch;4010 prio_rw_lock_t* latch;
4011 ulint flags;4011 ulint flags;
4012 ulint zip_size;4012 ulint zip_size;
4013 ulint size;4013 ulint size;
40144014
=== modified file 'Percona-Server/storage/innobase/ha/hash0hash.cc'
--- Percona-Server/storage/innobase/ha/hash0hash.cc 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/ha/hash0hash.cc 2013-09-26 14:59:13 +0000
@@ -105,15 +105,15 @@
105void105void
106hash_mutex_exit_all_but(106hash_mutex_exit_all_but(
107/*====================*/107/*====================*/
108 hash_table_t* table, /*!< in: hash table */108 hash_table_t* table, /*!< in: hash table */
109 ib_mutex_t* keep_mutex) /*!< in: mutex to keep */109 ib_prio_mutex_t* keep_mutex) /*!< in: mutex to keep */
110{110{
111 ulint i;111 ulint i;
112112
113 ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);113 ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
114 for (i = 0; i < table->n_sync_obj; i++) {114 for (i = 0; i < table->n_sync_obj; i++) {
115115
116 ib_mutex_t* mutex = table->sync_obj.mutexes + i;116 ib_prio_mutex_t* mutex = table->sync_obj.mutexes + i;
117 if (UNIV_LIKELY(keep_mutex != mutex)) {117 if (UNIV_LIKELY(keep_mutex != mutex)) {
118 mutex_exit(mutex);118 mutex_exit(mutex);
119 }119 }
@@ -132,7 +132,7 @@
132 ulint fold) /*!< in: fold */132 ulint fold) /*!< in: fold */
133{133{
134134
135 rw_lock_t* lock = hash_get_lock(table, fold);135 prio_rw_lock_t* lock = hash_get_lock(table, fold);
136136
137 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);137 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
138 ut_ad(lock);138 ut_ad(lock);
@@ -155,7 +155,7 @@
155 ulint fold) /*!< in: fold */155 ulint fold) /*!< in: fold */
156{156{
157157
158 rw_lock_t* lock = hash_get_lock(table, fold);158 prio_rw_lock_t* lock = hash_get_lock(table, fold);
159159
160 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);160 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
161 ut_ad(lock);161 ut_ad(lock);
@@ -179,7 +179,7 @@
179 ulint fold) /*!< in: fold */179 ulint fold) /*!< in: fold */
180{180{
181181
182 rw_lock_t* lock = hash_get_lock(table, fold);182 prio_rw_lock_t* lock = hash_get_lock(table, fold);
183183
184 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);184 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
185 ut_ad(lock);185 ut_ad(lock);
@@ -200,7 +200,7 @@
200 hash_table_t* table, /*!< in: hash table */200 hash_table_t* table, /*!< in: hash table */
201 ulint fold) /*!< in: fold */201 ulint fold) /*!< in: fold */
202{202{
203 rw_lock_t* lock = hash_get_lock(table, fold);203 prio_rw_lock_t* lock = hash_get_lock(table, fold);
204204
205 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);205 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
206 ut_ad(lock);206 ut_ad(lock);
@@ -225,7 +225,7 @@
225 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);225 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
226 for (i = 0; i < table->n_sync_obj; i++) {226 for (i = 0; i < table->n_sync_obj; i++) {
227227
228 rw_lock_t* lock = table->sync_obj.rw_locks + i;228 prio_rw_lock_t* lock = table->sync_obj.rw_locks + i;
229#ifdef UNIV_SYNC_DEBUG229#ifdef UNIV_SYNC_DEBUG
230 ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED));230 ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED));
231 ut_ad(!rw_lock_own(lock, RW_LOCK_EX));231 ut_ad(!rw_lock_own(lock, RW_LOCK_EX));
@@ -248,7 +248,7 @@
248 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);248 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
249 for (i = 0; i < table->n_sync_obj; i++) {249 for (i = 0; i < table->n_sync_obj; i++) {
250250
251 rw_lock_t* lock = table->sync_obj.rw_locks + i;251 prio_rw_lock_t* lock = table->sync_obj.rw_locks + i;
252#ifdef UNIV_SYNC_DEBUG252#ifdef UNIV_SYNC_DEBUG
253 ut_ad(rw_lock_own(lock, RW_LOCK_EX));253 ut_ad(rw_lock_own(lock, RW_LOCK_EX));
254#endif /* UNIV_SYNC_DEBUG */254#endif /* UNIV_SYNC_DEBUG */
@@ -264,14 +264,14 @@
264hash_unlock_x_all_but(264hash_unlock_x_all_but(
265/*==================*/265/*==================*/
266 hash_table_t* table, /*!< in: hash table */266 hash_table_t* table, /*!< in: hash table */
267 rw_lock_t* keep_lock) /*!< in: lock to keep */267 prio_rw_lock_t* keep_lock) /*!< in: lock to keep */
268{268{
269 ulint i;269 ulint i;
270270
271 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);271 ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
272 for (i = 0; i < table->n_sync_obj; i++) {272 for (i = 0; i < table->n_sync_obj; i++) {
273273
274 rw_lock_t* lock = table->sync_obj.rw_locks + i;274 prio_rw_lock_t* lock = table->sync_obj.rw_locks + i;
275#ifdef UNIV_SYNC_DEBUG275#ifdef UNIV_SYNC_DEBUG
276 ut_ad(rw_lock_own(lock, RW_LOCK_EX));276 ut_ad(rw_lock_own(lock, RW_LOCK_EX));
277#endif /* UNIV_SYNC_DEBUG */277#endif /* UNIV_SYNC_DEBUG */
@@ -373,8 +373,8 @@
373373
374 switch (type) {374 switch (type) {
375 case HASH_TABLE_SYNC_MUTEX:375 case HASH_TABLE_SYNC_MUTEX:
376 table->sync_obj.mutexes = static_cast<ib_mutex_t*>(376 table->sync_obj.mutexes = static_cast<ib_prio_mutex_t*>(
377 mem_alloc(n_sync_obj * sizeof(ib_mutex_t)));377 mem_alloc(n_sync_obj * sizeof(ib_prio_mutex_t)));
378378
379 for (i = 0; i < n_sync_obj; i++) {379 for (i = 0; i < n_sync_obj; i++) {
380 mutex_create(hash_table_mutex_key,380 mutex_create(hash_table_mutex_key,
@@ -384,8 +384,8 @@
384 break;384 break;
385385
386 case HASH_TABLE_SYNC_RW_LOCK:386 case HASH_TABLE_SYNC_RW_LOCK:
387 table->sync_obj.rw_locks = static_cast<rw_lock_t*>(387 table->sync_obj.rw_locks = static_cast<prio_rw_lock_t*>(
388 mem_alloc(n_sync_obj * sizeof(rw_lock_t)));388 mem_alloc(n_sync_obj * sizeof(prio_rw_lock_t)));
389389
390 for (i = 0; i < n_sync_obj; i++) {390 for (i = 0; i < n_sync_obj; i++) {
391 rw_lock_create(hash_table_rw_lock_key,391 rw_lock_create(hash_table_rw_lock_key,
392392
=== modified file 'Percona-Server/storage/innobase/handler/ha_innodb.cc'
--- Percona-Server/storage/innobase/handler/ha_innodb.cc 2013-09-24 13:11:08 +0000
+++ Percona-Server/storage/innobase/handler/ha_innodb.cc 2013-09-26 14:59:13 +0000
@@ -16549,6 +16549,31 @@
16549 PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,16549 PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
16550 "Number of pages reserved in doublewrite buffer for batch flushing",16550 "Number of pages reserved in doublewrite buffer for batch flushing",
16551 NULL, NULL, 120, 1, 127, 0);16551 NULL, NULL, 120, 1, 127, 0);
16552
16553#ifdef UNIV_LINUX
16554
16555static MYSQL_SYSVAR_BOOL(priority_purge, srv_purge_thread_priority,
16556 PLUGIN_VAR_OPCMDARG,
16557 "Make purge coordinator and worker threads acquire shared resources with "
16558 "priority", NULL, NULL, FALSE);
16559
16560static MYSQL_SYSVAR_BOOL(priority_io, srv_io_thread_priority,
16561 PLUGIN_VAR_OPCMDARG,
16562 "Make I/O threads acquire shared resources with priority",
16563 NULL, NULL, FALSE);
16564
16565static MYSQL_SYSVAR_BOOL(priority_cleaner, srv_cleaner_thread_priority,
16566 PLUGIN_VAR_OPCMDARG,
16567 "Make buffer pool cleaner thread acquire shared resources with priority",
16568 NULL, NULL, FALSE);
16569
16570static MYSQL_SYSVAR_BOOL(priority_master, srv_master_thread_priority,
16571 PLUGIN_VAR_OPCMDARG,
16572 "Make buffer pool cleaner thread acquire shared resources with priority",
16573 NULL, NULL, FALSE);
16574
16575#endif /* UNIV_LINUX */
16576
16552#endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */16577#endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */
1655316578
16554static MYSQL_SYSVAR_LONG(buffer_pool_instances, innobase_buffer_pool_instances,16579static MYSQL_SYSVAR_LONG(buffer_pool_instances, innobase_buffer_pool_instances,
@@ -17210,6 +17235,12 @@
17210#if defined UNIV_DEBUG || defined UNIV_PERF_DEBUG17235#if defined UNIV_DEBUG || defined UNIV_PERF_DEBUG
17211 MYSQL_SYSVAR(page_hash_locks),17236 MYSQL_SYSVAR(page_hash_locks),
17212 MYSQL_SYSVAR(doublewrite_batch_size),17237 MYSQL_SYSVAR(doublewrite_batch_size),
17238#ifdef UNIV_LINUX
17239 MYSQL_SYSVAR(priority_purge),
17240 MYSQL_SYSVAR(priority_io),
17241 MYSQL_SYSVAR(priority_cleaner),
17242 MYSQL_SYSVAR(priority_master),
17243#endif /* UNIV_LINUX */
17213#endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */17244#endif /* defined UNIV_DEBUG || defined UNIV_PERF_DEBUG */
17214 MYSQL_SYSVAR(print_all_deadlocks),17245 MYSQL_SYSVAR(print_all_deadlocks),
17215 MYSQL_SYSVAR(cmp_per_index_enabled),17246 MYSQL_SYSVAR(cmp_per_index_enabled),
1721617247
=== modified file 'Percona-Server/storage/innobase/include/btr0sea.h'
--- Percona-Server/storage/innobase/include/btr0sea.h 2013-09-06 13:40:39 +0000
+++ Percona-Server/storage/innobase/include/btr0sea.h 2013-09-26 14:59:13 +0000
@@ -208,7 +208,7 @@
208Returns the adaptive hash index latch for a given index key.208Returns the adaptive hash index latch for a given index key.
209@return the adaptive hash index latch for a given index key */209@return the adaptive hash index latch for a given index key */
210UNIV_INLINE210UNIV_INLINE
211rw_lock_t*211prio_rw_lock_t*
212btr_search_get_latch(212btr_search_get_latch(
213/*=================*/213/*=================*/
214 const dict_index_t* index) /*!< in: index */214 const dict_index_t* index) /*!< in: index */
215215
=== modified file 'Percona-Server/storage/innobase/include/btr0sea.ic'
--- Percona-Server/storage/innobase/include/btr0sea.ic 2013-09-06 13:40:39 +0000
+++ Percona-Server/storage/innobase/include/btr0sea.ic 2013-09-26 14:59:13 +0000
@@ -100,7 +100,7 @@
100Returns the adaptive hash index latch for a given index key.100Returns the adaptive hash index latch for a given index key.
101@return the adaptive hash index latch for a given index key */101@return the adaptive hash index latch for a given index key */
102UNIV_INLINE102UNIV_INLINE
103rw_lock_t*103prio_rw_lock_t*
104btr_search_get_latch(104btr_search_get_latch(
105/*=================*/105/*=================*/
106 const dict_index_t* index) /*!< in: index */106 const dict_index_t* index) /*!< in: index */
107107
=== modified file 'Percona-Server/storage/innobase/include/btr0types.h'
--- Percona-Server/storage/innobase/include/btr0types.h 2013-09-06 13:40:39 +0000
+++ Percona-Server/storage/innobase/include/btr0types.h 2013-09-26 14:59:13 +0000
@@ -55,7 +55,7 @@
55Bear in mind (3) and (4) when using the hash indexes.55Bear in mind (3) and (4) when using the hash indexes.
56*/56*/
5757
58extern rw_lock_t* btr_search_latch_arr;58extern prio_rw_lock_t* btr_search_latch_arr;
5959
60#endif /* UNIV_HOTBACKUP */60#endif /* UNIV_HOTBACKUP */
6161
6262
=== modified file 'Percona-Server/storage/innobase/include/buf0buf.h'
--- Percona-Server/storage/innobase/include/buf0buf.h 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/include/buf0buf.h 2013-09-26 14:59:13 +0000
@@ -1256,7 +1256,7 @@
1256 buf_pool_t* buf_pool, /*!< buffer pool instance */1256 buf_pool_t* buf_pool, /*!< buffer pool instance */
1257 ulint space, /*!< in: space id */1257 ulint space, /*!< in: space id */
1258 ulint offset, /*!< in: page number */1258 ulint offset, /*!< in: page number */
1259 rw_lock_t** lock, /*!< in/out: lock of the page1259 prio_rw_lock_t** lock, /*!< in/out: lock of the page
1260 hash acquired if bpage is1260 hash acquired if bpage is
1261 found. NULL otherwise. If NULL1261 found. NULL otherwise. If NULL
1262 is passed then the hash_lock1262 is passed then the hash_lock
@@ -1282,7 +1282,7 @@
1282 buf_pool_t* buf_pool, /*!< buffer pool instance */1282 buf_pool_t* buf_pool, /*!< buffer pool instance */
1283 ulint space, /*!< in: space id */1283 ulint space, /*!< in: space id */
1284 ulint offset, /*!< in: page number */1284 ulint offset, /*!< in: page number */
1285 rw_lock_t** lock, /*!< in/out: lock of the page1285 prio_rw_lock_t** lock, /*!< in/out: lock of the page
1286 hash acquired if bpage is1286 hash acquired if bpage is
1287 found. NULL otherwise. If NULL1287 found. NULL otherwise. If NULL
1288 is passed then the hash_lock1288 is passed then the hash_lock
@@ -1818,8 +1818,8 @@
1818 pool instance, protects compressed1818 pool instance, protects compressed
1819 only pages (of type buf_page_t, not1819 only pages (of type buf_page_t, not
1820 buf_block_t */1820 buf_block_t */
1821 ib_mutex_t LRU_list_mutex;1821 ib_prio_mutex_t LRU_list_mutex;
1822 ib_mutex_t free_list_mutex;1822 ib_prio_mutex_t free_list_mutex;
1823 ib_mutex_t zip_free_mutex;1823 ib_mutex_t zip_free_mutex;
1824 ib_mutex_t zip_hash_mutex;1824 ib_mutex_t zip_hash_mutex;
1825 ib_mutex_t flush_state_mutex; /*!< Flush state protection1825 ib_mutex_t flush_state_mutex; /*!< Flush state protection
18261826
=== modified file 'Percona-Server/storage/innobase/include/buf0buf.ic'
--- Percona-Server/storage/innobase/include/buf0buf.ic 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/include/buf0buf.ic 2013-09-26 14:59:13 +0000
@@ -1100,7 +1100,7 @@
11001100
1101#ifdef UNIV_SYNC_DEBUG1101#ifdef UNIV_SYNC_DEBUG
1102 ulint hash_fold;1102 ulint hash_fold;
1103 rw_lock_t* hash_lock;1103 prio_rw_lock_t* hash_lock;
11041104
1105 hash_fold = buf_page_address_fold(space, offset);1105 hash_fold = buf_page_address_fold(space, offset);
1106 ut_ad(hash_fold == fold);1106 ut_ad(hash_fold == fold);
@@ -1149,7 +1149,7 @@
1149 buf_pool_t* buf_pool, /*!< buffer pool instance */1149 buf_pool_t* buf_pool, /*!< buffer pool instance */
1150 ulint space, /*!< in: space id */1150 ulint space, /*!< in: space id */
1151 ulint offset, /*!< in: page number */1151 ulint offset, /*!< in: page number */
1152 rw_lock_t** lock, /*!< in/out: lock of the page1152 prio_rw_lock_t** lock, /*!< in/out: lock of the page
1153 hash acquired if bpage is1153 hash acquired if bpage is
1154 found. NULL otherwise. If NULL1154 found. NULL otherwise. If NULL
1155 is passed then the hash_lock1155 is passed then the hash_lock
@@ -1160,7 +1160,7 @@
1160{1160{
1161 buf_page_t* bpage = NULL;1161 buf_page_t* bpage = NULL;
1162 ulint fold;1162 ulint fold;
1163 rw_lock_t* hash_lock;1163 prio_rw_lock_t* hash_lock;
1164 ulint mode = RW_LOCK_SHARED;1164 ulint mode = RW_LOCK_SHARED;
11651165
1166 if (lock != NULL) {1166 if (lock != NULL) {
@@ -1232,7 +1232,7 @@
1232 buf_pool_t* buf_pool, /*!< buffer pool instance */1232 buf_pool_t* buf_pool, /*!< buffer pool instance */
1233 ulint space, /*!< in: space id */1233 ulint space, /*!< in: space id */
1234 ulint offset, /*!< in: page number */1234 ulint offset, /*!< in: page number */
1235 rw_lock_t** lock, /*!< in/out: lock of the page1235 prio_rw_lock_t** lock, /*!< in/out: lock of the page
1236 hash acquired if bpage is1236 hash acquired if bpage is
1237 found. NULL otherwise. If NULL1237 found. NULL otherwise. If NULL
1238 is passed then the hash_lock1238 is passed then the hash_lock
12391239
=== modified file 'Percona-Server/storage/innobase/include/dict0dict.h'
--- Percona-Server/storage/innobase/include/dict0dict.h 2013-08-14 03:57:21 +0000
+++ Percona-Server/storage/innobase/include/dict0dict.h 2013-09-26 14:59:13 +0000
@@ -1367,7 +1367,7 @@
1367Gets the read-write lock of the index tree.1367Gets the read-write lock of the index tree.
1368@return read-write lock */1368@return read-write lock */
1369UNIV_INLINE1369UNIV_INLINE
1370rw_lock_t*1370prio_rw_lock_t*
1371dict_index_get_lock(1371dict_index_get_lock(
1372/*================*/1372/*================*/
1373 dict_index_t* index) /*!< in: index */1373 dict_index_t* index) /*!< in: index */
@@ -1552,7 +1552,7 @@
15521552
1553/* Dictionary system struct */1553/* Dictionary system struct */
1554struct dict_sys_t{1554struct dict_sys_t{
1555 ib_mutex_t mutex; /*!< mutex protecting the data1555 ib_prio_mutex_t mutex; /*!< mutex protecting the data
1556 dictionary; protects also the1556 dictionary; protects also the
1557 disk-based dictionary system tables;1557 disk-based dictionary system tables;
1558 this mutex serializes CREATE TABLE1558 this mutex serializes CREATE TABLE
15591559
=== modified file 'Percona-Server/storage/innobase/include/dict0dict.ic'
--- Percona-Server/storage/innobase/include/dict0dict.ic 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/dict0dict.ic 2013-09-26 14:59:13 +0000
@@ -1175,7 +1175,7 @@
1175Gets the read-write lock of the index tree.1175Gets the read-write lock of the index tree.
1176@return read-write lock */1176@return read-write lock */
1177UNIV_INLINE1177UNIV_INLINE
1178rw_lock_t*1178prio_rw_lock_t*
1179dict_index_get_lock(1179dict_index_get_lock(
1180/*================*/1180/*================*/
1181 dict_index_t* index) /*!< in: index */1181 dict_index_t* index) /*!< in: index */
11821182
=== modified file 'Percona-Server/storage/innobase/include/dict0mem.h'
--- Percona-Server/storage/innobase/include/dict0mem.h 2013-09-02 10:01:38 +0000
+++ Percona-Server/storage/innobase/include/dict0mem.h 2013-09-26 14:59:13 +0000
@@ -544,7 +544,7 @@
544initialized to 0, NULL or FALSE in dict_mem_index_create(). */544initialized to 0, NULL or FALSE in dict_mem_index_create(). */
545struct dict_index_t{545struct dict_index_t{
546 index_id_t id; /*!< id of the index */546 index_id_t id; /*!< id of the index */
547 rw_lock_t* search_latch; /*!< latch protecting the AHI partition547 prio_rw_lock_t* search_latch; /*!< latch protecting the AHI partition
548 corresponding to this index */548 corresponding to this index */
549 hash_table_t* search_table; /*!< hash table protected by549 hash_table_t* search_table; /*!< hash table protected by
550 search_latch */550 search_latch */
@@ -632,7 +632,7 @@
632 /*!< approximate number of leaf pages in the632 /*!< approximate number of leaf pages in the
633 index tree */633 index tree */
634 /* @} */634 /* @} */
635 rw_lock_t lock; /*!< read-write lock protecting the635 prio_rw_lock_t lock; /*!< read-write lock protecting the
636 upper levels of the index tree */636 upper levels of the index tree */
637 trx_id_t trx_id; /*!< id of the transaction that created this637 trx_id_t trx_id; /*!< id of the transaction that created this
638 index, or 0 if the index existed638 index, or 0 if the index existed
639639
=== modified file 'Percona-Server/storage/innobase/include/fil0fil.h'
--- Percona-Server/storage/innobase/include/fil0fil.h 2013-08-14 03:57:21 +0000
+++ Percona-Server/storage/innobase/include/fil0fil.h 2013-09-26 14:59:13 +0000
@@ -189,7 +189,7 @@
189Returns the latch of a file space.189Returns the latch of a file space.
190@return latch protecting storage allocation */190@return latch protecting storage allocation */
191UNIV_INTERN191UNIV_INTERN
192rw_lock_t*192prio_rw_lock_t*
193fil_space_get_latch(193fil_space_get_latch(
194/*================*/194/*================*/
195 ulint id, /*!< in: space id */195 ulint id, /*!< in: space id */
196196
=== modified file 'Percona-Server/storage/innobase/include/ha0ha.ic'
--- Percona-Server/storage/innobase/include/ha0ha.ic 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/ha0ha.ic 2013-09-26 14:59:13 +0000
@@ -123,7 +123,7 @@
123 ut_ad(mutex_own(hash_get_mutex(table, fold)));123 ut_ad(mutex_own(hash_get_mutex(table, fold)));
124 } else if (table->type == HASH_TABLE_SYNC_RW_LOCK) {124 } else if (table->type == HASH_TABLE_SYNC_RW_LOCK) {
125# ifdef UNIV_SYNC_DEBUG125# ifdef UNIV_SYNC_DEBUG
126 rw_lock_t* lock = hash_get_lock(table, fold);126 prio_rw_lock_t* lock = hash_get_lock(table, fold);
127 ut_ad(rw_lock_own(lock, RW_LOCK_EX));127 ut_ad(rw_lock_own(lock, RW_LOCK_EX));
128# endif128# endif
129 } else {129 } else {
@@ -146,7 +146,7 @@
146 ut_ad(mutex_own(hash_get_mutex(table, fold)));146 ut_ad(mutex_own(hash_get_mutex(table, fold)));
147 } else if (table->type == HASH_TABLE_SYNC_RW_LOCK) {147 } else if (table->type == HASH_TABLE_SYNC_RW_LOCK) {
148# ifdef UNIV_SYNC_DEBUG148# ifdef UNIV_SYNC_DEBUG
149 rw_lock_t* lock = hash_get_lock(table, fold);149 prio_rw_lock_t* lock = hash_get_lock(table, fold);
150 ut_ad(rw_lock_own(lock, RW_LOCK_EX)150 ut_ad(rw_lock_own(lock, RW_LOCK_EX)
151 || rw_lock_own(lock, RW_LOCK_SHARED));151 || rw_lock_own(lock, RW_LOCK_SHARED));
152# endif152# endif
153153
=== modified file 'Percona-Server/storage/innobase/include/hash0hash.h'
--- Percona-Server/storage/innobase/include/hash0hash.h 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/hash0hash.h 2013-09-26 14:59:13 +0000
@@ -382,7 +382,7 @@
382Gets the nth mutex in a hash table.382Gets the nth mutex in a hash table.
383@return mutex */383@return mutex */
384UNIV_INLINE384UNIV_INLINE
385ib_mutex_t*385ib_prio_mutex_t*
386hash_get_nth_mutex(386hash_get_nth_mutex(
387/*===============*/387/*===============*/
388 hash_table_t* table, /*!< in: hash table */388 hash_table_t* table, /*!< in: hash table */
@@ -391,7 +391,7 @@
391Gets the nth rw_lock in a hash table.391Gets the nth rw_lock in a hash table.
392@return rw_lock */392@return rw_lock */
393UNIV_INLINE393UNIV_INLINE
394rw_lock_t*394prio_rw_lock_t*
395hash_get_nth_lock(395hash_get_nth_lock(
396/*==============*/396/*==============*/
397 hash_table_t* table, /*!< in: hash table */397 hash_table_t* table, /*!< in: hash table */
@@ -400,7 +400,7 @@
400Gets the mutex for a fold value in a hash table.400Gets the mutex for a fold value in a hash table.
401@return mutex */401@return mutex */
402UNIV_INLINE402UNIV_INLINE
403ib_mutex_t*403ib_prio_mutex_t*
404hash_get_mutex(404hash_get_mutex(
405/*===========*/405/*===========*/
406 hash_table_t* table, /*!< in: hash table */406 hash_table_t* table, /*!< in: hash table */
@@ -409,7 +409,7 @@
409Gets the rw_lock for a fold value in a hash table.409Gets the rw_lock for a fold value in a hash table.
410@return rw_lock */410@return rw_lock */
411UNIV_INLINE411UNIV_INLINE
412rw_lock_t*412prio_rw_lock_t*
413hash_get_lock(413hash_get_lock(
414/*==========*/414/*==========*/
415 hash_table_t* table, /*!< in: hash table */415 hash_table_t* table, /*!< in: hash table */
@@ -450,8 +450,8 @@
450void450void
451hash_mutex_exit_all_but(451hash_mutex_exit_all_but(
452/*====================*/452/*====================*/
453 hash_table_t* table, /*!< in: hash table */453 hash_table_t* table, /*!< in: hash table */
454 ib_mutex_t* keep_mutex); /*!< in: mutex to keep */454 ib_prio_mutex_t* keep_mutex); /*!< in: mutex to keep */
455/************************************************************//**455/************************************************************//**
456s-lock a lock for a fold value in a hash table. */456s-lock a lock for a fold value in a hash table. */
457UNIV_INTERN457UNIV_INTERN
@@ -506,7 +506,7 @@
506hash_unlock_x_all_but(506hash_unlock_x_all_but(
507/*==================*/507/*==================*/
508 hash_table_t* table, /*!< in: hash table */508 hash_table_t* table, /*!< in: hash table */
509 rw_lock_t* keep_lock); /*!< in: lock to keep */509 prio_rw_lock_t* keep_lock); /*!< in: lock to keep */
510510
511#else /* !UNIV_HOTBACKUP */511#else /* !UNIV_HOTBACKUP */
512# define hash_get_heap(table, fold) ((table)->heap)512# define hash_get_heap(table, fold) ((table)->heap)
@@ -547,10 +547,11 @@
547 rw_locks depending on the type.547 rw_locks depending on the type.
548 Must be a power of 2 */548 Must be a power of 2 */
549 union {549 union {
550 ib_mutex_t* mutexes;/* NULL, or an array of mutexes550 ib_prio_mutex_t* mutexes;
551 /* NULL, or an array of mutexes
551 used to protect segments of the552 used to protect segments of the
552 hash table */553 hash table */
553 rw_lock_t* rw_locks;/* NULL, or an array of rw_lcoks554 prio_rw_lock_t* rw_locks;/* NULL, or an array of rw_lcoks
554 used to protect segments of the555 used to protect segments of the
555 hash table */556 hash table */
556 } sync_obj;557 } sync_obj;
557558
=== modified file 'Percona-Server/storage/innobase/include/hash0hash.ic'
--- Percona-Server/storage/innobase/include/hash0hash.ic 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/hash0hash.ic 2013-09-26 14:59:13 +0000
@@ -150,7 +150,7 @@
150Gets the nth mutex in a hash table.150Gets the nth mutex in a hash table.
151@return mutex */151@return mutex */
152UNIV_INLINE152UNIV_INLINE
153ib_mutex_t*153ib_prio_mutex_t*
154hash_get_nth_mutex(154hash_get_nth_mutex(
155/*===============*/155/*===============*/
156 hash_table_t* table, /*!< in: hash table */156 hash_table_t* table, /*!< in: hash table */
@@ -168,7 +168,7 @@
168Gets the mutex for a fold value in a hash table.168Gets the mutex for a fold value in a hash table.
169@return mutex */169@return mutex */
170UNIV_INLINE170UNIV_INLINE
171ib_mutex_t*171ib_prio_mutex_t*
172hash_get_mutex(172hash_get_mutex(
173/*===========*/173/*===========*/
174 hash_table_t* table, /*!< in: hash table */174 hash_table_t* table, /*!< in: hash table */
@@ -188,7 +188,7 @@
188Gets the nth rw_lock in a hash table.188Gets the nth rw_lock in a hash table.
189@return rw_lock */189@return rw_lock */
190UNIV_INLINE190UNIV_INLINE
191rw_lock_t*191prio_rw_lock_t*
192hash_get_nth_lock(192hash_get_nth_lock(
193/*==============*/193/*==============*/
194 hash_table_t* table, /*!< in: hash table */194 hash_table_t* table, /*!< in: hash table */
@@ -206,7 +206,7 @@
206Gets the rw_lock for a fold value in a hash table.206Gets the rw_lock for a fold value in a hash table.
207@return rw_lock */207@return rw_lock */
208UNIV_INLINE208UNIV_INLINE
209rw_lock_t*209prio_rw_lock_t*
210hash_get_lock(210hash_get_lock(
211/*==========*/211/*==========*/
212 hash_table_t* table, /*!< in: hash table */212 hash_table_t* table, /*!< in: hash table */
213213
=== modified file 'Percona-Server/storage/innobase/include/log0log.h'
--- Percona-Server/storage/innobase/include/log0log.h 2013-06-25 13:13:06 +0000
+++ Percona-Server/storage/innobase/include/log0log.h 2013-09-26 14:59:13 +0000
@@ -796,7 +796,7 @@
796 ulint buf_free; /*!< first free offset within the log796 ulint buf_free; /*!< first free offset within the log
797 buffer */797 buffer */
798#ifndef UNIV_HOTBACKUP798#ifndef UNIV_HOTBACKUP
799 ib_mutex_t mutex; /*!< mutex protecting the log */799 ib_prio_mutex_t mutex; /*!< mutex protecting the log */
800800
801 ib_mutex_t log_flush_order_mutex;/*!< mutex to serialize access to801 ib_mutex_t log_flush_order_mutex;/*!< mutex to serialize access to
802 the flush list when we are putting802 the flush list when we are putting
803803
=== modified file 'Percona-Server/storage/innobase/include/mtr0mtr.h'
--- Percona-Server/storage/innobase/include/mtr0mtr.h 2013-06-25 13:13:06 +0000
+++ Percona-Server/storage/innobase/include/mtr0mtr.h 2013-09-26 14:59:13 +0000
@@ -234,7 +234,7 @@
234/*=============================*/234/*=============================*/
235 mtr_t* mtr, /*!< in: mtr */235 mtr_t* mtr, /*!< in: mtr */
236 ulint savepoint, /*!< in: savepoint */236 ulint savepoint, /*!< in: savepoint */
237 rw_lock_t* lock); /*!< in: latch to release */237 prio_rw_lock_t* lock); /*!< in: latch to release */
238#else /* !UNIV_HOTBACKUP */238#else /* !UNIV_HOTBACKUP */
239# define mtr_release_s_latch_at_savepoint(mtr,savepoint,lock) ((void) 0)239# define mtr_release_s_latch_at_savepoint(mtr,savepoint,lock) ((void) 0)
240#endif /* !UNIV_HOTBACKUP */240#endif /* !UNIV_HOTBACKUP */
@@ -281,7 +281,7 @@
281void281void
282mtr_s_lock_func(282mtr_s_lock_func(
283/*============*/283/*============*/
284 rw_lock_t* lock, /*!< in: rw-lock */284 prio_rw_lock_t* lock, /*!< in: rw-lock */
285 const char* file, /*!< in: file name */285 const char* file, /*!< in: file name */
286 ulint line, /*!< in: line number */286 ulint line, /*!< in: line number */
287 mtr_t* mtr); /*!< in: mtr */287 mtr_t* mtr); /*!< in: mtr */
@@ -292,7 +292,7 @@
292void292void
293mtr_x_lock_func(293mtr_x_lock_func(
294/*============*/294/*============*/
295 rw_lock_t* lock, /*!< in: rw-lock */295 prio_rw_lock_t* lock, /*!< in: rw-lock */
296 const char* file, /*!< in: file name */296 const char* file, /*!< in: file name */
297 ulint line, /*!< in: line number */297 ulint line, /*!< in: line number */
298 mtr_t* mtr); /*!< in: mtr */298 mtr_t* mtr); /*!< in: mtr */
299299
=== modified file 'Percona-Server/storage/innobase/include/mtr0mtr.ic'
--- Percona-Server/storage/innobase/include/mtr0mtr.ic 2013-05-26 14:20:00 +0000
+++ Percona-Server/storage/innobase/include/mtr0mtr.ic 2013-09-26 14:59:13 +0000
@@ -130,7 +130,7 @@
130/*=============================*/130/*=============================*/
131 mtr_t* mtr, /*!< in: mtr */131 mtr_t* mtr, /*!< in: mtr */
132 ulint savepoint, /*!< in: savepoint */132 ulint savepoint, /*!< in: savepoint */
133 rw_lock_t* lock) /*!< in: latch to release */133 prio_rw_lock_t* lock) /*!< in: latch to release */
134{134{
135 mtr_memo_slot_t* slot;135 mtr_memo_slot_t* slot;
136 dyn_array_t* memo;136 dyn_array_t* memo;
@@ -261,7 +261,7 @@
261void261void
262mtr_s_lock_func(262mtr_s_lock_func(
263/*============*/263/*============*/
264 rw_lock_t* lock, /*!< in: rw-lock */264 prio_rw_lock_t* lock, /*!< in: rw-lock */
265 const char* file, /*!< in: file name */265 const char* file, /*!< in: file name */
266 ulint line, /*!< in: line number */266 ulint line, /*!< in: line number */
267 mtr_t* mtr) /*!< in: mtr */267 mtr_t* mtr) /*!< in: mtr */
@@ -280,7 +280,7 @@
280void280void
281mtr_x_lock_func(281mtr_x_lock_func(
282/*============*/282/*============*/
283 rw_lock_t* lock, /*!< in: rw-lock */283 prio_rw_lock_t* lock, /*!< in: rw-lock */
284 const char* file, /*!< in: file name */284 const char* file, /*!< in: file name */
285 ulint line, /*!< in: line number */285 ulint line, /*!< in: line number */
286 mtr_t* mtr) /*!< in: mtr */286 mtr_t* mtr) /*!< in: mtr */
287287
=== modified file 'Percona-Server/storage/innobase/include/srv0srv.h'
--- Percona-Server/storage/innobase/include/srv0srv.h 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/srv0srv.h 2013-09-26 14:59:13 +0000
@@ -479,6 +479,18 @@
479extern const char* srv_io_thread_op_info[];479extern const char* srv_io_thread_op_info[];
480extern const char* srv_io_thread_function[];480extern const char* srv_io_thread_function[];
481481
482/* The relative priority of the purge coordinator and worker threads. */
483extern my_bool srv_purge_thread_priority;
484
485/* The relative priority of the I/O threads. */
486extern my_bool srv_io_thread_priority;
487
488/* The relative priority of the cleaner thread. */
489extern my_bool srv_cleaner_thread_priority;
490
491/* The relative priority of the master thread. */
492extern my_bool srv_master_thread_priority;
493
482/* the number of purge threads to use from the worker pool (currently 0 or 1) */494/* the number of purge threads to use from the worker pool (currently 0 or 1) */
483extern ulong srv_n_purge_threads;495extern ulong srv_n_purge_threads;
484496
485497
=== modified file 'Percona-Server/storage/innobase/include/sync0rw.h'
--- Percona-Server/storage/innobase/include/sync0rw.h 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/sync0rw.h 2013-09-26 14:59:13 +0000
@@ -96,6 +96,7 @@
96#define X_LOCK_DECR 0x0010000096#define X_LOCK_DECR 0x00100000
9797
98struct rw_lock_t;98struct rw_lock_t;
99struct prio_rw_lock_t;
99#ifdef UNIV_SYNC_DEBUG100#ifdef UNIV_SYNC_DEBUG
100struct rw_lock_debug_t;101struct rw_lock_debug_t;
101#endif /* UNIV_SYNC_DEBUG */102#endif /* UNIV_SYNC_DEBUG */
@@ -299,6 +300,24 @@
299#endif /* UNIV_DEBUG */300#endif /* UNIV_DEBUG */
300 const char* cmutex_name); /*!< in: mutex name */301 const char* cmutex_name); /*!< in: mutex name */
301/******************************************************************//**302/******************************************************************//**
303Creates, or rather, initializes a priority rw-lock object in a specified memory
304location (which must be appropriately aligned). The rw-lock is initialized
305to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
306is necessary only if the memory block containing it is freed. */
307UNIV_INTERN
308void
309rw_lock_create_func(
310/*================*/
311 prio_rw_lock_t* lock, /*!< in: pointer to memory */
312#ifdef UNIV_DEBUG
313# ifdef UNIV_SYNC_DEBUG
314 ulint level, /*!< in: level */
315# endif /* UNIV_SYNC_DEBUG */
316 const char* cfile_name, /*!< in: file name where created */
317 ulint cline, /*!< in: file line where created */
318#endif /* UNIV_DEBUG */
319 const char* cmutex_name); /*!< in: mutex name */
320/******************************************************************//**
302Calling this function is obligatory only if the memory buffer containing321Calling this function is obligatory only if the memory buffer containing
303the rw-lock is freed. Removes an rw-lock object from the global list. The322the rw-lock is freed. Removes an rw-lock object from the global list. The
304rw-lock is checked to be in the non-locked state. */323rw-lock is checked to be in the non-locked state. */
@@ -307,6 +326,15 @@
307rw_lock_free_func(326rw_lock_free_func(
308/*==============*/327/*==============*/
309 rw_lock_t* lock); /*!< in: rw-lock */328 rw_lock_t* lock); /*!< in: rw-lock */
329/******************************************************************//**
330Calling this function is obligatory only if the memory buffer containing
331the priority rw-lock is freed. Removes an rw-lock object from the global list.
332The rw-lock is checked to be in the non-locked state. */
333UNIV_INTERN
334void
335rw_lock_free_func(
336/*==============*/
337 prio_rw_lock_t* lock); /*!< in: rw-lock */
310#ifdef UNIV_DEBUG338#ifdef UNIV_DEBUG
311/******************************************************************//**339/******************************************************************//**
312Checks that the rw-lock has been initialized and that there are no340Checks that the rw-lock has been initialized and that there are no
@@ -317,6 +345,15 @@
317rw_lock_validate(345rw_lock_validate(
318/*=============*/346/*=============*/
319 rw_lock_t* lock); /*!< in: rw-lock */347 rw_lock_t* lock); /*!< in: rw-lock */
348/******************************************************************//**
349Checks that the priority rw-lock has been initialized and that there are no
350simultaneous shared and exclusive locks.
351@return TRUE */
352UNIV_INTERN
353ibool
354rw_lock_validate(
355/*=============*/
356 prio_rw_lock_t* lock); /*!< in: rw-lock */
320#endif /* UNIV_DEBUG */357#endif /* UNIV_DEBUG */
321/******************************************************************//**358/******************************************************************//**
322Low-level function which tries to lock an rw-lock in s-mode. Performs no359Low-level function which tries to lock an rw-lock in s-mode. Performs no
@@ -349,6 +386,22 @@
349 const char* file_name,/*!< in: file name where lock requested */386 const char* file_name,/*!< in: file name where lock requested */
350 ulint line); /*!< in: line where requested */387 ulint line); /*!< in: line where requested */
351/******************************************************************//**388/******************************************************************//**
389NOTE! Use the corresponding macro, not directly this function, except if
390you supply the file name and line number. Lock a priority rw-lock in shared
391mode for the current thread, using the relative thread priority. If the
392rw-lock is locked in exclusive mode, or there is an exclusive lock request
393waiting, the function spins a preset time (controlled by SYNC_SPIN_ROUNDS),
394waiting for the lock, before suspending the thread. */
395UNIV_INLINE
396void
397rw_lock_s_lock_func(
398/*================*/
399 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
400 ulint pass, /*!< in: pass value; != 0, if the lock will
401 be passed to another thread to unlock */
402 const char* file_name,/*!< in: file name where lock requested */
403 ulint line); /*!< in: line where requested */
404/******************************************************************//**
352NOTE! Use the corresponding macro, not directly this function! Lock an405NOTE! Use the corresponding macro, not directly this function! Lock an
353rw-lock in exclusive mode for the current thread if the lock can be406rw-lock in exclusive mode for the current thread if the lock can be
354obtained immediately.407obtained immediately.
@@ -373,6 +426,17 @@
373 rw_lock_t* lock); /*!< in/out: rw-lock */426 rw_lock_t* lock); /*!< in/out: rw-lock */
374427
375/******************************************************************//**428/******************************************************************//**
429Releases a shared mode priority lock. */
430UNIV_INLINE
431void
432rw_lock_s_unlock_func(
433/*==================*/
434#ifdef UNIV_SYNC_DEBUG
435 ulint pass, /*!< in: pass value; != 0, if the lock may have
436 been passed to another thread to unlock */
437#endif
438 prio_rw_lock_t* lock); /*!< in/out: rw-lock */
439/******************************************************************//**
376NOTE! Use the corresponding macro, not directly this function! Lock an440NOTE! Use the corresponding macro, not directly this function! Lock an
377rw-lock in exclusive mode for the current thread. If the rw-lock is locked441rw-lock in exclusive mode for the current thread. If the rw-lock is locked
378in shared or exclusive mode, or there is an exclusive lock request waiting,442in shared or exclusive mode, or there is an exclusive lock request waiting,
@@ -385,7 +449,30 @@
385void449void
386rw_lock_x_lock_func(450rw_lock_x_lock_func(
387/*================*/451/*================*/
388 rw_lock_t* lock, /*!< in: pointer to rw-lock */452 rw_lock_t* lock, /*!< in: pointer to rw-lock */
453 ulint pass, /*!< in: pass value; != 0, if the lock will
454 be passed to another thread to unlock */
455 const char* file_name,/*!< in: file name where lock requested */
456 ulint line, /*!< in: line where requested */
457 bool priority_lock = false,
458 /*!< in: whether the lock is a priority lock */
459 bool high_priority = false);
460 /*!< in: whether we are acquiring a priority
461 lock with high priority */
462/******************************************************************//**
463NOTE! Use the corresponding macro, not directly this function! Lock a priority
464rw-lock in exclusive mode for the current thread. If the rw-lock is locked
465in shared or exclusive mode, or there is an exclusive lock request waiting,
466the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
467for the lock, before suspending the thread. If the same thread has an x-lock
468on the rw-lock, locking succeed, with the following exception: if pass != 0,
469only a single x-lock may be taken on the lock. NOTE: If the same thread has
470an s-lock, locking does not succeed! */
471UNIV_INTERN
472void
473rw_lock_x_lock_func(
474/*================*/
475 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
389 ulint pass, /*!< in: pass value; != 0, if the lock will476 ulint pass, /*!< in: pass value; != 0, if the lock will
390 be passed to another thread to unlock */477 be passed to another thread to unlock */
391 const char* file_name,/*!< in: file name where lock requested */478 const char* file_name,/*!< in: file name where lock requested */
@@ -402,6 +489,17 @@
402#endif489#endif
403 rw_lock_t* lock); /*!< in/out: rw-lock */490 rw_lock_t* lock); /*!< in/out: rw-lock */
404/******************************************************************//**491/******************************************************************//**
492Releases an exclusive mode priority lock. */
493UNIV_INLINE
494void
495rw_lock_x_unlock_func(
496/*==================*/
497#ifdef UNIV_SYNC_DEBUG
498 ulint pass, /*!< in: pass value; != 0, if the lock may have
499 been passed to another thread to unlock */
500#endif
501 prio_rw_lock_t* lock); /*!< in/out: rw-lock */
502/******************************************************************//**
405This function is used in the insert buffer to move the ownership of an503This function is used in the insert buffer to move the ownership of an
406x-latch on a buffer frame to the current thread. The x-latch was set by504x-latch on a buffer frame to the current thread. The x-latch was set by
407the buffer read operation and it protected the buffer frame while the505the buffer read operation and it protected the buffer frame while the
@@ -424,6 +522,15 @@
424rw_lock_get_x_lock_count(522rw_lock_get_x_lock_count(
425/*=====================*/523/*=====================*/
426 const rw_lock_t* lock); /*!< in: rw-lock */524 const rw_lock_t* lock); /*!< in: rw-lock */
525/******************************************************************//**
526Returns the value of writer_count for the priority lock. Does not reserve the
527lock mutex, so the caller must be sure it is not changed during the call.
528@return value of writer_count */
529UNIV_INLINE
530ulint
531rw_lock_get_x_lock_count(
532/*=====================*/
533 const prio_rw_lock_t* lock); /*!< in: rw-lock */
427/********************************************************************//**534/********************************************************************//**
428Check if there are threads waiting for the rw-lock.535Check if there are threads waiting for the rw-lock.
429@return 1 if waiters, 0 otherwise */536@return 1 if waiters, 0 otherwise */
@@ -432,6 +539,14 @@
432rw_lock_get_waiters(539rw_lock_get_waiters(
433/*================*/540/*================*/
434 const rw_lock_t* lock); /*!< in: rw-lock */541 const rw_lock_t* lock); /*!< in: rw-lock */
542/********************************************************************//**
543Check if there are threads waiting for the priority rw-lock.
544@return 1 if waiters, 0 otherwise */
545UNIV_INLINE
546ulint
547rw_lock_get_waiters(
548/*================*/
549 const prio_rw_lock_t* lock); /*!< in: rw-lock */
435/******************************************************************//**550/******************************************************************//**
436Returns the write-status of the lock - this function made more sense551Returns the write-status of the lock - this function made more sense
437with the old rw_lock implementation.552with the old rw_lock implementation.
@@ -442,6 +557,15 @@
442/*===============*/557/*===============*/
443 const rw_lock_t* lock); /*!< in: rw-lock */558 const rw_lock_t* lock); /*!< in: rw-lock */
444/******************************************************************//**559/******************************************************************//**
560Returns the write-status of the priority lock - this function made more sense
561with the old rw_lock implementation.
562@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
563UNIV_INLINE
564ulint
565rw_lock_get_writer(
566/*===============*/
567 const prio_rw_lock_t* lock); /*!< in: rw-lock */
568/******************************************************************//**
445Returns the number of readers.569Returns the number of readers.
446@return number of readers */570@return number of readers */
447UNIV_INLINE571UNIV_INLINE
@@ -450,6 +574,14 @@
450/*=====================*/574/*=====================*/
451 const rw_lock_t* lock); /*!< in: rw-lock */575 const rw_lock_t* lock); /*!< in: rw-lock */
452/******************************************************************//**576/******************************************************************//**
577Returns the number of readers.
578@return number of readers */
579UNIV_INLINE
580ulint
581rw_lock_get_reader_count(
582/*=====================*/
583 const prio_rw_lock_t* lock); /*!< in: rw-lock */
584/******************************************************************//**
453Decrements lock_word the specified amount if it is greater than 0.585Decrements lock_word the specified amount if it is greater than 0.
454This is used by both s_lock and x_lock operations.586This is used by both s_lock and x_lock operations.
455@return TRUE if decr occurs */587@return TRUE if decr occurs */
@@ -496,6 +628,17 @@
496 ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,628 ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
497 RW_LOCK_EX */629 RW_LOCK_EX */
498 __attribute__((warn_unused_result));630 __attribute__((warn_unused_result));
631/******************************************************************//**
632Checks if the thread has locked the priority rw-lock in the specified mode,
633with the pass value == 0. */
634UNIV_INTERN
635ibool
636rw_lock_own(
637/*========*/
638 prio_rw_lock_t* lock, /*!< in: rw-lock */
639 ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
640 RW_LOCK_EX */
641 __attribute__((warn_unused_result));
499#endif /* UNIV_SYNC_DEBUG */642#endif /* UNIV_SYNC_DEBUG */
500/******************************************************************//**643/******************************************************************//**
501Checks if somebody has locked the rw-lock in the specified mode. */644Checks if somebody has locked the rw-lock in the specified mode. */
@@ -631,6 +774,27 @@
631#endif /* UNIV_DEBUG */774#endif /* UNIV_DEBUG */
632};775};
633776
777/** The structure implementing a priority rw lock. */
778struct prio_rw_lock_t {
779 struct rw_lock_t base_lock; /* The regular rw latch
780 provides the lock word etc. for
781 the priority rw lock */
782 volatile ulint high_priority_s_waiters;
783 /* If 1, high priority S
784 waiters exist */
785 os_event_t high_priority_s_event; /* High priority wait
786 array event for S waiters */
787 volatile ulint high_priority_x_waiters;
788 /* If 1, high priority X
789 waiters exist */
790 os_event_t high_priority_x_event;
791 /* High priority wait arraay
792 event for X waiters */
793 volatile ulint high_priority_wait_ex_waiter;
794 /* If 1, a waiting next-writer
795 exists and is high-priority */
796};
797
634#ifdef UNIV_SYNC_DEBUG798#ifdef UNIV_SYNC_DEBUG
635/** The structure for storing debug info of an rw-lock. All access to this799/** The structure for storing debug info of an rw-lock. All access to this
636structure must be protected by rw_lock_debug_mutex_enter(). */800structure must be protected by rw_lock_debug_mutex_enter(). */
@@ -695,6 +859,26 @@
695 const char* cmutex_name); /*!< in: mutex name */859 const char* cmutex_name); /*!< in: mutex name */
696860
697/******************************************************************//**861/******************************************************************//**
862Performance schema instrumented wrap function for rw_lock_create_func()
863NOTE! Please use the corresponding macro rw_lock_create(), not
864directly this function! */
865UNIV_INLINE
866void
867pfs_rw_lock_create_func(
868/*====================*/
869 PSI_rwlock_key key, /*!< in: key registered with
870 performance schema */
871 prio_rw_lock_t* lock, /*!< in: rw lock */
872#ifdef UNIV_DEBUG
873# ifdef UNIV_SYNC_DEBUG
874 ulint level, /*!< in: level */
875# endif /* UNIV_SYNC_DEBUG */
876 const char* cfile_name, /*!< in: file name where created */
877 ulint cline, /*!< in: file line where created */
878#endif /* UNIV_DEBUG */
879 const char* cmutex_name); /*!< in: mutex name */
880
881/******************************************************************//**
698Performance schema instrumented wrap function for rw_lock_x_lock_func()882Performance schema instrumented wrap function for rw_lock_x_lock_func()
699NOTE! Please use the corresponding macro rw_lock_x_lock(), not883NOTE! Please use the corresponding macro rw_lock_x_lock(), not
700directly this function! */884directly this function! */
@@ -707,6 +891,21 @@
707 be passed to another thread to unlock */891 be passed to another thread to unlock */
708 const char* file_name,/*!< in: file name where lock requested */892 const char* file_name,/*!< in: file name where lock requested */
709 ulint line); /*!< in: line where requested */893 ulint line); /*!< in: line where requested */
894
895/******************************************************************//**
896Performance schema instrumented wrap function for rw_lock_x_lock_func()
897NOTE! Please use the corresponding macro rw_lock_x_lock(), not
898directly this function! */
899UNIV_INLINE
900void
901pfs_rw_lock_x_lock_func(
902/*====================*/
903 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
904 ulint pass, /*!< in: pass value; != 0, if the lock will
905 be passed to another thread to unlock */
906 const char* file_name,/*!< in: file name where lock requested */
907 ulint line); /*!< in: line where requested */
908
710/******************************************************************//**909/******************************************************************//**
711Performance schema instrumented wrap function for910Performance schema instrumented wrap function for
712rw_lock_x_lock_func_nowait()911rw_lock_x_lock_func_nowait()
@@ -719,75 +918,147 @@
719 rw_lock_t* lock, /*!< in: pointer to rw-lock */918 rw_lock_t* lock, /*!< in: pointer to rw-lock */
720 const char* file_name,/*!< in: file name where lock requested */919 const char* file_name,/*!< in: file name where lock requested */
721 ulint line); /*!< in: line where requested */920 ulint line); /*!< in: line where requested */
722/******************************************************************//**921
723Performance schema instrumented wrap function for rw_lock_s_lock_func()922/******************************************************************//**
724NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly923Performance schema instrumented wrap function for rw_lock_s_lock_func()
725this function! */924NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
726UNIV_INLINE925this function! */
727void926UNIV_INLINE
728pfs_rw_lock_s_lock_func(927void
729/*====================*/928pfs_rw_lock_s_lock_func(
730 rw_lock_t* lock, /*!< in: pointer to rw-lock */929/*====================*/
731 ulint pass, /*!< in: pass value; != 0, if the lock will930 rw_lock_t* lock, /*!< in: pointer to rw-lock */
732 be passed to another thread to unlock */931 ulint pass, /*!< in: pass value; != 0, if the lock will
733 const char* file_name,/*!< in: file name where lock requested */932 be passed to another thread to unlock */
734 ulint line); /*!< in: line where requested */933 const char* file_name,/*!< in: file name where lock requested */
735/******************************************************************//**934 ulint line); /*!< in: line where requested */
736Performance schema instrumented wrap function for rw_lock_s_lock_func()935
737NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly936/******************************************************************//**
738this function!937Performance schema instrumented wrap function for rw_lock_s_lock_func()
739@return TRUE if success */938NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
740UNIV_INLINE939this function! */
741ibool940UNIV_INLINE
742pfs_rw_lock_s_lock_low(941void
743/*===================*/942pfs_rw_lock_s_lock_func(
744 rw_lock_t* lock, /*!< in: pointer to rw-lock */943/*====================*/
745 ulint pass, /*!< in: pass value; != 0, if the944 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
746 lock will be passed to another945 ulint pass, /*!< in: pass value; != 0, if the lock will
747 thread to unlock */946 be passed to another thread to unlock */
748 const char* file_name, /*!< in: file name where lock requested */947 const char* file_name,/*!< in: file name where lock requested */
749 ulint line); /*!< in: line where requested */948 ulint line); /*!< in: line where requested */
750/******************************************************************//**949
751Performance schema instrumented wrap function for rw_lock_x_lock_func()950/******************************************************************//**
752NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly951Performance schema instrumented wrap function for rw_lock_s_lock_func()
753this function! */952NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
754UNIV_INLINE953this function!
755void954@return TRUE if success */
756pfs_rw_lock_x_lock_func(955UNIV_INLINE
757/*====================*/956ibool
758 rw_lock_t* lock, /*!< in: pointer to rw-lock */957pfs_rw_lock_s_lock_low(
759 ulint pass, /*!< in: pass value; != 0, if the lock will958/*===================*/
760 be passed to another thread to unlock */959 rw_lock_t* lock, /*!< in: pointer to rw-lock */
761 const char* file_name,/*!< in: file name where lock requested */960 ulint pass, /*!< in: pass value; != 0, if the
762 ulint line); /*!< in: line where requested */961 lock will be passed to another
763/******************************************************************//**962 thread to unlock */
764Performance schema instrumented wrap function for rw_lock_s_unlock_func()963 const char* file_name, /*!< in: file name where lock requested */
765NOTE! Please use the corresponding macro rw_lock_s_unlock(), not directly964 ulint line); /*!< in: line where requested */
766this function! */965/******************************************************************//**
767UNIV_INLINE966Performance schema instrumented wrap function for rw_lock_s_lock_func()
768void967NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
769pfs_rw_lock_s_unlock_func(968this function!
770/*======================*/969@return TRUE if success */
771#ifdef UNIV_SYNC_DEBUG970UNIV_INLINE
772 ulint pass, /*!< in: pass value; != 0, if the971ibool
773 lock may have been passed to another972pfs_rw_lock_s_lock_low(
774 thread to unlock */973/*===================*/
775#endif974 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
776 rw_lock_t* lock); /*!< in/out: rw-lock */975 ulint pass, /*!< in: pass value; != 0, if the
777/******************************************************************//**976 lock will be passed to another
778Performance schema instrumented wrap function for rw_lock_s_unlock_func()977 thread to unlock */
779NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly978 const char* file_name, /*!< in: file name where lock requested */
780this function! */979 ulint line); /*!< in: line where requested */
781UNIV_INLINE980/******************************************************************//**
782void981Performance schema instrumented wrap function for rw_lock_x_lock_func()
783pfs_rw_lock_x_unlock_func(982NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly
784/*======================*/983this function! */
785#ifdef UNIV_SYNC_DEBUG984UNIV_INLINE
786 ulint pass, /*!< in: pass value; != 0, if the985void
787 lock may have been passed to another986pfs_rw_lock_x_lock_func(
788 thread to unlock */987/*====================*/
789#endif988 rw_lock_t* lock, /*!< in: pointer to rw-lock */
790 rw_lock_t* lock); /*!< in/out: rw-lock */989 ulint pass, /*!< in: pass value; != 0, if the lock will
990 be passed to another thread to unlock */
991 const char* file_name,/*!< in: file name where lock requested */
992 ulint line); /*!< in: line where requested */
993/******************************************************************//**
994Performance schema instrumented wrap function for rw_lock_x_lock_func()
995NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly
996this function! */
997UNIV_INLINE
998void
999pfs_rw_lock_x_lock_func(
1000/*====================*/
1001 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
1002 ulint pass, /*!< in: pass value; != 0, if the lock will
1003 be passed to another thread to unlock */
1004 const char* file_name,/*!< in: file name where lock requested */
1005 ulint line); /*!< in: line where requested */
1006/******************************************************************//**
1007Performance schema instrumented wrap function for rw_lock_s_unlock_func()
1008NOTE! Please use the corresponding macro rw_lock_s_unlock(), not directly
1009this function! */
1010UNIV_INLINE
1011void
1012pfs_rw_lock_s_unlock_func(
1013/*======================*/
1014#ifdef UNIV_SYNC_DEBUG
1015 ulint pass, /*!< in: pass value; != 0, if the
1016 lock may have been passed to another
1017 thread to unlock */
1018#endif
1019 rw_lock_t* lock); /*!< in/out: rw-lock */
1020/******************************************************************//**
1021Performance schema instrumented wrap function for rw_lock_s_unlock_func()
1022NOTE! Please use the corresponding macro rw_lock_s_unlock(), not directly
1023this function! */
1024UNIV_INLINE
1025void
1026pfs_rw_lock_s_unlock_func(
1027/*======================*/
1028#ifdef UNIV_SYNC_DEBUG
1029 ulint pass, /*!< in: pass value; != 0, if the
1030 lock may have been passed to another
1031 thread to unlock */
1032#endif
1033 prio_rw_lock_t* lock); /*!< in/out: rw-lock */
1034/******************************************************************//**
1035Performance schema instrumented wrap function for rw_lock_s_unlock_func()
1036NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly
1037this function! */
1038UNIV_INLINE
1039void
1040pfs_rw_lock_x_unlock_func(
1041/*======================*/
1042#ifdef UNIV_SYNC_DEBUG
1043 ulint pass, /*!< in: pass value; != 0, if the
1044 lock may have been passed to another
1045 thread to unlock */
1046#endif
1047 rw_lock_t* lock); /*!< in/out: rw-lock */
1048/******************************************************************//**
1049Performance schema instrumented wrap function for rw_lock_s_unlock_func()
1050NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly
1051this function! */
1052UNIV_INLINE
1053void
1054pfs_rw_lock_x_unlock_func(
1055/*======================*/
1056#ifdef UNIV_SYNC_DEBUG
1057 ulint pass, /*!< in: pass value; != 0, if the
1058 lock may have been passed to another
1059 thread to unlock */
1060#endif
1061 prio_rw_lock_t* lock); /*!< in/out: rw-lock */
791/******************************************************************//**1062/******************************************************************//**
792Performance schema instrumented wrap function for rw_lock_free_func()1063Performance schema instrumented wrap function for rw_lock_free_func()
793NOTE! Please use the corresponding macro rw_lock_free(), not directly1064NOTE! Please use the corresponding macro rw_lock_free(), not directly
@@ -797,6 +1068,15 @@
797pfs_rw_lock_free_func(1068pfs_rw_lock_free_func(
798/*==================*/1069/*==================*/
799 rw_lock_t* lock); /*!< in: rw-lock */1070 rw_lock_t* lock); /*!< in: rw-lock */
1071/******************************************************************//**
1072Performance schema instrumented wrap function for rw_lock_free_func()
1073NOTE! Please use the corresponding macro rw_lock_free(), not directly
1074this function! */
1075UNIV_INLINE
1076void
1077pfs_rw_lock_free_func(
1078/*==================*/
1079 prio_rw_lock_t* lock); /*!< in: rw-lock */
800#endif /* UNIV_PFS_RWLOCK */1080#endif /* UNIV_PFS_RWLOCK */
8011081
8021082
8031083
=== modified file 'Percona-Server/storage/innobase/include/sync0rw.ic'
--- Percona-Server/storage/innobase/include/sync0rw.ic 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/sync0rw.ic 2013-09-26 14:59:13 +0000
@@ -31,17 +31,22 @@
31*******************************************************/31*******************************************************/
3232
33/******************************************************************//**33/******************************************************************//**
34Lock an rw-lock in shared mode for the current thread. If the rw-lock is34Lock a regular or priority rw-lock in shared mode for the current thread. If
35locked in exclusive mode, or there is an exclusive lock request waiting,35the rw-lock is locked in exclusive mode, or there is an exclusive lock request
36the function spins a preset time (controlled by SYNC_SPIN_ROUNDS),36waiting, the function spins a preset time (controlled by SYNC_SPIN_ROUNDS),
37waiting for the lock before suspending the thread. */37waiting for the lock before suspending the thread. */
38UNIV_INTERN38UNIV_INTERN
39void39void
40rw_lock_s_lock_spin(40rw_lock_s_lock_spin(
41/*================*/41/*================*/
42 rw_lock_t* lock, /*!< in: pointer to rw-lock */42 void* _lock, /*!< in: pointer to rw-lock */
43 ulint pass, /*!< in: pass value; != 0, if the lock will43 ulint pass, /*!< in: pass value; != 0, if the lock will
44 be passed to another thread to unlock */44 be passed to another thread to unlock */
45 bool priority_lock,
46 /*!< in: whether the lock is a priority lock */
47 bool high_priority,
48 /*!< in: whether we are acquiring a priority
49 lock with high priority */
45 const char* file_name,/*!< in: file name where lock requested */50 const char* file_name,/*!< in: file name where lock requested */
46 ulint line); /*!< in: line where requested */51 ulint line); /*!< in: line where requested */
47#ifdef UNIV_SYNC_DEBUG52#ifdef UNIV_SYNC_DEBUG
@@ -80,6 +85,20 @@
80}85}
8186
82/********************************************************************//**87/********************************************************************//**
88Check if there are threads waiting for the priority rw-lock.
89@return 1 if waiters, 0 otherwise */
90UNIV_INLINE
91ulint
92rw_lock_get_waiters(
93/*================*/
94 const prio_rw_lock_t* lock) /*!< in: rw-lock */
95{
96 return rw_lock_get_waiters(&lock->base_lock)
97 | lock->high_priority_s_waiters
98 | lock->high_priority_x_waiters;
99}
100
101/********************************************************************//**
83Sets lock->waiters to 1. It is not an error if lock->waiters is already102Sets lock->waiters to 1. It is not an error if lock->waiters is already
841. On platforms where ATOMIC builtins are used this function enforces a1031. On platforms where ATOMIC builtins are used this function enforces a
85memory barrier. */104memory barrier. */
@@ -137,6 +156,19 @@
137}156}
138157
139/******************************************************************//**158/******************************************************************//**
159Returns the write-status of the priority lock - this function made more sense
160with the old rw_lock implementation.
161@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
162UNIV_INLINE
163ulint
164rw_lock_get_writer(
165/*===============*/
166 const prio_rw_lock_t* lock) /*!< in: rw-lock */
167{
168 return(rw_lock_get_writer(&lock->base_lock));
169}
170
171/******************************************************************//**
140Returns the number of readers.172Returns the number of readers.
141@return number of readers */173@return number of readers */
142UNIV_INLINE174UNIV_INLINE
@@ -156,6 +188,18 @@
156 return(0);188 return(0);
157}189}
158190
191/******************************************************************//**
192Returns the number of readers.
193@return number of readers */
194UNIV_INLINE
195ulint
196rw_lock_get_reader_count(
197/*=====================*/
198 const prio_rw_lock_t* lock) /*!< in: rw-lock */
199{
200 return(rw_lock_get_reader_count(&lock->base_lock));
201}
202
159#ifndef INNODB_RW_LOCKS_USE_ATOMICS203#ifndef INNODB_RW_LOCKS_USE_ATOMICS
160UNIV_INLINE204UNIV_INLINE
161ib_mutex_t*205ib_mutex_t*
@@ -185,6 +229,19 @@
185}229}
186230
187/******************************************************************//**231/******************************************************************//**
232Returns the value of writer_count for the priority lock. Does not reserve the
233lock mutex, so the caller must be sure it is not changed during the call.
234@return value of writer_count */
235UNIV_INLINE
236ulint
237rw_lock_get_x_lock_count(
238/*=====================*/
239 const prio_rw_lock_t* lock) /*!< in: rw-lock */
240{
241 return(rw_lock_get_x_lock_count(&lock->base_lock));
242}
243
244/******************************************************************//**
188Two different implementations for decrementing the lock_word of a rw_lock:245Two different implementations for decrementing the lock_word of a rw_lock:
189one for systems supporting atomic operations, one for others. This does246one for systems supporting atomic operations, one for others. This does
190does not support recusive x-locks: they should be handled by the caller and247does not support recusive x-locks: they should be handled by the caller and
@@ -361,7 +418,75 @@
361 } else {418 } else {
362 /* Did not succeed, try spin wait */419 /* Did not succeed, try spin wait */
363420
364 rw_lock_s_lock_spin(lock, pass, file_name, line);421 rw_lock_s_lock_spin(lock, pass, false, false, file_name, line);
422
423 return;
424 }
425}
426
427/******************************************************************//**
428Return true if waiters of higher priority than the current thread
429exist.
430@true if waiterss of higher priority exist */
431UNIV_INLINE
432bool
433rw_lock_higher_prio_waiters_exist(
434/*==============================*/
435 bool priority_lock, /*!< in: whether the lock is a priority lock */
436 bool high_priority, /*!< in: whether we are acquiring a priority
437 lock with high priority */
438 void* lock) /*!< in: rw lock */
439{
440 if (high_priority || !priority_lock) {
441 ut_ad(!(!priority_lock && high_priority));
442 return(false);
443 }
444
445 ut_ad(priority_lock && !high_priority);
446
447 prio_rw_lock_t *prio_rw_lock = (prio_rw_lock_t *) lock;
448 return prio_rw_lock->high_priority_wait_ex_waiter > 0
449 || prio_rw_lock->high_priority_s_waiters > 0
450 || prio_rw_lock->high_priority_x_waiters > 0;
451}
452
453/******************************************************************//**
454NOTE! Use the corresponding macro, not directly this function, except if
455you supply the file name and line number. Lock a priority rw-lock in shared
456mode for the current thread, using the relative thread priority. If the
457rw-lock is locked in exclusive mode, or there is an exclusive lock request
458waiting, the function spins a preset time (controlled by SYNC_SPIN_ROUNDS),
459waiting for the lock, before suspending the thread. */
460UNIV_INLINE
461void
462rw_lock_s_lock_func(
463/*================*/
464 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
465 ulint pass, /*!< in: pass value; != 0, if the lock will
466 be passed to another thread to unlock */
467 const char* file_name,/*!< in: file name where lock requested */
468 ulint line) /*!< in: line where requested */
469{
470#ifdef UNIV_SYNC_DEBUG
471 ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */
472 ut_ad(!rw_lock_own(lock, RW_LOCK_EX));
473#endif /* UNIV_SYNC_DEBUG */
474
475 bool high_priority = srv_current_thread_priority > 0;
476
477 /* Do not attempt to acquire a low-priority S latch if there are
478 high-priority waiters even if such attempt would be successful. This
479 is to prevent a high priority X request from being starved by a
480 sequence of overlapping regular priority S requests. */
481
482 if (!rw_lock_higher_prio_waiters_exist(true, high_priority, lock)
483 && rw_lock_s_lock_low(&lock->base_lock, pass, file_name, line)) {
484
485 return; /* Success */
486 } else {
487 /* Did not succeed, try spin wait */
488 rw_lock_s_lock_spin(lock, pass, true, high_priority, file_name,
489 line);
365490
366 return;491 return;
367 }492 }
@@ -380,8 +505,6 @@
380 const char* file_name,/*!< in: file name where lock requested */505 const char* file_name,/*!< in: file name where lock requested */
381 ulint line) /*!< in: line where requested */506 ulint line) /*!< in: line where requested */
382{507{
383 os_thread_id_t curr_thread = os_thread_get_curr_id();
384
385 ibool success;508 ibool success;
386509
387#ifdef INNODB_RW_LOCKS_USE_ATOMICS510#ifdef INNODB_RW_LOCKS_USE_ATOMICS
@@ -401,7 +524,8 @@
401 rw_lock_set_writer_id_and_recursion_flag(lock, TRUE);524 rw_lock_set_writer_id_and_recursion_flag(lock, TRUE);
402525
403 } else if (lock->recursive526 } else if (lock->recursive
404 && os_thread_eq(lock->writer_thread, curr_thread)) {527 && os_thread_eq(lock->writer_thread,
528 os_thread_get_curr_id())) {
405 /* Relock: this lock_word modification is safe since no other529 /* Relock: this lock_word modification is safe since no other
406 threads can modify (lock, unlock, or reserve) lock_word while530 threads can modify (lock, unlock, or reserve) lock_word while
407 there is an exclusive writer and this is the writer thread. */531 there is an exclusive writer and this is the writer thread. */
@@ -469,13 +593,75 @@
469}593}
470594
471/******************************************************************//**595/******************************************************************//**
472Releases an exclusive mode lock. */596Releases a shared mode priority lock. */
473UNIV_INLINE597UNIV_INLINE
474void598void
475rw_lock_x_unlock_func(599rw_lock_s_unlock_func(
476/*==================*/600/*==================*/
477#ifdef UNIV_SYNC_DEBUG601#ifdef UNIV_SYNC_DEBUG
478 ulint pass, /*!< in: pass value; != 0, if the lock may have602 ulint pass, /*!< in: pass value; != 0, if the lock may have
603 been passed to another thread to unlock */
604#endif
605 prio_rw_lock_t* lock) /*!< in/out: rw-lock */
606{
607 ut_ad(lock->base_lock.lock_word > -X_LOCK_DECR);
608 ut_ad(lock->base_lock.lock_word != 0);
609 ut_ad(lock->base_lock.lock_word < X_LOCK_DECR);
610
611#ifdef UNIV_SYNC_DEBUG
612 rw_lock_remove_debug_info(&lock->base_lock, pass, RW_LOCK_SHARED);
613#endif
614
615 /* Increment lock_word to indicate 1 less reader */
616 if (rw_lock_lock_word_incr(&lock->base_lock, 1) == 0) {
617
618 /* A waiting next-writer exists, either high priority or
619 regular. Wake up the first waiter in this order: 1) high
620 priority next-writer; 2) high priority X waiters; 3) high
621 priority S waiters; 4) regular priority next-waiter. This
622 allows high priority requests to overtake an already-waiting
623 regular priority next-waiter. */
624 if (lock->high_priority_wait_ex_waiter) {
625
626 lock->high_priority_wait_ex_waiter = 0;
627 /* Note that we do not have a separate high priority
628 next-waiter event. There can be only one such waiter,
629 here we already know it's high priority, no
630 regular-priority wakeup may happen. */
631 os_event_set(lock->base_lock.wait_ex_event);
632 } else if (lock->high_priority_x_waiters) {
633
634 lock->high_priority_x_waiters = 0;
635 os_event_set(lock->high_priority_x_event);
636 } else if (lock->high_priority_s_waiters) {
637
638 lock->high_priority_s_waiters = 0;
639 os_event_set(lock->high_priority_s_event);
640 } else {
641
642 os_event_set(lock->base_lock.wait_ex_event);
643 }
644 sync_array_object_signalled();
645 }
646
647 ut_ad(rw_lock_validate(lock));
648
649#ifdef UNIV_SYNC_PERF_STAT
650 rw_s_exit_count++;
651#endif
652}
653
654/******************************************************************//**
655Prepares an exclusive mode lock release: resets the recursion flag and removes
656the debug information if needed and returns the required lock word increment
657value.
658@return lock word increment value to perform the unlock */
659UNIV_INLINE
660ulint
661rw_lock_x_prepare_unlock(
662/*=====================*/
663#ifdef UNIV_SYNC_DEBUG
664 ulint pass, /*!< in: pass value; != 0, if the lock may have
479 been passed to another thread to unlock */665 been passed to another thread to unlock */
480#endif666#endif
481 rw_lock_t* lock) /*!< in/out: rw-lock */667 rw_lock_t* lock) /*!< in/out: rw-lock */
@@ -507,10 +693,32 @@
507 x_lock_incr = 1;693 x_lock_incr = 1;
508 }694 }
509695
696 return(x_lock_incr);
697}
698
699/******************************************************************//**
700Releases an exclusive mode lock. */
701UNIV_INLINE
702void
703rw_lock_x_unlock_func(
704/*==================*/
705#ifdef UNIV_SYNC_DEBUG
706 ulint pass, /*!< in: pass value; != 0, if the lock may have
707 been passed to another thread to unlock */
708#endif
709 rw_lock_t* lock) /*!< in/out: rw-lock */
710{
711 ulint x_lock_incr = rw_lock_x_prepare_unlock(
712#ifdef UNIV_SYNC_DEBUG
713 pass,
714#endif
715 lock);
716
510 if (rw_lock_lock_word_incr(lock, x_lock_incr) == X_LOCK_DECR) {717 if (rw_lock_lock_word_incr(lock, x_lock_incr) == X_LOCK_DECR) {
511 /* Lock is now free. May have to signal read/write waiters.718 /* Lock is now free. May have to signal read/write waiters.
512 We do not need to signal wait_ex waiters, since they cannot719 We do not need to signal wait_ex waiters, since they cannot
513 exist when there is a writer. */720 exist when there is a writer. */
721
514 if (lock->waiters) {722 if (lock->waiters) {
515 rw_lock_reset_waiter_flag(lock);723 rw_lock_reset_waiter_flag(lock);
516 os_event_set(lock->event);724 os_event_set(lock->event);
@@ -525,6 +733,58 @@
525#endif733#endif
526}734}
527735
736/******************************************************************//**
737Releases an exclusive mode priority lock. */
738UNIV_INLINE
739void
740rw_lock_x_unlock_func(
741/*==================*/
742#ifdef UNIV_SYNC_DEBUG
743 ulint pass, /*!< in: pass value; != 0, if the lock may have
744 been passed to another thread to unlock */
745#endif
746 prio_rw_lock_t* lock) /*!< in/out: rw-lock */
747{
748 ulint x_lock_incr = rw_lock_x_prepare_unlock(
749#ifdef UNIV_SYNC_DEBUG
750 pass,
751#endif
752 &lock->base_lock);
753
754 if (rw_lock_lock_word_incr(&lock->base_lock, x_lock_incr)
755 == X_LOCK_DECR) {
756
757 /* Priority lock is now free. Signal any waiters in this
758 order: 1) high priority X waiters; 2) high priority S waiters;
759 3) regular priority waiters.
760 We do not need to signal wait_ex waiters, since they cannot
761 exist when there is a writer. */
762
763 if (lock->high_priority_x_waiters) {
764
765 lock->high_priority_x_waiters = 0;
766 os_event_set(lock->high_priority_x_event);
767 sync_array_object_signalled();
768 } else if (lock->high_priority_s_waiters) {
769
770 lock->high_priority_s_waiters = 0;
771 os_event_set(lock->high_priority_s_event);
772 sync_array_object_signalled();
773 } else if (lock->base_lock.waiters) {
774
775 rw_lock_reset_waiter_flag(&lock->base_lock);
776 os_event_set(lock->base_lock.event);
777 sync_array_object_signalled();
778 }
779 }
780
781 ut_ad(rw_lock_validate(lock));
782
783#ifdef UNIV_SYNC_PERF_STAT
784 rw_x_exit_count++;
785#endif
786}
787
528#ifdef UNIV_PFS_RWLOCK788#ifdef UNIV_PFS_RWLOCK
529789
530/******************************************************************//**790/******************************************************************//**
@@ -561,6 +821,42 @@
561# endif /* UNIV_DEBUG */821# endif /* UNIV_DEBUG */
562 cmutex_name);822 cmutex_name);
563}823}
824
825/******************************************************************//**
826Performance schema instrumented wrap function for rw_lock_create_func().
827NOTE! Please use the corresponding macro rw_lock_create(), not directly
828this function! */
829UNIV_INLINE
830void
831pfs_rw_lock_create_func(
832/*====================*/
833 mysql_pfs_key_t key, /*!< in: key registered with
834 performance schema */
835 prio_rw_lock_t* lock, /*!< in: pointer to memory */
836# ifdef UNIV_DEBUG
837# ifdef UNIV_SYNC_DEBUG
838 ulint level, /*!< in: level */
839# endif /* UNIV_SYNC_DEBUG */
840 const char* cfile_name, /*!< in: file name where created */
841 ulint cline, /*!< in: file line where created */
842# endif /* UNIV_DEBUG */
843 const char* cmutex_name) /*!< in: mutex name */
844{
845 /* Initialize the rwlock for performance schema */
846 lock->base_lock.pfs_psi = PSI_RWLOCK_CALL(init_rwlock)(key, lock);
847
848 /* The actual function to initialize an rwlock */
849 rw_lock_create_func(lock,
850# ifdef UNIV_DEBUG
851# ifdef UNIV_SYNC_DEBUG
852 level,
853# endif /* UNIV_SYNC_DEBUG */
854 cfile_name,
855 cline,
856# endif /* UNIV_DEBUG */
857 cmutex_name);
858}
859
564/******************************************************************//**860/******************************************************************//**
565Performance schema instrumented wrap function for rw_lock_x_lock_func()861Performance schema instrumented wrap function for rw_lock_x_lock_func()
566NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly862NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly
@@ -594,6 +890,42 @@
594 rw_lock_x_lock_func(lock, pass, file_name, line);890 rw_lock_x_lock_func(lock, pass, file_name, line);
595 }891 }
596}892}
893
894/******************************************************************//**
895Performance schema instrumented wrap function for rw_lock_x_lock_func()
896NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly
897this function! */
898UNIV_INLINE
899void
900pfs_rw_lock_x_lock_func(
901/*====================*/
902 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
903 ulint pass, /*!< in: pass value; != 0, if the lock will
904 be passed to another thread to unlock */
905 const char* file_name,/*!< in: file name where lock requested */
906 ulint line) /*!< in: line where requested */
907{
908 if (lock->base_lock.pfs_psi != NULL)
909 {
910 PSI_rwlock_locker* locker;
911 PSI_rwlock_locker_state state;
912
913 /* Record the entry of rw x lock request in performance schema */
914 locker = PSI_RWLOCK_CALL(start_rwlock_wrwait)(
915 &state, lock->base_lock.pfs_psi, PSI_RWLOCK_WRITELOCK,
916 file_name, line);
917
918 rw_lock_x_lock_func(lock, pass, file_name, line);
919
920 if (locker != NULL)
921 PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, 0);
922 }
923 else
924 {
925 rw_lock_x_lock_func(lock, pass, file_name, line);
926 }
927}
928
597/******************************************************************//**929/******************************************************************//**
598Performance schema instrumented wrap function for930Performance schema instrumented wrap function for
599rw_lock_x_lock_func_nowait()931rw_lock_x_lock_func_nowait()
@@ -650,6 +982,26 @@
650982
651 rw_lock_free_func(lock);983 rw_lock_free_func(lock);
652}984}
985
986/******************************************************************//**
987Performance schema instrumented wrap function for rw_lock_free_func()
988NOTE! Please use the corresponding macro rw_lock_free(), not directly
989this function! */
990UNIV_INLINE
991void
992pfs_rw_lock_free_func(
993/*==================*/
994 prio_rw_lock_t* lock) /*!< in: pointer to rw-lock */
995{
996 if (lock->base_lock.pfs_psi != NULL)
997 {
998 PSI_RWLOCK_CALL(destroy_rwlock)(lock->base_lock.pfs_psi);
999 lock->base_lock.pfs_psi = NULL;
1000 }
1001
1002 rw_lock_free_func(lock);
1003}
1004
653/******************************************************************//**1005/******************************************************************//**
654Performance schema instrumented wrap function for rw_lock_s_lock_func()1006Performance schema instrumented wrap function for rw_lock_s_lock_func()
655NOTE! Please use the corresponding macro rw_lock_s_lock(), not1007NOTE! Please use the corresponding macro rw_lock_s_lock(), not
@@ -687,6 +1039,46 @@
6871039
688 return;1040 return;
689}1041}
1042
1043/******************************************************************//**
1044Performance schema instrumented wrap function for rw_lock_s_lock_func()
1045NOTE! Please use the corresponding macro rw_lock_s_lock(), not
1046directly this function! */
1047UNIV_INLINE
1048void
1049pfs_rw_lock_s_lock_func(
1050/*====================*/
1051 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
1052 ulint pass, /*!< in: pass value; != 0, if the
1053 lock will be passed to another
1054 thread to unlock */
1055 const char* file_name,/*!< in: file name where lock
1056 requested */
1057 ulint line) /*!< in: line where requested */
1058{
1059 if (lock->base_lock.pfs_psi != NULL)
1060 {
1061 PSI_rwlock_locker* locker;
1062 PSI_rwlock_locker_state state;
1063
1064 /* Instrumented to inform we are aquiring a shared rwlock */
1065 locker = PSI_RWLOCK_CALL(start_rwlock_rdwait)(
1066 &state, lock->base_lock.pfs_psi, PSI_RWLOCK_READLOCK,
1067 file_name, line);
1068
1069 rw_lock_s_lock_func(lock, pass, file_name, line);
1070
1071 if (locker != NULL)
1072 PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, 0);
1073 }
1074 else
1075 {
1076 rw_lock_s_lock_func(lock, pass, file_name, line);
1077 }
1078
1079 return;
1080}
1081
690/******************************************************************//**1082/******************************************************************//**
691Performance schema instrumented wrap function for rw_lock_s_lock_func()1083Performance schema instrumented wrap function for rw_lock_s_lock_func()
692NOTE! Please use the corresponding macro rw_lock_s_lock(), not1084NOTE! Please use the corresponding macro rw_lock_s_lock(), not
@@ -728,55 +1120,129 @@
728}1120}
7291121
730/******************************************************************//**1122/******************************************************************//**
731Performance schema instrumented wrap function for rw_lock_x_unlock_func()1123Performance schema instrumented wrap function for rw_lock_s_lock_func()
732NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly1124NOTE! Please use the corresponding macro rw_lock_s_lock(), not
733this function! */1125directly this function!
734UNIV_INLINE1126@return TRUE if success */
735void1127UNIV_INLINE
736pfs_rw_lock_x_unlock_func(1128ibool
737/*======================*/1129pfs_rw_lock_s_lock_low(
738#ifdef UNIV_SYNC_DEBUG1130/*===================*/
739 ulint pass, /*!< in: pass value; != 0, if the1131 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
740 lock may have been passed to another1132 ulint pass, /*!< in: pass value; != 0, if the
741 thread to unlock */1133 lock will be passed to another
742#endif1134 thread to unlock */
743 rw_lock_t* lock) /*!< in/out: rw-lock */1135 const char* file_name, /*!< in: file name where lock requested */
744{1136 ulint line) /*!< in: line where requested */
745 /* Inform performance schema we are unlocking the lock */1137{
746 if (lock->pfs_psi != NULL)1138 return(pfs_rw_lock_s_lock_low(&lock->base_lock, pass,
747 PSI_RWLOCK_CALL(unlock_rwlock)(lock->pfs_psi);1139 file_name, line));
7481140}
749 rw_lock_x_unlock_func(1141
750#ifdef UNIV_SYNC_DEBUG1142/******************************************************************//**
751 pass,1143Performance schema instrumented wrap function for rw_lock_x_unlock_func()
752#endif1144NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly
753 lock);1145this function! */
754}1146UNIV_INLINE
7551147void
756/******************************************************************//**1148pfs_rw_lock_x_unlock_func(
757Performance schema instrumented wrap function for rw_lock_s_unlock_func()1149/*======================*/
758NOTE! Please use the corresponding macro pfs_rw_lock_s_unlock(), not1150#ifdef UNIV_SYNC_DEBUG
759directly this function! */1151 ulint pass, /*!< in: pass value; != 0, if the
760UNIV_INLINE1152 lock may have been passed to another
761void1153 thread to unlock */
762pfs_rw_lock_s_unlock_func(1154#endif
763/*======================*/1155 rw_lock_t* lock) /*!< in/out: rw-lock */
764#ifdef UNIV_SYNC_DEBUG1156{
765 ulint pass, /*!< in: pass value; != 0, if the1157 /* Inform performance schema we are unlocking the lock */
766 lock may have been passed to another1158 if (lock->pfs_psi != NULL)
767 thread to unlock */1159 PSI_RWLOCK_CALL(unlock_rwlock)(lock->pfs_psi);
768#endif1160
769 rw_lock_t* lock) /*!< in/out: rw-lock */1161 rw_lock_x_unlock_func(
770{1162#ifdef UNIV_SYNC_DEBUG
771 /* Inform performance schema we are unlocking the lock */1163 pass,
772 if (lock->pfs_psi != NULL)1164#endif
773 PSI_RWLOCK_CALL(unlock_rwlock)(lock->pfs_psi);1165 lock);
7741166}
775 rw_lock_s_unlock_func(1167
776#ifdef UNIV_SYNC_DEBUG1168/******************************************************************//**
777 pass,1169Performance schema instrumented wrap function for rw_lock_x_unlock_func()
778#endif1170NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly
779 lock);1171this function! */
7801172UNIV_INLINE
781}1173void
1174pfs_rw_lock_x_unlock_func(
1175/*======================*/
1176#ifdef UNIV_SYNC_DEBUG
1177 ulint pass, /*!< in: pass value; != 0, if the
1178 lock may have been passed to another
1179 thread to unlock */
1180#endif
1181 prio_rw_lock_t* lock) /*!< in/out: rw-lock */
1182{
1183 /* Inform performance schema we are unlocking the lock */
1184 if (lock->base_lock.pfs_psi != NULL)
1185 PSI_RWLOCK_CALL(unlock_rwlock)(lock->base_lock.pfs_psi);
1186
1187 rw_lock_x_unlock_func(
1188#ifdef UNIV_SYNC_DEBUG
1189 pass,
1190#endif
1191 lock);
1192}
1193
1194/******************************************************************//**
1195Performance schema instrumented wrap function for rw_lock_s_unlock_func()
1196NOTE! Please use the corresponding macro pfs_rw_lock_s_unlock(), not
1197directly this function! */
1198UNIV_INLINE
1199void
1200pfs_rw_lock_s_unlock_func(
1201/*======================*/
1202#ifdef UNIV_SYNC_DEBUG
1203 ulint pass, /*!< in: pass value; != 0, if the
1204 lock may have been passed to another
1205 thread to unlock */
1206#endif
1207 rw_lock_t* lock) /*!< in/out: rw-lock */
1208{
1209 /* Inform performance schema we are unlocking the lock */
1210 if (lock->pfs_psi != NULL)
1211 PSI_RWLOCK_CALL(unlock_rwlock)(lock->pfs_psi);
1212
1213 rw_lock_s_unlock_func(
1214#ifdef UNIV_SYNC_DEBUG
1215 pass,
1216#endif
1217 lock);
1218
1219}
1220
1221/******************************************************************//**
1222Performance schema instrumented wrap function for rw_lock_s_unlock_func()
1223NOTE! Please use the corresponding macro pfs_rw_lock_s_unlock(), not
1224directly this function! */
1225UNIV_INLINE
1226void
1227pfs_rw_lock_s_unlock_func(
1228/*======================*/
1229#ifdef UNIV_SYNC_DEBUG
1230 ulint pass, /*!< in: pass value; != 0, if the
1231 lock may have been passed to another
1232 thread to unlock */
1233#endif
1234 prio_rw_lock_t* lock) /*!< in/out: rw-lock */
1235{
1236 /* Inform performance schema we are unlocking the lock */
1237 if (lock->base_lock.pfs_psi != NULL)
1238 PSI_RWLOCK_CALL(unlock_rwlock)(lock->base_lock.pfs_psi);
1239
1240 rw_lock_s_unlock_func(
1241#ifdef UNIV_SYNC_DEBUG
1242 pass,
1243#endif
1244 lock);
1245
1246}
1247
782#endif /* UNIV_PFS_RWLOCK */1248#endif /* UNIV_PFS_RWLOCK */
7831249
=== modified file 'Percona-Server/storage/innobase/include/sync0sync.h'
--- Percona-Server/storage/innobase/include/sync0sync.h 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/include/sync0sync.h 2013-09-26 14:59:13 +0000
@@ -160,6 +160,8 @@
160160
161mutex_create161mutex_create
162mutex_enter162mutex_enter
163mutex_enter_first
164mutex_enter_last
163mutex_exit165mutex_exit
164mutex_enter_nowait166mutex_enter_nowait
165mutex_free167mutex_free
@@ -195,6 +197,12 @@
195# define mutex_enter_nowait(M) \197# define mutex_enter_nowait(M) \
196 pfs_mutex_enter_nowait_func((M), __FILE__, __LINE__)198 pfs_mutex_enter_nowait_func((M), __FILE__, __LINE__)
197199
200# define mutex_enter_first(M) \
201 pfs_mutex_enter_func((M), __FILE__, __LINE__, HIGH_PRIO)
202
203# define mutex_enter_last(M) \
204 pfs_mutex_enter_func((M), __FILE__, __LINE__, LOW_PRIO)
205
198# define mutex_exit(M) pfs_mutex_exit_func(M)206# define mutex_exit(M) pfs_mutex_exit_func(M)
199207
200# define mutex_free(M) pfs_mutex_free_func(M)208# define mutex_free(M) pfs_mutex_free_func(M)
@@ -221,6 +229,12 @@
221# define mutex_enter_nowait(M) \229# define mutex_enter_nowait(M) \
222 mutex_enter_nowait_func((M), __FILE__, __LINE__)230 mutex_enter_nowait_func((M), __FILE__, __LINE__)
223231
232# define mutex_enter_first(M) \
233 mutex_enter_func((M), __FILE__, __LINE__, HIGH_PRIO)
234
235# define mutex_enter_last(M) \
236 mutex_enter_func((M), __FILE__, __LINE__, LOW_PRIO)
237
224# define mutex_exit(M) mutex_exit_func(M)238# define mutex_exit(M) mutex_exit_func(M)
225239
226# define mutex_free(M) mutex_free_func(M)240# define mutex_free(M) mutex_free_func(M)
@@ -247,6 +261,26 @@
247 const char* cmutex_name); /*!< in: mutex name */261 const char* cmutex_name); /*!< in: mutex name */
248262
249/******************************************************************//**263/******************************************************************//**
264Creates, or rather, initializes a priority mutex object in a specified memory
265location (which must be appropriately aligned). The mutex is initialized
266in the reset state. Explicit freeing of the mutex with mutex_free is
267necessary only if the memory block containing it is freed. */
268UNIV_INTERN
269void
270mutex_create_func(
271/*==============*/
272 ib_prio_mutex_t* mutex, /*!< in: pointer to memory */
273#ifdef UNIV_DEBUG
274# ifdef UNIV_SYNC_DEBUG
275 ulint level, /*!< in: level */
276# endif /* UNIV_SYNC_DEBUG */
277 const char* cfile_name, /*!< in: file name where
278 created */
279 ulint cline, /*!< in: file line where
280 created */
281#endif /* UNIV_DEBUG */
282 const char* cmutex_name); /*!< in: mutex name */
283/******************************************************************//**
250NOTE! Use the corresponding macro mutex_free(), not directly this function!284NOTE! Use the corresponding macro mutex_free(), not directly this function!
251Calling this function is obligatory only if the memory buffer containing285Calling this function is obligatory only if the memory buffer containing
252the mutex is freed. Removes a mutex object from the mutex list. The mutex286the mutex is freed. Removes a mutex object from the mutex list. The mutex
@@ -256,6 +290,16 @@
256mutex_free_func(290mutex_free_func(
257/*============*/291/*============*/
258 ib_mutex_t* mutex); /*!< in: mutex */292 ib_mutex_t* mutex); /*!< in: mutex */
293/******************************************************************//**
294NOTE! Use the corresponding macro mutex_free(), not directly this function!
295Calling this function is obligatory only if the memory buffer containing
296the mutex is freed. Removes a priority mutex object from the mutex list. The
297mutex is checked to be in the reset state. */
298UNIV_INTERN
299void
300mutex_free_func(
301/*============*/
302 ib_prio_mutex_t* mutex); /*!< in: mutex */
259/**************************************************************//**303/**************************************************************//**
260NOTE! The following macro should be used in mutex locking, not the304NOTE! The following macro should be used in mutex locking, not the
261corresponding function. */305corresponding function. */
@@ -275,6 +319,26 @@
275 ib_mutex_t* mutex, /*!< in: pointer to mutex */319 ib_mutex_t* mutex, /*!< in: pointer to mutex */
276 const char* file_name, /*!< in: file name where locked */320 const char* file_name, /*!< in: file name where locked */
277 ulint line); /*!< in: line where locked */321 ulint line); /*!< in: line where locked */
322/******************************************************************//**
323NOTE! Use the corresponding macro in the header file, not this function
324directly. Locks a priority mutex for the current thread. If the mutex is
325reserved the function spins a preset time (controlled by SYNC_SPIN_ROUNDS)
326waiting for the mutex before suspending the thread. If the thread is suspended,
327the priority argument value determines the relative order for its wake up. Any
328HIGH_PRIO waiters will be woken up before any LOW_PRIO waiters. In case of
329DEFAULT_PRIO, the relative priority will be set according to
330srv_current_thread_priority. */
331UNIV_INLINE
332void
333mutex_enter_func(
334/*=============*/
335 ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */
336 const char* file_name, /*!< in: file name where
337 locked */
338 ulint line, /*!< in: line where locked */
339 enum ib_sync_priority priority = DEFAULT_PRIO);
340 /*!<in: mutex acquisition
341 priority */
278/********************************************************************//**342/********************************************************************//**
279NOTE! Use the corresponding macro in the header file, not this function343NOTE! Use the corresponding macro in the header file, not this function
280directly. Tries to lock the mutex for the current thread. If the lock is not344directly. Tries to lock the mutex for the current thread. If the lock is not
@@ -288,6 +352,20 @@
288 const char* file_name, /*!< in: file name where mutex352 const char* file_name, /*!< in: file name where mutex
289 requested */353 requested */
290 ulint line); /*!< in: line where requested */354 ulint line); /*!< in: line where requested */
355/********************************************************************//**
356NOTE! Use the corresponding macro in the header file, not this function
357directly. Tries to lock the mutex for the current thread. If the lock is not
358acquired immediately, returns with return value 1.
359@return 0 if succeed, 1 if not */
360UNIV_INTERN
361ulint
362mutex_enter_nowait_func(
363/*====================*/
364 ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */
365 const char* file_name, /*!< in: file name where mutex
366 requested */
367 ulint line); /*!< in: line where
368 requested */
291/******************************************************************//**369/******************************************************************//**
292NOTE! Use the corresponding macro mutex_exit(), not directly this function!370NOTE! Use the corresponding macro mutex_exit(), not directly this function!
293Unlocks a mutex owned by the current thread. */371Unlocks a mutex owned by the current thread. */
@@ -296,6 +374,14 @@
296mutex_exit_func(374mutex_exit_func(
297/*============*/375/*============*/
298 ib_mutex_t* mutex); /*!< in: pointer to mutex */376 ib_mutex_t* mutex); /*!< in: pointer to mutex */
377/******************************************************************//**
378NOTE! Use the corresponding macro mutex_exit(), not directly this function!
379Unlocks a priority mutex owned by the current thread. */
380UNIV_INLINE
381void
382mutex_exit_func(
383/*============*/
384 ib_prio_mutex_t* mutex); /*!< in: pointer to mutex */
299385
300386
301#ifdef UNIV_PFS_MUTEX387#ifdef UNIV_PFS_MUTEX
@@ -320,6 +406,29 @@
320# endif /* UNIV_DEBUG */406# endif /* UNIV_DEBUG */
321 const char* cmutex_name);407 const char* cmutex_name);
322/******************************************************************//**408/******************************************************************//**
409NOTE! Please use the corresponding macro mutex_create(), not directly
410this function!
411A wrapper function for mutex_create_func(), registers the mutex
412with peformance schema if "UNIV_PFS_MUTEX" is defined when
413creating the performance mutex */
414UNIV_INLINE
415void
416pfs_mutex_create_func(
417/*==================*/
418 PSI_mutex_key key, /*!< in: Performance Schema
419 key */
420 ib_prio_mutex_t* mutex, /*!< in: pointer to memory */
421# ifdef UNIV_DEBUG
422# ifdef UNIV_SYNC_DEBUG
423 ulint level, /*!< in: level */
424# endif /* UNIV_SYNC_DEBUG */
425 const char* cfile_name, /*!< in: file name where
426 created */
427 ulint cline, /*!< in: file line where
428 created */
429# endif /* UNIV_DEBUG */
430 const char* cmutex_name);
431/******************************************************************//**
323NOTE! Please use the corresponding macro mutex_enter(), not directly432NOTE! Please use the corresponding macro mutex_enter(), not directly
324this function!433this function!
325This is a performance schema instrumented wrapper function for434This is a performance schema instrumented wrapper function for
@@ -331,6 +440,22 @@
331 ib_mutex_t* mutex, /*!< in: pointer to mutex */440 ib_mutex_t* mutex, /*!< in: pointer to mutex */
332 const char* file_name, /*!< in: file name where locked */441 const char* file_name, /*!< in: file name where locked */
333 ulint line); /*!< in: line where locked */442 ulint line); /*!< in: line where locked */
443/******************************************************************//**
444NOTE! Please use the corresponding macro mutex_enter(), not directly
445this function!
446This is a performance schema instrumented wrapper function for
447mutex_enter_func(). */
448UNIV_INLINE
449void
450pfs_mutex_enter_func(
451/*=================*/
452 ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */
453 const char* file_name, /*!< in: file name where
454 locked */
455 ulint line, /*!< in: line where locked */
456 enum ib_sync_priority priority = DEFAULT_PRIO);
457 /*!<in: mutex acquisition
458 priority */
334/********************************************************************//**459/********************************************************************//**
335NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly460NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly
336this function!461this function!
@@ -345,6 +470,21 @@
345 const char* file_name, /*!< in: file name where mutex470 const char* file_name, /*!< in: file name where mutex
346 requested */471 requested */
347 ulint line); /*!< in: line where requested */472 ulint line); /*!< in: line where requested */
473/********************************************************************//**
474NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly
475this function!
476This is a performance schema instrumented wrapper function for
477mutex_enter_nowait_func.
478@return 0 if succeed, 1 if not */
479UNIV_INLINE
480ulint
481pfs_mutex_enter_nowait_func(
482/*========================*/
483 ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */
484 const char* file_name, /*!< in: file name where mutex
485 requested */
486 ulint line); /*!< in: line where
487 requested */
348/******************************************************************//**488/******************************************************************//**
349NOTE! Please use the corresponding macro mutex_exit(), not directly489NOTE! Please use the corresponding macro mutex_exit(), not directly
350this function!490this function!
@@ -355,6 +495,16 @@
355pfs_mutex_exit_func(495pfs_mutex_exit_func(
356/*================*/496/*================*/
357 ib_mutex_t* mutex); /*!< in: pointer to mutex */497 ib_mutex_t* mutex); /*!< in: pointer to mutex */
498/******************************************************************//**
499NOTE! Please use the corresponding macro mutex_exit(), not directly
500this function!
501A wrap function of mutex_exit_func() with peformance schema instrumentation.
502Unlocks a priority mutex owned by the current thread. */
503UNIV_INLINE
504void
505pfs_mutex_exit_func(
506/*================*/
507 ib_prio_mutex_t* mutex); /*!< in: pointer to mutex */
358508
359/******************************************************************//**509/******************************************************************//**
360NOTE! Please use the corresponding macro mutex_free(), not directly510NOTE! Please use the corresponding macro mutex_free(), not directly
@@ -366,6 +516,16 @@
366pfs_mutex_free_func(516pfs_mutex_free_func(
367/*================*/517/*================*/
368 ib_mutex_t* mutex); /*!< in: mutex */518 ib_mutex_t* mutex); /*!< in: mutex */
519/******************************************************************//**
520NOTE! Please use the corresponding macro mutex_free(), not directly
521this function!
522Wrapper function for mutex_free_func(). Also destroys the performance
523schema probes when freeing the priority mutex */
524UNIV_INLINE
525void
526pfs_mutex_free_func(
527/*================*/
528 ib_prio_mutex_t* mutex); /*!< in: mutex */
369529
370#endif /* UNIV_PFS_MUTEX */530#endif /* UNIV_PFS_MUTEX */
371531
@@ -414,6 +574,16 @@
414/*======*/574/*======*/
415 const ib_mutex_t* mutex) /*!< in: mutex */575 const ib_mutex_t* mutex) /*!< in: mutex */
416 __attribute__((warn_unused_result));576 __attribute__((warn_unused_result));
577/******************************************************************//**
578Checks that the current thread owns the priority mutex. Works only
579in the debug version.
580@return TRUE if owns */
581UNIV_INTERN
582ibool
583mutex_own(
584/*======*/
585 const ib_prio_mutex_t* mutex) /*!< in: priority mutex */
586 __attribute__((warn_unused_result));
417#endif /* UNIV_DEBUG */587#endif /* UNIV_DEBUG */
418#ifdef UNIV_SYNC_DEBUG588#ifdef UNIV_SYNC_DEBUG
419/******************************************************************//**589/******************************************************************//**
@@ -748,6 +918,9 @@
748#define RW_LOCK_SHARED 352918#define RW_LOCK_SHARED 352
749#define RW_LOCK_WAIT_EX 353919#define RW_LOCK_WAIT_EX 353
750#define SYNC_MUTEX 354920#define SYNC_MUTEX 354
921#define SYNC_PRIO_MUTEX 355
922#define PRIO_RW_LOCK_EX 356
923#define PRIO_RW_LOCK_SHARED 357
751924
752/* NOTE! The structure appears here only for the compiler to know its size.925/* NOTE! The structure appears here only for the compiler to know its size.
753Do not use its fields directly! The structure used in the spin lock926Do not use its fields directly! The structure used in the spin lock
@@ -798,6 +971,20 @@
798#endif971#endif
799};972};
800973
974/** XtraDB priority mutex */
975struct ib_prio_mutex_t {
976 ib_mutex_t base_mutex; /* The regular mutex provides the lock
977 word etc. for the priority mutex */
978 os_event_t high_priority_event; /* High priority wait array
979 event */
980 volatile ulint high_priority_waiters; /* Set to 1 if there are (or
981 may be) threads that asked for this
982 mutex to be acquired with high priority
983 in the global wait array for this mutex
984 to be released. Otherwise, this is
985 0. */
986};
987
801/** Constant determining how long spin wait is continued before suspending988/** Constant determining how long spin wait is continued before suspending
802the thread. A value 600 rounds on a 1995 100 MHz Pentium seems to correspond989the thread. A value 600 rounds on a 1995 100 MHz Pentium seems to correspond
803to 20 microseconds. */990to 20 microseconds. */
804991
=== modified file 'Percona-Server/storage/innobase/include/sync0sync.ic'
--- Percona-Server/storage/innobase/include/sync0sync.ic 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/sync0sync.ic 2013-09-26 14:59:13 +0000
@@ -39,14 +39,17 @@
39 ib_mutex_t* mutex, /*!< in: mutex */39 ib_mutex_t* mutex, /*!< in: mutex */
40 ulint n); /*!< in: value to set */40 ulint n); /*!< in: value to set */
41/******************************************************************//**41/******************************************************************//**
42Reserves a mutex for the current thread. If the mutex is reserved, the42Reserves a mutex or a priority mutex for the current thread. If the mutex is
43function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting43reserved, the function spins a preset time (controlled by SYNC_SPIN_ROUNDS)
44for the mutex before suspending the thread. */44waiting for the mutex before suspending the thread. */
45UNIV_INTERN45UNIV_INTERN
46void46void
47mutex_spin_wait(47mutex_spin_wait(
48/*============*/48/*============*/
49 ib_mutex_t* mutex, /*!< in: pointer to mutex */49 void* _mutex, /*!< in: pointer to mutex */
50 bool high_priority, /*!< in: whether the mutex is a
51 priority mutex with high priority
52 specified */
50 const char* file_name, /*!< in: file name where mutex53 const char* file_name, /*!< in: file name where mutex
51 requested */54 requested */
52 ulint line); /*!< in: line where requested */55 ulint line); /*!< in: line where requested */
@@ -192,6 +195,55 @@
192}195}
193196
194/******************************************************************//**197/******************************************************************//**
198NOTE! Use the corresponding macro mutex_exit(), not directly this function!
199Unlocks a priority mutex owned by the current thread. */
200UNIV_INLINE
201void
202mutex_exit_func(
203/*============*/
204 ib_prio_mutex_t* mutex) /*!< in: pointer to mutex */
205{
206 ut_ad(mutex_own(mutex));
207
208 ut_d(mutex->base_mutex.thread_id = (os_thread_id_t) ULINT_UNDEFINED);
209
210#ifdef UNIV_SYNC_DEBUG
211 sync_thread_reset_level(&mutex->base_mutex);
212#endif
213 mutex_reset_lock_word(&mutex->base_mutex);
214
215 /* A problem: we assume that mutex_reset_lock word
216 is a memory barrier, that is when we read the waiters
217 field next, the read must be serialized in memory
218 after the reset. A speculative processor might
219 perform the read first, which could leave a waiting
220 thread hanging indefinitely.
221
222 Our current solution call every second
223 sync_arr_wake_threads_if_sema_free()
224 to wake up possible hanging threads if
225 they are missed in mutex_signal_object. */
226
227 /* Wake up any high priority waiters first. */
228 if (mutex->high_priority_waiters != 0) {
229
230 mutex->high_priority_waiters = 0;
231 os_event_set(mutex->high_priority_event);
232 sync_array_object_signalled();
233
234 } else if (mutex_get_waiters(&mutex->base_mutex) != 0) {
235
236 mutex_signal_object(&mutex->base_mutex);
237 }
238
239#ifdef UNIV_SYNC_PERF_STAT
240 mutex_exit_count++;
241#endif
242
243}
244
245
246/******************************************************************//**
195Locks a mutex for the current thread. If the mutex is reserved, the function247Locks a mutex for the current thread. If the mutex is reserved, the function
196spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting for the mutex248spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting for the mutex
197before suspending the thread. */249before suspending the thread. */
@@ -217,8 +269,54 @@
217 return; /* Succeeded! */269 return; /* Succeeded! */
218 }270 }
219271
220 mutex_spin_wait(mutex, file_name, line);272 mutex_spin_wait(mutex, false, file_name, line);
221}273}
274
275/******************************************************************//**
276NOTE! Use the corresponding macro in the header file, not this function
277directly. Locks a priority mutex for the current thread. If the mutex is
278reserved the function spins a preset time (controlled by SYNC_SPIN_ROUNDS)
279waiting for the mutex before suspending the thread. If the thread is suspended,
280the priority argument value determines the relative order for its wake up. Any
281HIGH_PRIO waiters will be woken up before any LOW_PRIO waiters. In case of
282DEFAULT_PRIO, the relative priority will be set according to
283srv_current_thread_priority. */
284UNIV_INLINE
285void
286mutex_enter_func(
287/*=============*/
288 ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */
289 const char* file_name, /*!< in: file name where
290 locked */
291 ulint line, /*!< in: line where locked */
292 enum ib_sync_priority priority)
293 /*!<in: mutex acquisition
294 priority */
295{
296 bool high_priority;
297
298 ut_ad(mutex_validate(&mutex->base_mutex));
299 ut_ad(!mutex_own(mutex));
300
301 /* Note that we do not peek at the value of lock_word before trying
302 the atomic test_and_set; we could peek, and possibly save time. */
303
304 if (!ib_mutex_test_and_set(&mutex->base_mutex)) {
305 ut_d(mutex->base_mutex.thread_id = os_thread_get_curr_id());
306#ifdef UNIV_SYNC_DEBUG
307 mutex_set_debug_info(&mutex->base_mutex, file_name, line);
308#endif
309 return; /* Succeeded! */
310 }
311
312 if (UNIV_LIKELY(priority == DEFAULT_PRIO)) {
313 high_priority = srv_current_thread_priority;
314 } else {
315 high_priority = (priority == HIGH_PRIO);
316 }
317 mutex_spin_wait(mutex, high_priority, file_name, line);
318}
319
222320
223#ifdef UNIV_PFS_MUTEX321#ifdef UNIV_PFS_MUTEX
224/******************************************************************//**322/******************************************************************//**
@@ -252,6 +350,40 @@
252 }350 }
253}351}
254352
353/******************************************************************//**
354NOTE! Please use the corresponding macro mutex_enter(), not directly
355this function!
356This is a performance schema instrumented wrapper function for
357mutex_enter_func(). */
358UNIV_INLINE
359void
360pfs_mutex_enter_func(
361/*=================*/
362 ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */
363 const char* file_name, /*!< in: file name where
364 locked */
365 ulint line, /*!< in: line where locked */
366 enum ib_sync_priority priority) /*!<in: mutex acquisition
367 priority */
368{
369 if (mutex->base_mutex.pfs_psi != NULL) {
370 PSI_mutex_locker* locker;
371 PSI_mutex_locker_state state;
372
373 locker = PSI_MUTEX_CALL(start_mutex_wait)(
374 &state, mutex->base_mutex.pfs_psi,
375 PSI_MUTEX_LOCK, file_name, line);
376
377 mutex_enter_func(mutex, file_name, line, priority);
378
379 if (locker != NULL) {
380 PSI_MUTEX_CALL(end_mutex_wait)(locker, 0);
381 }
382 } else {
383 mutex_enter_func(mutex, file_name, line, priority);
384 }
385}
386
255/********************************************************************//**387/********************************************************************//**
256NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly388NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly
257this function!389this function!
@@ -289,6 +421,26 @@
289 return(ret);421 return(ret);
290}422}
291423
424/********************************************************************//**
425NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly
426this function!
427This is a performance schema instrumented wrapper function for
428mutex_enter_nowait_func.
429@return 0 if succeed, 1 if not */
430UNIV_INLINE
431ulint
432pfs_mutex_enter_nowait_func(
433/*========================*/
434 ib_prio_mutex_t* mutex, /*!< in: pointer to mutex */
435 const char* file_name, /*!< in: file name where mutex
436 requested */
437 ulint line) /*!< in: line where
438 requested */
439{
440 return pfs_mutex_enter_nowait_func(&mutex->base_mutex, file_name,
441 line);
442}
443
292/******************************************************************//**444/******************************************************************//**
293NOTE! Please use the corresponding macro mutex_exit(), not directly445NOTE! Please use the corresponding macro mutex_exit(), not directly
294this function!446this function!
@@ -308,6 +460,25 @@
308}460}
309461
310/******************************************************************//**462/******************************************************************//**
463NOTE! Please use the corresponding macro mutex_exit(), not directly
464this function!
465A wrap function of mutex_exit_func() with peformance schema instrumentation.
466Unlocks a priority mutex owned by the current thread. */
467UNIV_INLINE
468void
469pfs_mutex_exit_func(
470/*================*/
471 ib_prio_mutex_t* mutex) /*!< in: pointer to mutex */
472{
473 if (mutex->base_mutex.pfs_psi != NULL) {
474 PSI_MUTEX_CALL(unlock_mutex)(mutex->base_mutex.pfs_psi);
475 }
476
477 mutex_exit_func(mutex);
478}
479
480
481/******************************************************************//**
311NOTE! Please use the corresponding macro mutex_create(), not directly482NOTE! Please use the corresponding macro mutex_create(), not directly
312this function!483this function!
313A wrapper function for mutex_create_func(), registers the mutex484A wrapper function for mutex_create_func(), registers the mutex
@@ -342,6 +513,44 @@
342}513}
343514
344/******************************************************************//**515/******************************************************************//**
516NOTE! Please use the corresponding macro mutex_create(), not directly
517this function!
518A wrapper function for mutex_create_func(), registers the mutex
519with peformance schema if "UNIV_PFS_MUTEX" is defined when
520creating the performance mutex */
521UNIV_INLINE
522void
523pfs_mutex_create_func(
524/*==================*/
525 PSI_mutex_key key, /*!< in: Performance Schema
526 key */
527 ib_prio_mutex_t* mutex, /*!< in: pointer to memory */
528# ifdef UNIV_DEBUG
529# ifdef UNIV_SYNC_DEBUG
530 ulint level, /*!< in: level */
531# endif /* UNIV_SYNC_DEBUG */
532 const char* cfile_name, /*!< in: file name where
533 created */
534 ulint cline, /*!< in: file line where
535 created */
536# endif /* UNIV_DEBUG */
537 const char* cmutex_name)
538{
539 mutex->base_mutex.pfs_psi = PSI_MUTEX_CALL(init_mutex)(key, mutex);
540
541 mutex_create_func(mutex,
542# ifdef UNIV_DEBUG
543# ifdef UNIV_SYNC_DEBUG
544 level,
545# endif /* UNIV_SYNC_DEBUG */
546 cfile_name,
547 cline,
548# endif /* UNIV_DEBUG */
549 cmutex_name);
550}
551
552
553/******************************************************************//**
345NOTE! Please use the corresponding macro mutex_free(), not directly554NOTE! Please use the corresponding macro mutex_free(), not directly
346this function!555this function!
347Wrapper function for mutex_free_func(). Also destroys the performance556Wrapper function for mutex_free_func(). Also destroys the performance
@@ -360,6 +569,26 @@
360 mutex_free_func(mutex);569 mutex_free_func(mutex);
361}570}
362571
572/******************************************************************//**
573NOTE! Please use the corresponding macro mutex_free(), not directly
574this function!
575Wrapper function for mutex_free_func(). Also destroys the performance
576schema probes when freeing the priority mutex */
577UNIV_INLINE
578void
579pfs_mutex_free_func(
580/*================*/
581 ib_prio_mutex_t* mutex) /*!< in: mutex */
582{
583 if (mutex->base_mutex.pfs_psi != NULL) {
584 PSI_MUTEX_CALL(destroy_mutex)(mutex->base_mutex.pfs_psi);
585 mutex->base_mutex.pfs_psi = NULL;
586 }
587
588 mutex_free_func(mutex);
589}
590
591
363#endif /* UNIV_PFS_MUTEX */592#endif /* UNIV_PFS_MUTEX */
364593
365#ifndef HAVE_ATOMIC_BUILTINS594#ifndef HAVE_ATOMIC_BUILTINS
366595
=== modified file 'Percona-Server/storage/innobase/include/sync0types.h'
--- Percona-Server/storage/innobase/include/sync0types.h 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/sync0types.h 2013-09-26 14:59:13 +0000
@@ -28,4 +28,17 @@
2828
29struct ib_mutex_t;29struct ib_mutex_t;
3030
31/* The relative priority of the current thread. If 0, low priority; if 1, high
32priority. */
33extern UNIV_THREAD_LOCAL ulint srv_current_thread_priority;
34
35struct ib_prio_mutex_t;
36
37/** Priority mutex and rwlatch acquisition priorities */
38enum ib_sync_priority {
39 DEFAULT_PRIO,
40 LOW_PRIO,
41 HIGH_PRIO
42};
43
31#endif44#endif
3245
=== modified file 'Percona-Server/storage/innobase/include/trx0purge.h'
--- Percona-Server/storage/innobase/include/trx0purge.h 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/include/trx0purge.h 2013-09-26 14:59:13 +0000
@@ -138,7 +138,7 @@
138 purge query: this trx is not in the138 purge query: this trx is not in the
139 trx list of the trx system and it139 trx list of the trx system and it
140 never ends */140 never ends */
141 rw_lock_t latch; /*!< The latch protecting the purge141 prio_rw_lock_t latch; /*!< The latch protecting the purge
142 view. A purge operation must acquire an142 view. A purge operation must acquire an
143 x-latch here for the instant at which143 x-latch here for the instant at which
144 it changes the purge view: an undo144 it changes the purge view: an undo
145145
=== modified file 'Percona-Server/storage/innobase/include/trx0trx.h'
--- Percona-Server/storage/innobase/include/trx0trx.h 2013-09-02 10:01:38 +0000
+++ Percona-Server/storage/innobase/include/trx0trx.h 2013-09-26 14:59:13 +0000
@@ -1138,7 +1138,7 @@
11381138
1139Bear in mind (3) and (4) when using the hash index.1139Bear in mind (3) and (4) when using the hash index.
1140*/1140*/
1141extern rw_lock_t* btr_search_latch_arr;1141extern prio_rw_lock_t* btr_search_latch_arr;
11421142
1143#ifndef UNIV_NONINL1143#ifndef UNIV_NONINL
1144#include "trx0trx.ic"1144#include "trx0trx.ic"
11451145
=== modified file 'Percona-Server/storage/innobase/include/univ.i'
--- Percona-Server/storage/innobase/include/univ.i 2013-08-29 17:05:40 +0000
+++ Percona-Server/storage/innobase/include/univ.i 2013-09-26 14:59:13 +0000
@@ -277,6 +277,13 @@
277# define UNIV_COLD /* empty */277# define UNIV_COLD /* empty */
278#endif278#endif
279279
280#ifdef UNIV_LINUX
281# define UNIV_THREAD_LOCAL __thread
282#else
283/* FIXME: the TLS variables are silently broken on other platforms for now */
284# define UNIV_THREAD_LOCAL
285#endif
286
280#ifndef UNIV_MUST_NOT_INLINE287#ifndef UNIV_MUST_NOT_INLINE
281/* Definition for inline version */288/* Definition for inline version */
282289
283290
=== modified file 'Percona-Server/storage/innobase/mtr/mtr0mtr.cc'
--- Percona-Server/storage/innobase/mtr/mtr0mtr.cc 2013-06-25 13:13:06 +0000
+++ Percona-Server/storage/innobase/mtr/mtr0mtr.cc 2013-09-26 14:59:13 +0000
@@ -82,10 +82,10 @@
82 buf_page_release((buf_block_t*) object, slot->type);82 buf_page_release((buf_block_t*) object, slot->type);
83 break;83 break;
84 case MTR_MEMO_S_LOCK:84 case MTR_MEMO_S_LOCK:
85 rw_lock_s_unlock((rw_lock_t*) object);85 rw_lock_s_unlock((prio_rw_lock_t*) object);
86 break;86 break;
87 case MTR_MEMO_X_LOCK:87 case MTR_MEMO_X_LOCK:
88 rw_lock_x_unlock((rw_lock_t*) object);88 rw_lock_x_unlock((prio_rw_lock_t*) object);
89 break;89 break;
90#ifdef UNIV_DEBUG90#ifdef UNIV_DEBUG
91 default:91 default:
9292
=== modified file 'Percona-Server/storage/innobase/srv/srv0srv.cc'
--- Percona-Server/storage/innobase/srv/srv0srv.cc 2013-09-24 13:11:08 +0000
+++ Percona-Server/storage/innobase/srv/srv0srv.cc 2013-09-26 14:59:13 +0000
@@ -319,6 +319,22 @@
319/* Number of iterations over which adaptive flushing is averaged. */319/* Number of iterations over which adaptive flushing is averaged. */
320UNIV_INTERN ulong srv_flushing_avg_loops = 30;320UNIV_INTERN ulong srv_flushing_avg_loops = 30;
321321
322/* The relative priority of the current thread. If 0, low priority; if 1, high
323priority. */
324UNIV_INTERN UNIV_THREAD_LOCAL ulint srv_current_thread_priority = 0;
325
326/* The relative priority of the purge coordinator and worker threads. */
327UNIV_INTERN my_bool srv_purge_thread_priority = FALSE;
328
329/* The relative priority of the I/O threads. */
330UNIV_INTERN my_bool srv_io_thread_priority = FALSE;
331
332/* The relative priority of the cleaner thread. */
333UNIV_INTERN my_bool srv_cleaner_thread_priority = FALSE;
334
335/* The relative priority of the master thread. */
336UNIV_INTERN my_bool srv_master_thread_priority = FALSE;
337
322/* The number of purge threads to use.*/338/* The number of purge threads to use.*/
323UNIV_INTERN ulong srv_n_purge_threads = 1;339UNIV_INTERN ulong srv_n_purge_threads = 1;
324340
@@ -2863,6 +2879,8 @@
28632879
2864 MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP);2880 MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP);
28652881
2882 srv_current_thread_priority = srv_master_thread_priority;
2883
2866 if (srv_check_activity(old_activity_count)) {2884 if (srv_check_activity(old_activity_count)) {
2867 old_activity_count = srv_get_activity_count();2885 old_activity_count = srv_get_activity_count();
2868 srv_master_do_active_tasks();2886 srv_master_do_active_tasks();
@@ -3003,6 +3021,8 @@
30033021
3004 os_event_wait(slot->event);3022 os_event_wait(slot->event);
30053023
3024 srv_current_thread_priority = srv_purge_thread_priority;
3025
3006 if (srv_task_execute()) {3026 if (srv_task_execute()) {
30073027
3008 /* If there are tasks in the queue, wakeup3028 /* If there are tasks in the queue, wakeup
@@ -3279,6 +3299,8 @@
32793299
3280 n_total_purged = 0;3300 n_total_purged = 0;
32813301
3302 srv_current_thread_priority = srv_purge_thread_priority;
3303
3282 rseg_history_len = srv_do_purge(3304 rseg_history_len = srv_do_purge(
3283 srv_n_purge_threads, &n_total_purged);3305 srv_n_purge_threads, &n_total_purged);
32843306
32853307
=== modified file 'Percona-Server/storage/innobase/srv/srv0start.cc'
--- Percona-Server/storage/innobase/srv/srv0start.cc 2013-08-14 03:57:21 +0000
+++ Percona-Server/storage/innobase/srv/srv0start.cc 2013-09-26 14:59:13 +0000
@@ -476,6 +476,7 @@
476#endif /* UNIV_PFS_THREAD */476#endif /* UNIV_PFS_THREAD */
477477
478 while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {478 while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
479 srv_current_thread_priority = srv_io_thread_priority;
479 fil_aio_wait(segment);480 fil_aio_wait(segment);
480 }481 }
481482
482483
=== modified file 'Percona-Server/storage/innobase/sync/sync0arr.cc'
--- Percona-Server/storage/innobase/sync/sync0arr.cc 2013-08-14 03:57:21 +0000
+++ Percona-Server/storage/innobase/sync/sync0arr.cc 2013-09-26 14:59:13 +0000
@@ -83,10 +83,11 @@
83 void* wait_object; /*!< pointer to the object the83 void* wait_object; /*!< pointer to the object the
84 thread is waiting for; if NULL84 thread is waiting for; if NULL
85 the cell is free for use */85 the cell is free for use */
86 ib_mutex_t* old_wait_mutex; /*!< the latest wait mutex in cell */86 void* old_wait_mutex; /*!< the latest regular or priority
87 rw_lock_t* old_wait_rw_lock;87 wait mutex in cell */
88 /*!< the latest wait rw-lock88 void* old_wait_rw_lock;
89 in cell */89 /*!< the latest regular or priority
90 wait rw-lock in cell */
90 ulint request_type; /*!< lock type requested on the91 ulint request_type; /*!< lock type requested on the
91 object */92 object */
92 const char* file; /*!< in debug version file where93 const char* file; /*!< in debug version file where
@@ -295,9 +296,19 @@
295296
296 if (type == SYNC_MUTEX) {297 if (type == SYNC_MUTEX) {
297 return(((ib_mutex_t*) cell->wait_object)->event);298 return(((ib_mutex_t*) cell->wait_object)->event);
299 } else if (type == SYNC_PRIO_MUTEX) {
300 return(((ib_prio_mutex_t*) cell->wait_object)
301 ->high_priority_event);
298 } else if (type == RW_LOCK_WAIT_EX) {302 } else if (type == RW_LOCK_WAIT_EX) {
299 return(((rw_lock_t*) cell->wait_object)->wait_ex_event);303 return(((rw_lock_t*) cell->wait_object)->wait_ex_event);
304 } else if (type == PRIO_RW_LOCK_SHARED) {
305 return(((prio_rw_lock_t *) cell->wait_object)
306 ->high_priority_s_event);
307 } else if (type == PRIO_RW_LOCK_EX) {
308 return(((prio_rw_lock_t *) cell->wait_object)
309 ->high_priority_x_event);
300 } else { /* RW_LOCK_SHARED and RW_LOCK_EX wait on the same event */310 } else { /* RW_LOCK_SHARED and RW_LOCK_EX wait on the same event */
311 ut_ad(type == RW_LOCK_SHARED || type == RW_LOCK_EX);
301 return(((rw_lock_t*) cell->wait_object)->event);312 return(((rw_lock_t*) cell->wait_object)->event);
302 }313 }
303}314}
@@ -336,12 +347,10 @@
336 cell->waiting = FALSE;347 cell->waiting = FALSE;
337 cell->wait_object = object;348 cell->wait_object = object;
338349
339 if (type == SYNC_MUTEX) {350 if (type == SYNC_MUTEX || type == SYNC_PRIO_MUTEX) {
340 cell->old_wait_mutex =351 cell->old_wait_mutex = object;
341 static_cast<ib_mutex_t*>(object);
342 } else {352 } else {
343 cell->old_wait_rw_lock =353 cell->old_wait_rw_lock = object;
344 static_cast<rw_lock_t*>(object);
345 }354 }
346355
347 cell->request_type = type;356 cell->request_type = type;
@@ -436,7 +445,9 @@
436 sync_cell_t* cell) /*!< in: sync cell */445 sync_cell_t* cell) /*!< in: sync cell */
437{446{
438 ib_mutex_t* mutex;447 ib_mutex_t* mutex;
448 ib_prio_mutex_t* prio_mutex;
439 rw_lock_t* rwlock;449 rw_lock_t* rwlock;
450 prio_rw_lock_t* prio_rwlock = NULL;
440 ulint type;451 ulint type;
441 ulint writer;452 ulint writer;
442453
@@ -449,10 +460,19 @@
449 innobase_basename(cell->file), (ulong) cell->line,460 innobase_basename(cell->file), (ulong) cell->line,
450 difftime(time(NULL), cell->reservation_time));461 difftime(time(NULL), cell->reservation_time));
451462
452 if (type == SYNC_MUTEX) {463 if (type == SYNC_MUTEX || type == SYNC_PRIO_MUTEX) {
453 /* We use old_wait_mutex in case the cell has already464 /* We use old_wait_mutex in case the cell has already
454 been freed meanwhile */465 been freed meanwhile */
455 mutex = cell->old_wait_mutex;466 if (type == SYNC_MUTEX) {
467
468 mutex = static_cast<ib_mutex_t*>(cell->old_wait_mutex);
469 } else {
470
471 prio_mutex = static_cast<ib_prio_mutex_t*>
472 (cell->old_wait_mutex);
473 mutex = &prio_mutex->base_mutex;
474 }
475
456476
457 fprintf(file,477 fprintf(file,
458 "Mutex at %p '%s', lock var %lu\n"478 "Mutex at %p '%s', lock var %lu\n"
@@ -467,15 +487,38 @@
467#endif /* UNIV_SYNC_DEBUG */487#endif /* UNIV_SYNC_DEBUG */
468 (ulong) mutex->waiters);488 (ulong) mutex->waiters);
469489
490 if (type == SYNC_PRIO_MUTEX) {
491
492 fprintf(file,
493 "high-priority waiters flag %lu\n",
494 (ulong) prio_mutex->high_priority_waiters);
495 }
496
470 } else if (type == RW_LOCK_EX497 } else if (type == RW_LOCK_EX
471 || type == RW_LOCK_WAIT_EX498 || type == RW_LOCK_WAIT_EX
472 || type == RW_LOCK_SHARED) {499 || type == RW_LOCK_SHARED
500 || type == PRIO_RW_LOCK_SHARED
501 || type == PRIO_RW_LOCK_EX) {
473502
474 fputs(type == RW_LOCK_EX ? "X-lock on"503 fputs((type == RW_LOCK_EX || type == PRIO_RW_LOCK_EX)
504 ? "X-lock on"
475 : type == RW_LOCK_WAIT_EX ? "X-lock (wait_ex) on"505 : type == RW_LOCK_WAIT_EX ? "X-lock (wait_ex) on"
476 : "S-lock on", file);506 : "S-lock on", file);
477507
478 rwlock = cell->old_wait_rw_lock;508 /* Currently we are unable to tell high priority
509 RW_LOCK_WAIT_EX waiter from a regular priority one. Assume
510 it's a regular one. */
511 if (type == RW_LOCK_EX || type == RW_LOCK_WAIT_EX
512 || type == RW_LOCK_SHARED) {
513
514 rwlock = static_cast<rw_lock_t *>
515 (cell->old_wait_rw_lock);
516 } else {
517
518 prio_rwlock = static_cast<prio_rw_lock_t *>
519 (cell->old_wait_rw_lock);
520 rwlock = &prio_rwlock->base_lock;
521 }
479522
480 fprintf(file,523 fprintf(file,
481 " RW-latch at %p '%s'\n",524 " RW-latch at %p '%s'\n",
@@ -503,6 +546,15 @@
503 (ulong) rwlock->last_s_line,546 (ulong) rwlock->last_s_line,
504 rwlock->last_x_file_name,547 rwlock->last_x_file_name,
505 (ulong) rwlock->last_x_line);548 (ulong) rwlock->last_x_line);
549 if (prio_rwlock) {
550 fprintf(stderr, "high priority S waiters flag %lu, "
551 "high priority X waiters flag %lu, "
552 "wait-exclusive waiter is "
553 "high priority if exists: %lu\n",
554 prio_rwlock->high_priority_s_waiters,
555 prio_rwlock->high_priority_x_waiters,
556 prio_rwlock->high_priority_wait_ex_waiter);
557 }
506 } else {558 } else {
507 ut_error;559 ut_error;
508 }560 }
@@ -615,9 +667,15 @@
615 return(FALSE); /* No deadlock here */667 return(FALSE); /* No deadlock here */
616 }668 }
617669
618 if (cell->request_type == SYNC_MUTEX) {670 if (cell->request_type == SYNC_MUTEX
671 || cell->request_type == SYNC_PRIO_MUTEX) {
619672
620 mutex = static_cast<ib_mutex_t*>(cell->wait_object);673 if (cell->request_type == SYNC_MUTEX) {
674 mutex = static_cast<ib_mutex_t*>(cell->wait_object);
675 } else {
676 mutex = &(static_cast<ib_prio_mutex_t*>(
677 cell->wait_object))->base_mutex;
678 }
621679
622 if (mutex_get_lock_word(mutex) != 0) {680 if (mutex_get_lock_word(mutex) != 0) {
623681
@@ -647,6 +705,7 @@
647 return(FALSE); /* No deadlock */705 return(FALSE); /* No deadlock */
648706
649 } else if (cell->request_type == RW_LOCK_EX707 } else if (cell->request_type == RW_LOCK_EX
708 || cell->request_type == PRIO_RW_LOCK_EX
650 || cell->request_type == RW_LOCK_WAIT_EX) {709 || cell->request_type == RW_LOCK_WAIT_EX) {
651710
652 lock = static_cast<rw_lock_t*>(cell->wait_object);711 lock = static_cast<rw_lock_t*>(cell->wait_object);
@@ -685,7 +744,8 @@
685744
686 return(FALSE);745 return(FALSE);
687746
688 } else if (cell->request_type == RW_LOCK_SHARED) {747 } else if (cell->request_type == RW_LOCK_SHARED
748 || cell->request_type == PRIO_RW_LOCK_SHARED) {
689749
690 lock = static_cast<rw_lock_t*>(cell->wait_object);750 lock = static_cast<rw_lock_t*>(cell->wait_object);
691751
@@ -734,16 +794,23 @@
734 ib_mutex_t* mutex;794 ib_mutex_t* mutex;
735 rw_lock_t* lock;795 rw_lock_t* lock;
736796
737 if (cell->request_type == SYNC_MUTEX) {797 if (cell->request_type == SYNC_MUTEX
798 || cell->request_type == SYNC_PRIO_MUTEX) {
738799
739 mutex = static_cast<ib_mutex_t*>(cell->wait_object);800 if (cell->request_type == SYNC_MUTEX) {
801 mutex = static_cast<ib_mutex_t*>(cell->wait_object);
802 } else {
803 mutex = &(static_cast<ib_prio_mutex_t*>(
804 cell->wait_object))->base_mutex;
805 }
740806
741 if (mutex_get_lock_word(mutex) == 0) {807 if (mutex_get_lock_word(mutex) == 0) {
742808
743 return(TRUE);809 return(TRUE);
744 }810 }
745811
746 } else if (cell->request_type == RW_LOCK_EX) {812 } else if (cell->request_type == RW_LOCK_EX
813 || cell->request_type == PRIO_RW_LOCK_EX) {
747814
748 lock = static_cast<rw_lock_t*>(cell->wait_object);815 lock = static_cast<rw_lock_t*>(cell->wait_object);
749816
@@ -762,7 +829,8 @@
762829
763 return(TRUE);830 return(TRUE);
764 }831 }
765 } else if (cell->request_type == RW_LOCK_SHARED) {832 } else if (cell->request_type == RW_LOCK_SHARED
833 || cell->request_type == PRIO_RW_LOCK_SHARED) {
766 lock = static_cast<rw_lock_t*>(cell->wait_object);834 lock = static_cast<rw_lock_t*>(cell->wait_object);
767835
768 /* lock_word > 0 means no writer or reserved writer */836 /* lock_word > 0 means no writer or reserved writer */
@@ -770,6 +838,9 @@
770838
771 return(TRUE);839 return(TRUE);
772 }840 }
841 } else {
842
843 ut_error;
773 }844 }
774845
775 return(FALSE);846 return(FALSE);
776847
=== modified file 'Percona-Server/storage/innobase/sync/sync0rw.cc'
--- Percona-Server/storage/innobase/sync/sync0rw.cc 2013-08-06 15:16:34 +0000
+++ Percona-Server/storage/innobase/sync/sync0rw.cc 2013-09-26 14:59:13 +0000
@@ -277,6 +277,41 @@
277}277}
278278
279/******************************************************************//**279/******************************************************************//**
280Creates, or rather, initializes a priority rw-lock object in a specified memory
281location (which must be appropriately aligned). The rw-lock is initialized
282to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
283is necessary only if the memory block containing it is freed. */
284UNIV_INTERN
285void
286rw_lock_create_func(
287/*================*/
288 prio_rw_lock_t* lock, /*!< in: pointer to memory */
289#ifdef UNIV_DEBUG
290# ifdef UNIV_SYNC_DEBUG
291 ulint level, /*!< in: level */
292# endif /* UNIV_SYNC_DEBUG */
293 const char* cfile_name, /*!< in: file name where created */
294 ulint cline, /*!< in: file line where created */
295#endif /* UNIV_DEBUG */
296 const char* cmutex_name) /*!< in: mutex name */
297{
298 rw_lock_create_func(&lock->base_lock,
299#ifdef UNIV_DEBUG
300# ifdef UNIV_SYNC_DEBUG
301 level,
302# endif
303 cfile_name,
304 cline,
305#endif
306 cmutex_name);
307 lock->high_priority_s_waiters = 0;
308 lock->high_priority_s_event = os_event_create();
309 lock->high_priority_x_waiters = 0;
310 lock->high_priority_x_event = os_event_create();
311 lock->high_priority_wait_ex_waiter = 0;
312}
313
314/******************************************************************//**
280Calling this function is obligatory only if the memory buffer containing315Calling this function is obligatory only if the memory buffer containing
281the rw-lock is freed. Removes an rw-lock object from the global list. The316the rw-lock is freed. Removes an rw-lock object from the global list. The
282rw-lock is checked to be in the non-locked state. */317rw-lock is checked to be in the non-locked state. */
@@ -321,6 +356,21 @@
321#endif /* !INNODB_RW_LOCKS_USE_ATOMICS */356#endif /* !INNODB_RW_LOCKS_USE_ATOMICS */
322}357}
323358
359/******************************************************************//**
360Calling this function is obligatory only if the memory buffer containing
361the priority rw-lock is freed. Removes an rw-lock object from the global list.
362The rw-lock is checked to be in the non-locked state. */
363UNIV_INTERN
364void
365rw_lock_free_func(
366/*==============*/
367 prio_rw_lock_t* lock) /*!< in: rw-lock */
368{
369 os_event_free(lock->high_priority_s_event);
370 os_event_free(lock->high_priority_x_event);
371 rw_lock_free_func(&lock->base_lock);
372}
373
324#ifdef UNIV_DEBUG374#ifdef UNIV_DEBUG
325/******************************************************************//**375/******************************************************************//**
326Checks that the rw-lock has been initialized and that there are no376Checks that the rw-lock has been initialized and that there are no
@@ -347,20 +397,41 @@
347397
348 return(TRUE);398 return(TRUE);
349}399}
400
401/******************************************************************//**
402Checks that the priority rw-lock has been initialized and that there are no
403simultaneous shared and exclusive locks.
404@return TRUE */
405UNIV_INTERN
406ibool
407rw_lock_validate(
408/*=============*/
409 prio_rw_lock_t* lock) /*!< in: rw-lock */
410{
411 ut_ad(lock->high_priority_s_waiters < 2);
412 ut_ad(lock->high_priority_x_waiters < 2);
413 return(rw_lock_validate(&lock->base_lock));
414}
415
350#endif /* UNIV_DEBUG */416#endif /* UNIV_DEBUG */
351417
352/******************************************************************//**418/******************************************************************//**
353Lock an rw-lock in shared mode for the current thread. If the rw-lock is419Lock a regular or priority rw-lock in shared mode for the current thread. If
354locked in exclusive mode, or there is an exclusive lock request waiting,420the rw-lock is locked in exclusive mode, or there is an exclusive lock request
355the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting421waiting, the function spins a preset time (controlled by SYNC_SPIN_ROUNDS),
356for the lock, before suspending the thread. */422waiting for the lock, before suspending the thread. */
357UNIV_INTERN423UNIV_INTERN
358void424void
359rw_lock_s_lock_spin(425rw_lock_s_lock_spin(
360/*================*/426/*================*/
361 rw_lock_t* lock, /*!< in: pointer to rw-lock */427 void* _lock, /*!< in: pointer to rw-lock */
362 ulint pass, /*!< in: pass value; != 0, if the lock428 ulint pass, /*!< in: pass value; != 0, if the lock
363 will be passed to another thread to unlock */429 will be passed to another thread to unlock */
430 bool priority_lock,
431 /*!< in: whether the lock is a priority lock */
432 bool high_priority,
433 /*!< in: whether we are acquiring a priority
434 lock with high priority */
364 const char* file_name, /*!< in: file name where lock requested */435 const char* file_name, /*!< in: file name where lock requested */
365 ulint line) /*!< in: line where requested */436 ulint line) /*!< in: line where requested */
366{437{
@@ -368,6 +439,7 @@
368 ulint i = 0; /* spin round count */439 ulint i = 0; /* spin round count */
369 sync_array_t* sync_arr;440 sync_array_t* sync_arr;
370 size_t counter_index;441 size_t counter_index;
442 rw_lock_t* lock = (rw_lock_t *) _lock;
371443
372 /* We reuse the thread id to index into the counter, cache444 /* We reuse the thread id to index into the counter, cache
373 it here for efficiency. */445 it here for efficiency. */
@@ -379,35 +451,47 @@
379 rw_lock_stats.rw_s_spin_wait_count.add(counter_index, 1);451 rw_lock_stats.rw_s_spin_wait_count.add(counter_index, 1);
380lock_loop:452lock_loop:
381453
382 /* Spin waiting for the writer field to become free */454 if (!rw_lock_higher_prio_waiters_exist(priority_lock, high_priority,
383 while (i < SYNC_SPIN_ROUNDS && lock->lock_word <= 0) {455 lock)) {
384 if (srv_spin_wait_delay) {456
385 ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));457 /* Spin waiting for the writer field to become free */
386 }458 while (i < SYNC_SPIN_ROUNDS && lock->lock_word <= 0) {
387459 if (srv_spin_wait_delay) {
388 i++;460 ut_delay(ut_rnd_interval(0,
389 }461 srv_spin_wait_delay));
390462 }
391 if (i == SYNC_SPIN_ROUNDS) {463
464 i++;
465 }
466
467 if (i == SYNC_SPIN_ROUNDS) {
468 os_thread_yield();
469 }
470
471 if (srv_print_latch_waits) {
472 fprintf(stderr,
473 "Thread " ULINTPF " spin wait rw-s-lock at %p"
474 " '%s' rnds " ULINTPF "\n",
475 os_thread_pf(os_thread_get_curr_id()),
476 (void*) lock, lock->lock_name, i);
477 }
478 } else {
479
480 /* In case of higher priority waiters already present, perform
481 only this part of the spinning code path. */
392 os_thread_yield();482 os_thread_yield();
393 }483 }
394484
395 if (srv_print_latch_waits) {
396 fprintf(stderr,
397 "Thread " ULINTPF " spin wait rw-s-lock at %p"
398 " '%s' rnds " ULINTPF "\n",
399 os_thread_pf(os_thread_get_curr_id()),
400 (void*) lock, lock->lock_name, i);
401 }
402
403 /* We try once again to obtain the lock */485 /* We try once again to obtain the lock */
404 if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {486 if (!rw_lock_higher_prio_waiters_exist(priority_lock, high_priority,
487 lock)
488 && (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line))) {
405 rw_lock_stats.rw_s_spin_round_count.add(counter_index, i);489 rw_lock_stats.rw_s_spin_round_count.add(counter_index, i);
406490
407 return; /* Success */491 return; /* Success */
408 } else {492 } else {
409493
410 if (i < SYNC_SPIN_ROUNDS) {494 if (i > 0 && i < SYNC_SPIN_ROUNDS) {
411 goto lock_loop;495 goto lock_loop;
412 }496 }
413497
@@ -416,14 +500,24 @@
416 sync_arr = sync_array_get();500 sync_arr = sync_array_get();
417501
418 sync_array_reserve_cell(502 sync_array_reserve_cell(
419 sync_arr, lock, RW_LOCK_SHARED,503 sync_arr, lock,
504 high_priority ? PRIO_RW_LOCK_SHARED : RW_LOCK_SHARED,
420 file_name, line, &index);505 file_name, line, &index);
421506
422 /* Set waiters before checking lock_word to ensure wake-up507 /* Set waiters before checking lock_word to ensure wake-up
423 signal is sent. This may lead to some unnecessary signals. */508 signal is sent. This may lead to some unnecessary signals. */
424 rw_lock_set_waiter_flag(lock);509 if (high_priority) {
510 prio_rw_lock_t* prio_rw_lock
511 = (prio_rw_lock_t *) _lock;
512 prio_rw_lock->high_priority_s_waiters = 1;
513 } else {
514 rw_lock_set_waiter_flag(lock);
515 }
425516
426 if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {517 if (!rw_lock_higher_prio_waiters_exist(priority_lock,
518 high_priority, lock)
519 && (TRUE == rw_lock_s_lock_low(lock, pass,
520 file_name, line))) {
427 sync_array_free_cell(sync_arr, index);521 sync_array_free_cell(sync_arr, index);
428 return; /* Success */522 return; /* Success */
429 }523 }
@@ -618,7 +712,12 @@
618 ulint pass, /*!< in: pass value; != 0, if the lock will712 ulint pass, /*!< in: pass value; != 0, if the lock will
619 be passed to another thread to unlock */713 be passed to another thread to unlock */
620 const char* file_name,/*!< in: file name where lock requested */714 const char* file_name,/*!< in: file name where lock requested */
621 ulint line) /*!< in: line where requested */715 ulint line, /*!< in: line where requested */
716 bool priority_lock,
717 /*!< in: whether the lock is a priority lock */
718 bool high_priority)
719 /*!< in: whether we are acquiring a priority
720 lock with high priority */
622{721{
623 ulint i; /*!< spin round count */722 ulint i; /*!< spin round count */
624 ulint index; /*!< index of the reserved wait cell */723 ulint index; /*!< index of the reserved wait cell */
@@ -640,12 +739,15 @@
640739
641lock_loop:740lock_loop:
642741
643 if (rw_lock_x_lock_low(lock, pass, file_name, line)) {742 if (!rw_lock_higher_prio_waiters_exist(priority_lock, high_priority,
743 lock)
744 && rw_lock_x_lock_low(lock, pass, file_name, line)) {
644 rw_lock_stats.rw_x_spin_round_count.add(counter_index, i);745 rw_lock_stats.rw_x_spin_round_count.add(counter_index, i);
645746
646 return; /* Locking succeeded */747 return; /* Locking succeeded */
647748
648 } else {749 } else if (!rw_lock_higher_prio_waiters_exist(priority_lock,
750 high_priority, lock)) {
649751
650 if (!spinning) {752 if (!spinning) {
651 spinning = TRUE;753 spinning = TRUE;
@@ -669,26 +771,42 @@
669 } else {771 } else {
670 goto lock_loop;772 goto lock_loop;
671 }773 }
774 } else {
775
776 /* In case we skipped spinning because of higher-priority
777 waiters already waiting, perform only this bit of the spinning
778 code path. */
779 os_thread_yield();
672 }780 }
673781
674 rw_lock_stats.rw_x_spin_round_count.add(counter_index, i);782 if (spinning) {
675783
676 if (srv_print_latch_waits) {784 rw_lock_stats.rw_x_spin_round_count.add(counter_index, i);
677 fprintf(stderr,785
678 "Thread " ULINTPF " spin wait rw-x-lock at %p"786 if (srv_print_latch_waits) {
679 " '%s' rnds " ULINTPF "\n",787 fprintf(stderr,
680 os_thread_pf(os_thread_get_curr_id()), (void*) lock,788 "Thread " ULINTPF " spin wait rw-x-lock at %p"
681 lock->lock_name, i);789 " '%s' rnds " ULINTPF "\n",
790 os_thread_pf(os_thread_get_curr_id()),
791 (void*) lock,lock->lock_name, i);
792 }
682 }793 }
683794
684 sync_arr = sync_array_get();795 sync_arr = sync_array_get();
685796
686 sync_array_reserve_cell(797 sync_array_reserve_cell(
687 sync_arr, lock, RW_LOCK_EX, file_name, line, &index);798 sync_arr, lock,
799 high_priority ? PRIO_RW_LOCK_EX : RW_LOCK_EX,
800 file_name, line, &index);
688801
689 /* Waiters must be set before checking lock_word, to ensure signal802 /* Waiters must be set before checking lock_word, to ensure signal
690 is sent. This could lead to a few unnecessary wake-up signals. */803 is sent. This could lead to a few unnecessary wake-up signals. */
691 rw_lock_set_waiter_flag(lock);804 if (high_priority) {
805 prio_rw_lock_t* prio_lock = (prio_rw_lock_t *)lock;
806 prio_lock->high_priority_x_waiters = 1;
807 } else {
808 rw_lock_set_waiter_flag(lock);
809 }
692810
693 if (rw_lock_x_lock_low(lock, pass, file_name, line)) {811 if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
694 sync_array_free_cell(sync_arr, index);812 sync_array_free_cell(sync_arr, index);
@@ -713,6 +831,29 @@
713 goto lock_loop;831 goto lock_loop;
714}832}
715833
834/******************************************************************//**
835NOTE! Use the corresponding macro, not directly this function! Lock a priority
836rw-lock in exclusive mode for the current thread. If the rw-lock is locked
837in shared or exclusive mode, or there is an exclusive lock request waiting,
838the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
839for the lock, before suspending the thread. If the same thread has an x-lock
840on the rw-lock, locking succeed, with the following exception: if pass != 0,
841only a single x-lock may be taken on the lock. NOTE: If the same thread has
842an s-lock, locking does not succeed! */
843UNIV_INTERN
844void
845rw_lock_x_lock_func(
846/*================*/
847 prio_rw_lock_t* lock, /*!< in: pointer to rw-lock */
848 ulint pass, /*!< in: pass value; != 0, if the lock will
849 be passed to another thread to unlock */
850 const char* file_name,/*!< in: file name where lock requested */
851 ulint line) /*!< in: line where requested */
852{
853 rw_lock_x_lock_func(&lock->base_lock, pass, file_name, line, true,
854 srv_current_thread_priority > 0);
855}
856
716#ifdef UNIV_SYNC_DEBUG857#ifdef UNIV_SYNC_DEBUG
717/******************************************************************//**858/******************************************************************//**
718Acquires the debug mutex. We cannot use the mutex defined in sync0sync,859Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
@@ -881,6 +1022,21 @@
8811022
882 return(FALSE);1023 return(FALSE);
883}1024}
1025
1026/******************************************************************//**
1027Checks if the thread has locked the priority rw-lock in the specified mode,
1028with the pass value == 0. */
1029UNIV_INTERN
1030ibool
1031rw_lock_own(
1032/*========*/
1033 prio_rw_lock_t* lock, /*!< in: rw-lock */
1034 ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
1035 RW_LOCK_EX */
1036{
1037 return(rw_lock_own(&lock->base_lock, lock_type));
1038}
1039
884#endif /* UNIV_SYNC_DEBUG */1040#endif /* UNIV_SYNC_DEBUG */
8851041
886/******************************************************************//**1042/******************************************************************//**
8871043
=== modified file 'Percona-Server/storage/innobase/sync/sync0sync.cc'
--- Percona-Server/storage/innobase/sync/sync0sync.cc 2013-09-20 05:27:28 +0000
+++ Percona-Server/storage/innobase/sync/sync0sync.cc 2013-09-26 14:59:13 +0000
@@ -321,6 +321,40 @@
321}321}
322322
323/******************************************************************//**323/******************************************************************//**
324Creates, or rather, initializes a priority mutex object in a specified memory
325location (which must be appropriately aligned). The mutex is initialized
326in the reset state. Explicit freeing of the mutex with mutex_free is
327necessary only if the memory block containing it is freed. */
328UNIV_INTERN
329void
330mutex_create_func(
331/*==============*/
332 ib_prio_mutex_t* mutex, /*!< in: pointer to memory */
333#ifdef UNIV_DEBUG
334# ifdef UNIV_SYNC_DEBUG
335 ulint level, /*!< in: level */
336# endif /* UNIV_SYNC_DEBUG */
337 const char* cfile_name, /*!< in: file name where
338 created */
339 ulint cline, /*!< in: file line where
340 created */
341#endif /* UNIV_DEBUG */
342 const char* cmutex_name) /*!< in: mutex name */
343{
344 mutex_create_func(&mutex->base_mutex,
345#ifdef UNIV_DEBUG
346# ifdef UNIV_SYNC_DEBUG
347 level,
348#endif /* UNIV_SYNC_DEBUG */
349 cfile_name,
350 cline,
351#endif /* UNIV_DEBUG */
352 cmutex_name);
353 mutex->high_priority_waiters = 0;
354 mutex->high_priority_event = os_event_create();
355}
356
357/******************************************************************//**
324NOTE! Use the corresponding macro mutex_free(), not directly this function!358NOTE! Use the corresponding macro mutex_free(), not directly this function!
325Calling this function is obligatory only if the memory buffer containing359Calling this function is obligatory only if the memory buffer containing
326the mutex is freed. Removes a mutex object from the mutex list. The mutex360the mutex is freed. Removes a mutex object from the mutex list. The mutex
@@ -380,6 +414,22 @@
380 return;414 return;
381}415}
382416