1 diff -ruN a/innobase/configure b/innobase/configure
2 diff -ruN a/innobase/configure.in b/innobase/configure.in
3 --- a/innobase/configure.in 2009-01-30 06:42:15.000000000 +0900
4 +++ b/innobase/configure.in 2009-05-06 15:40:47.000000000 +0900
6 AC_CHECK_FUNCS(sched_yield)
7 AC_CHECK_FUNCS(fdatasync)
8 AC_CHECK_FUNCS(localtime_r)
10 +# as http://lists.mysql.com/commits/40686 does
11 +AC_CACHE_CHECK([whether the compiler provides atomic builtins],
12 + [mysql_cv_atomic_builtins], [AC_TRY_RUN([
15 + int foo= -10; int bar= 10;
16 + __sync_fetch_and_add(&foo, bar);
19 + bar= __sync_lock_test_and_set(&foo, bar);
20 + if (bar || foo != 10)
22 + bar= __sync_val_compare_and_swap(&bar, foo, 15);
27 +], [mysql_cv_atomic_builtins=yes], [mysql_cv_atomic_builtins=no])])
29 +if test "x$mysql_cv_atomic_builtins" = xyes; then
30 + AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1,
31 + [Define to 1 if compiler provides atomic builtins.])
34 #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args.
35 # Some versions of Unix only take 2 arguments.
36 #AC_C_INLINE Already checked in MySQL
37 diff -ruN a/innobase/ib_config.h b/innobase/ib_config.h
38 --- a/innobase/ib_config.h 2009-01-30 07:05:03.000000000 +0900
39 +++ b/innobase/ib_config.h 2009-05-06 15:40:47.000000000 +0900
41 /* Define to 1 if you have the <aio.h> header file. */
44 +/* Define to 1 if compiler provides atomic builtins. */
45 +#define HAVE_ATOMIC_BUILTINS 1
47 /* Define to 1 if you have the <dlfcn.h> header file. */
48 #define HAVE_DLFCN_H 1
50 diff -ruN a/innobase/ib_config.h.in b/innobase/ib_config.h.in
51 --- a/innobase/ib_config.h.in 2009-01-30 06:56:11.000000000 +0900
52 +++ b/innobase/ib_config.h.in 2009-05-06 15:40:47.000000000 +0900
54 /* Define to 1 if you have the <aio.h> header file. */
57 +/* Define to 1 if compiler provides atomic builtins. */
58 +#undef HAVE_ATOMIC_BUILTINS
60 /* Define to 1 if you have the <dlfcn.h> header file. */
63 diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
64 --- a/innobase/include/srv0srv.h 2009-05-06 15:38:01.000000000 +0900
65 +++ b/innobase/include/srv0srv.h 2009-05-06 16:04:36.000000000 +0900
67 extern ulint srv_mem_pool_size;
68 extern ulint srv_lock_table_size;
70 +extern ibool srv_thread_concurrency_timer_based;
72 extern ulint srv_n_file_io_threads;
73 extern ulint srv_n_read_io_threads;
74 extern ulint srv_n_write_io_threads;
75 diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
76 --- a/innobase/srv/srv0srv.c 2009-05-06 15:38:01.000000000 +0900
77 +++ b/innobase/srv/srv0srv.c 2009-05-06 17:12:54.000000000 +0900
79 computer. Bigger computers need bigger values. Value 0 will disable the
82 +ibool srv_thread_concurrency_timer_based = TRUE;
83 ulong srv_thread_concurrency = 0;
84 ulong srv_commit_concurrency = 0;
86 @@ -1026,6 +1027,74 @@
87 Puts an OS thread to wait if there are too many concurrent threads
88 (>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
90 +#ifdef HAVE_ATOMIC_BUILTINS
92 +enter_innodb_with_tickets(trx_t* trx)
94 + trx->declared_to_be_inside_innodb = TRUE;
95 + trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
100 +srv_conc_enter_innodb_timer_based(trx_t* trx)
102 + lint conc_n_threads;
103 + ibool has_yielded = FALSE;
104 + ulint has_slept = 0;
106 + if (trx->declared_to_be_inside_innodb) {
107 + ut_print_timestamp(stderr);
109 +" InnoDB: Error: trying to declare trx to enter InnoDB, but\n"
110 +"InnoDB: it already is declared.\n", stderr);
111 + trx_print(stderr, trx, 0);
112 + putc('\n', stderr);
115 + if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
116 + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
117 + if (conc_n_threads <= (lint) srv_thread_concurrency) {
118 + enter_innodb_with_tickets(trx);
121 + __sync_add_and_fetch(&srv_conc_n_threads, -1);
125 + has_yielded = TRUE;
129 + if (trx->has_search_latch
130 + || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
132 + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
133 + enter_innodb_with_tickets(trx);
138 + trx->op_info = "sleeping before entering InnoDB";
139 + os_thread_sleep(10000);
143 + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
144 + enter_innodb_with_tickets(trx);
149 +srv_conc_exit_innodb_timer_based(trx_t* trx)
151 + __sync_add_and_fetch(&srv_conc_n_threads, -1);
152 + trx->declared_to_be_inside_innodb = FALSE;
153 + trx->n_tickets_to_enter_innodb = 0;
159 srv_conc_enter_innodb(
160 /*==================*/
161 @@ -1049,6 +1118,13 @@
165 +#ifdef HAVE_ATOMIC_BUILTINS
166 + if (srv_thread_concurrency_timer_based) {
167 + srv_conc_enter_innodb_timer_based(trx);
172 os_fast_mutex_lock(&srv_conc_mutex);
174 if (trx->declared_to_be_inside_innodb) {
175 @@ -1202,6 +1278,15 @@
179 + ut_ad(srv_conc_n_threads >= 0);
180 +#ifdef HAVE_ATOMIC_BUILTINS
181 + if (srv_thread_concurrency_timer_based) {
182 + __sync_add_and_fetch(&srv_conc_n_threads, 1);
183 + trx->declared_to_be_inside_innodb = TRUE;
184 + trx->n_tickets_to_enter_innodb = 1;
188 os_fast_mutex_lock(&srv_conc_mutex);
190 srv_conc_n_threads++;
191 @@ -1233,8 +1318,16 @@
195 +#ifdef HAVE_ATOMIC_BUILTINS
196 + if (srv_thread_concurrency_timer_based) {
197 + srv_conc_exit_innodb_timer_based(trx);
202 os_fast_mutex_lock(&srv_conc_mutex);
204 + ut_ad(srv_conc_n_threads > 0);
205 srv_conc_n_threads--;
206 trx->declared_to_be_inside_innodb = FALSE;
207 trx->n_tickets_to_enter_innodb = 0;
208 diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
209 --- a/innobase/srv/srv0start.c 2009-05-06 15:38:01.000000000 +0900
210 +++ b/innobase/srv/srv0start.c 2009-05-06 17:22:26.000000000 +0900
211 @@ -1040,6 +1040,11 @@
215 +#ifdef HAVE_ATOMIC_BUILTINS
217 + "InnoDB: use atomic builtins.\n");
220 /* Since InnoDB does not currently clean up all its internal data
221 structures in MySQL Embedded Server Library server_end(), we
222 print an error message if someone tries to start up InnoDB a
223 diff -ruN /dev/null b/patch_info/innodb_thread_concurrency_timer_based.info
224 --- /dev/null 1970-01-01 09:00:00.000000000 +0900
225 +++ b/patch_info/innodb_thread_concurrency_timer_based.info 2009-05-06 17:17:12.000000000 +0900
227 +File=thread_concurrency_timer_based.patch
228 +Name=Use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)
230 +Author=Percona <info@percona.com>
233 diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
234 --- a/sql/ha_innodb.cc 2009-05-06 15:38:01.000000000 +0900
235 +++ b/sql/ha_innodb.cc 2009-05-06 15:54:08.000000000 +0900
239 long innobase_read_io_threads, innobase_write_io_threads;
240 +my_bool innobase_thread_concurrency_timer_based;
241 long innobase_extra_rsegments;
242 longlong innobase_buffer_pool_size, innobase_log_file_size;
244 @@ -1476,6 +1477,9 @@
245 srv_n_log_files = (ulint) innobase_log_files_in_group;
246 srv_log_file_size = (ulint) innobase_log_file_size;
248 + srv_thread_concurrency_timer_based =
249 + (ibool) innobase_thread_concurrency_timer_based;
251 #ifdef UNIV_LOG_ARCHIVE
252 srv_log_archive_on = (ulint) innobase_log_archive;
253 #endif /* UNIV_LOG_ARCHIVE */
254 diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
255 --- a/sql/ha_innodb.h 2009-05-06 15:38:01.000000000 +0900
256 +++ b/sql/ha_innodb.h 2009-05-06 15:55:50.000000000 +0900
258 extern long innobase_buffer_pool_awe_mem_mb;
259 extern long innobase_file_io_threads, innobase_lock_wait_timeout;
260 extern long innobase_read_io_threads, innobase_write_io_threads;
261 +extern my_bool innobase_thread_concurrency_timer_based;
262 extern long innobase_extra_rsegments;
263 extern long innobase_force_recovery;
264 extern long innobase_open_files;
265 diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
266 --- a/sql/mysqld.cc 2009-05-06 15:38:01.000000000 +0900
267 +++ b/sql/mysqld.cc 2009-05-06 16:22:06.000000000 +0900
268 @@ -5118,6 +5118,7 @@
269 OPT_INNODB_ADAPTIVE_CHECKPOINT,
270 OPT_INNODB_READ_IO_THREADS,
271 OPT_INNODB_WRITE_IO_THREADS,
272 + OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED,
273 OPT_INNODB_EXTRA_RSEGMENTS,
274 OPT_INNODB_DICT_SIZE_LIMIT,
275 OPT_INNODB_ADAPTIVE_HASH_INDEX,
276 @@ -5484,6 +5485,11 @@
277 "Number of background write I/O threads in InnoDB.",
278 (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads,
279 0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0},
280 + {"innodb_thread_concurrency_timer_based", OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED,
281 + "Use InnoDB timer based concurrency throttling. ",
282 + (gptr*) &innobase_thread_concurrency_timer_based,
283 + (gptr*) &innobase_thread_concurrency_timer_based,
284 + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
285 {"innodb_extra_rsegments", OPT_INNODB_EXTRA_RSEGMENTS,
286 "Number of extra user rollback segments when create new database.",
287 (gptr*) &innobase_extra_rsegments, (gptr*) &innobase_extra_rsegments,
288 diff -ruN a/sql/set_var.cc b/sql/set_var.cc
289 --- a/sql/set_var.cc 2009-05-06 15:38:01.000000000 +0900
290 +++ b/sql/set_var.cc 2009-05-06 16:02:27.000000000 +0900
291 @@ -1093,6 +1093,7 @@
292 {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS},
293 {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG},
294 {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG},
295 + {"innodb_thread_concurrency_timer_based", (char*) &innobase_thread_concurrency_timer_based, SHOW_MY_BOOL},
296 {"innodb_extra_rsegments", (char*) &innobase_extra_rsegments, SHOW_LONG},
297 {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS},
298 {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS},