1 diff -ruN a/innobase/configure b/innobase/configure
2 --- a/innobase/configure 2009-01-30 06:56:31.000000000 +0900
3 +++ b/innobase/configure 2009-05-06 15:40:47.000000000 +0900
4 @@ -21306,6 +21306,88 @@
9 +# as http://lists.mysql.com/commits/40686 does
10 +{ echo "$as_me:$LINENO: checking whether the compiler provides atomic builtins" >&5
11 +echo $ECHO_N "checking whether the compiler provides atomic builtins... $ECHO_C" >&6; }
12 +if test "${mysql_cv_atomic_builtins+set}" = set; then
13 + echo $ECHO_N "(cached) $ECHO_C" >&6
15 + if test "$cross_compiling" = yes; then
16 + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
17 +See \`config.log' for more details." >&5
18 +echo "$as_me: error: cannot run test program while cross compiling
19 +See \`config.log' for more details." >&2;}
20 + { (exit 1); exit 1; }; }
22 + cat >conftest.$ac_ext <<_ACEOF
25 +cat confdefs.h >>conftest.$ac_ext
26 +cat >>conftest.$ac_ext <<_ACEOF
27 +/* end confdefs.h. */
31 + int foo= -10; int bar= 10;
32 + __sync_fetch_and_add(&foo, bar);
35 + bar= __sync_lock_test_and_set(&foo, bar);
36 + if (bar || foo != 10)
38 + bar= __sync_val_compare_and_swap(&bar, foo, 15);
45 +rm -f conftest$ac_exeext
46 +if { (ac_try="$ac_link"
48 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
49 + *) ac_try_echo=$ac_try;;
51 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
52 + (eval "$ac_link") 2>&5
54 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
55 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
56 + { (case "(($ac_try" in
57 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
58 + *) ac_try_echo=$ac_try;;
60 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
61 + (eval "$ac_try") 2>&5
63 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
64 + (exit $ac_status); }; }; then
65 + mysql_cv_atomic_builtins=yes
67 + echo "$as_me: program exited with status $ac_status" >&5
68 +echo "$as_me: failed program was:" >&5
69 +sed 's/^/| /' conftest.$ac_ext >&5
72 +mysql_cv_atomic_builtins=no
74 +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
79 +{ echo "$as_me:$LINENO: result: $mysql_cv_atomic_builtins" >&5
80 +echo "${ECHO_T}$mysql_cv_atomic_builtins" >&6; }
82 +if test "x$mysql_cv_atomic_builtins" = xyes; then
84 +cat >>confdefs.h <<\_ACEOF
85 +#define HAVE_ATOMIC_BUILTINS 1
90 #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args.
91 # Some versions of Unix only take 2 arguments.
92 #AC_C_INLINE Already checked in MySQL
93 diff -ruN a/innobase/configure.in b/innobase/configure.in
94 --- a/innobase/configure.in 2009-01-30 06:42:15.000000000 +0900
95 +++ b/innobase/configure.in 2009-05-06 15:40:47.000000000 +0900
97 AC_CHECK_FUNCS(sched_yield)
98 AC_CHECK_FUNCS(fdatasync)
99 AC_CHECK_FUNCS(localtime_r)
101 +# as http://lists.mysql.com/commits/40686 does
102 +AC_CACHE_CHECK([whether the compiler provides atomic builtins],
103 + [mysql_cv_atomic_builtins], [AC_TRY_RUN([
106 + int foo= -10; int bar= 10;
107 + __sync_fetch_and_add(&foo, bar);
110 + bar= __sync_lock_test_and_set(&foo, bar);
111 + if (bar || foo != 10)
113 + bar= __sync_val_compare_and_swap(&bar, foo, 15);
118 +], [mysql_cv_atomic_builtins=yes], [mysql_cv_atomic_builtins=no])])
120 +if test "x$mysql_cv_atomic_builtins" = xyes; then
121 + AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1,
122 + [Define to 1 if compiler provides atomic builtins.])
125 #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args.
126 # Some versions of Unix only take 2 arguments.
127 #AC_C_INLINE Already checked in MySQL
128 diff -ruN a/innobase/ib_config.h b/innobase/ib_config.h
129 --- a/innobase/ib_config.h 2009-01-30 07:05:03.000000000 +0900
130 +++ b/innobase/ib_config.h 2009-05-06 15:40:47.000000000 +0900
132 /* Define to 1 if you have the <aio.h> header file. */
135 +/* Define to 1 if compiler provides atomic builtins. */
136 +#define HAVE_ATOMIC_BUILTINS 1
138 /* Define to 1 if you have the <dlfcn.h> header file. */
139 #define HAVE_DLFCN_H 1
141 diff -ruN a/innobase/ib_config.h.in b/innobase/ib_config.h.in
142 --- a/innobase/ib_config.h.in 2009-01-30 06:56:11.000000000 +0900
143 +++ b/innobase/ib_config.h.in 2009-05-06 15:40:47.000000000 +0900
145 /* Define to 1 if you have the <aio.h> header file. */
148 +/* Define to 1 if compiler provides atomic builtins. */
149 +#undef HAVE_ATOMIC_BUILTINS
151 /* Define to 1 if you have the <dlfcn.h> header file. */
154 diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
155 --- a/innobase/include/srv0srv.h 2009-05-06 15:38:01.000000000 +0900
156 +++ b/innobase/include/srv0srv.h 2009-05-06 16:04:36.000000000 +0900
158 extern ulint srv_mem_pool_size;
159 extern ulint srv_lock_table_size;
161 +extern ibool srv_thread_concurrency_timer_based;
163 extern ulint srv_n_file_io_threads;
164 extern ulint srv_n_read_io_threads;
165 extern ulint srv_n_write_io_threads;
166 diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
167 --- a/innobase/srv/srv0srv.c 2009-05-06 15:38:01.000000000 +0900
168 +++ b/innobase/srv/srv0srv.c 2009-05-06 17:12:54.000000000 +0900
170 computer. Bigger computers need bigger values. Value 0 will disable the
171 concurrency check. */
173 +ibool srv_thread_concurrency_timer_based = TRUE;
174 ulong srv_thread_concurrency = 0;
175 ulong srv_commit_concurrency = 0;
177 @@ -1020,6 +1021,74 @@
178 Puts an OS thread to wait if there are too many concurrent threads
179 (>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
181 +#ifdef HAVE_ATOMIC_BUILTINS
183 +enter_innodb_with_tickets(trx_t* trx)
185 + trx->declared_to_be_inside_innodb = TRUE;
186 + trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
191 +srv_conc_enter_innodb_timer_based(trx_t* trx)
193 + lint conc_n_threads;
194 + ibool has_yielded = FALSE;
195 + ulint has_slept = 0;
197 + if (trx->declared_to_be_inside_innodb) {
198 + ut_print_timestamp(stderr);
200 +" InnoDB: Error: trying to declare trx to enter InnoDB, but\n"
201 +"InnoDB: it already is declared.\n", stderr);
202 + trx_print(stderr, trx, 0);
203 + putc('\n', stderr);
206 + if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
207 + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
208 + if (conc_n_threads <= (lint) srv_thread_concurrency) {
209 + enter_innodb_with_tickets(trx);
212 + __sync_add_and_fetch(&srv_conc_n_threads, -1);
216 + has_yielded = TRUE;
220 + if (trx->has_search_latch
221 + || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
223 + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
224 + enter_innodb_with_tickets(trx);
229 + trx->op_info = "sleeping before entering InnoDB";
230 + os_thread_sleep(10000);
234 + conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
235 + enter_innodb_with_tickets(trx);
240 +srv_conc_exit_innodb_timer_based(trx_t* trx)
242 + __sync_add_and_fetch(&srv_conc_n_threads, -1);
243 + trx->declared_to_be_inside_innodb = FALSE;
244 + trx->n_tickets_to_enter_innodb = 0;
250 srv_conc_enter_innodb(
251 /*==================*/
252 @@ -1043,6 +1112,13 @@
256 +#ifdef HAVE_ATOMIC_BUILTINS
257 + if (srv_thread_concurrency_timer_based) {
258 + srv_conc_enter_innodb_timer_based(trx);
263 os_fast_mutex_lock(&srv_conc_mutex);
265 if (trx->declared_to_be_inside_innodb) {
266 @@ -1196,6 +1272,15 @@
270 + ut_ad(srv_conc_n_threads >= 0);
271 +#ifdef HAVE_ATOMIC_BUILTINS
272 + if (srv_thread_concurrency_timer_based) {
273 + __sync_add_and_fetch(&srv_conc_n_threads, 1);
274 + trx->declared_to_be_inside_innodb = TRUE;
275 + trx->n_tickets_to_enter_innodb = 1;
279 os_fast_mutex_lock(&srv_conc_mutex);
281 srv_conc_n_threads++;
282 @@ -1227,8 +1312,16 @@
286 +#ifdef HAVE_ATOMIC_BUILTINS
287 + if (srv_thread_concurrency_timer_based) {
288 + srv_conc_exit_innodb_timer_based(trx);
293 os_fast_mutex_lock(&srv_conc_mutex);
295 + ut_ad(srv_conc_n_threads > 0);
296 srv_conc_n_threads--;
297 trx->declared_to_be_inside_innodb = FALSE;
298 trx->n_tickets_to_enter_innodb = 0;
299 diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
300 --- a/innobase/srv/srv0start.c 2009-05-06 15:38:01.000000000 +0900
301 +++ b/innobase/srv/srv0start.c 2009-05-06 17:22:26.000000000 +0900
302 @@ -1040,6 +1040,11 @@
306 +#ifdef HAVE_ATOMIC_BUILTINS
308 + "InnoDB: use atomic builtins.\n");
311 /* Since InnoDB does not currently clean up all its internal data
312 structures in MySQL Embedded Server Library server_end(), we
313 print an error message if someone tries to start up InnoDB a
314 diff -ruN a/patch_info/innodb_thread_concurrency_timer_based.info b/patch_info/innodb_thread_concurrency_timer_based.info
315 --- /dev/null 1970-01-01 09:00:00.000000000 +0900
316 +++ b/patch_info/innodb_thread_concurrency_timer_based.info 2009-05-06 17:17:12.000000000 +0900
318 +File=thread_concurrency_timer_based.patch
319 +Name=Use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)
321 +Author=Percona <info@percona.com>
324 diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
325 --- a/sql/ha_innodb.cc 2009-05-06 15:38:01.000000000 +0900
326 +++ b/sql/ha_innodb.cc 2009-05-06 15:54:08.000000000 +0900
330 long innobase_read_io_threads, innobase_write_io_threads;
331 +my_bool innobase_thread_concurrency_timer_based;
332 long innobase_extra_rsegments;
333 longlong innobase_buffer_pool_size, innobase_log_file_size;
335 @@ -1477,6 +1478,9 @@
336 srv_n_log_files = (ulint) innobase_log_files_in_group;
337 srv_log_file_size = (ulint) innobase_log_file_size;
339 + srv_thread_concurrency_timer_based =
340 + (ibool) innobase_thread_concurrency_timer_based;
342 #ifdef UNIV_LOG_ARCHIVE
343 srv_log_archive_on = (ulint) innobase_log_archive;
344 #endif /* UNIV_LOG_ARCHIVE */
345 diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
346 --- a/sql/ha_innodb.h 2009-05-06 15:38:01.000000000 +0900
347 +++ b/sql/ha_innodb.h 2009-05-06 15:55:50.000000000 +0900
349 extern long innobase_buffer_pool_awe_mem_mb;
350 extern long innobase_file_io_threads, innobase_lock_wait_timeout;
351 extern long innobase_read_io_threads, innobase_write_io_threads;
352 +extern my_bool innobase_thread_concurrency_timer_based;
353 extern long innobase_extra_rsegments;
354 extern long innobase_force_recovery;
355 extern long innobase_open_files;
356 diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
357 --- a/sql/mysqld.cc 2009-05-06 15:38:01.000000000 +0900
358 +++ b/sql/mysqld.cc 2009-05-06 16:22:06.000000000 +0900
359 @@ -5096,6 +5096,7 @@
360 OPT_INNODB_ADAPTIVE_CHECKPOINT,
361 OPT_INNODB_READ_IO_THREADS,
362 OPT_INNODB_WRITE_IO_THREADS,
363 + OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED,
364 OPT_INNODB_EXTRA_RSEGMENTS,
365 OPT_INNODB_DICT_SIZE_LIMIT,
366 OPT_INNODB_ADAPTIVE_HASH_INDEX,
367 @@ -5455,6 +5456,11 @@
368 "Number of background write I/O threads in InnoDB.",
369 (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads,
370 0, GET_LONG, REQUIRED_ARG, 1, 1, 64, 0, 0, 0},
371 + {"innodb_thread_concurrency_timer_based", OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED,
372 + "Use InnoDB timer based concurrency throttling. ",
373 + (gptr*) &innobase_thread_concurrency_timer_based,
374 + (gptr*) &innobase_thread_concurrency_timer_based,
375 + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
376 {"innodb_extra_rsegments", OPT_INNODB_EXTRA_RSEGMENTS,
377 "Number of extra user rollback segments when create new database.",
378 (gptr*) &innobase_extra_rsegments, (gptr*) &innobase_extra_rsegments,
379 diff -ruN a/sql/set_var.cc b/sql/set_var.cc
380 --- a/sql/set_var.cc 2009-05-06 15:38:01.000000000 +0900
381 +++ b/sql/set_var.cc 2009-05-06 16:02:27.000000000 +0900
382 @@ -1063,6 +1063,7 @@
383 {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS},
384 {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG},
385 {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG},
386 + {"innodb_thread_concurrency_timer_based", (char*) &innobase_thread_concurrency_timer_based, SHOW_MY_BOOL},
387 {"innodb_extra_rsegments", (char*) &innobase_extra_rsegments, SHOW_LONG},
388 {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS},
389 {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS},