Merge lp:~percona-dev/percona-patches/fix-rwlock-bug333750-2 into lp:~percona-dev/percona-patches/5.0.77
- fix-rwlock-bug333750-2
- Merge into 5.0.77
Proposed by
Yasufumi Kinoshita
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | not available | ||||
Proposed branch: | lp:~percona-dev/percona-patches/fix-rwlock-bug333750-2 | ||||
Merge into: | lp:~percona-dev/percona-patches/5.0.77 | ||||
Diff against target: | None lines | ||||
To merge this branch: | bzr merge lp:~percona-dev/percona-patches/fix-rwlock-bug333750-2 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Percona developers | Pending | ||
Review via email: mp+5606@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'innodb_rw_lock.patch' |
2 | --- innodb_rw_lock.patch 2009-02-12 01:54:35 +0000 |
3 | +++ innodb_rw_lock.patch 2009-04-16 09:35:29 +0000 |
4 | @@ -1,11 +1,10 @@ |
5 | -diff -r 962aec0d731c innobase/configure |
6 | ---- a/innobase/configure Thu Oct 09 08:28:53 2008 -0700 |
7 | -+++ b/innobase/configure Thu Oct 09 08:30:28 2008 -0700 |
8 | -@@ -20519,6 +20519,88 @@ |
9 | - |
10 | +diff -ruN a/innobase/configure b/innobase/configure |
11 | +--- a/innobase/configure 2009-01-30 06:56:31.000000000 +0900 |
12 | ++++ b/innobase/configure 2009-04-16 16:15:28.000000000 +0900 |
13 | +@@ -21306,6 +21306,88 @@ |
14 | fi |
15 | done |
16 | -+ |
17 | + |
18 | + |
19 | +# as http://lists.mysql.com/commits/40686 does |
20 | +{ echo "$as_me:$LINENO: checking whether the compiler provides atomic builtins" >&5 |
21 | @@ -87,12 +86,13 @@ |
22 | +_ACEOF |
23 | + |
24 | +fi |
25 | - |
26 | ++ |
27 | #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args. |
28 | # Some versions of Unix only take 2 arguments. |
29 | -diff -r 962aec0d731c innobase/configure.in |
30 | ---- a/innobase/configure.in Thu Oct 09 08:28:53 2008 -0700 |
31 | -+++ b/innobase/configure.in Thu Oct 09 08:30:28 2008 -0700 |
32 | + #AC_C_INLINE Already checked in MySQL |
33 | +diff -ruN a/innobase/configure.in b/innobase/configure.in |
34 | +--- a/innobase/configure.in 2009-01-30 06:42:15.000000000 +0900 |
35 | ++++ b/innobase/configure.in 2009-04-16 16:15:28.000000000 +0900 |
36 | @@ -42,6 +42,31 @@ |
37 | AC_CHECK_FUNCS(sched_yield) |
38 | AC_CHECK_FUNCS(fdatasync) |
39 | @@ -125,35 +125,35 @@ |
40 | #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args. |
41 | # Some versions of Unix only take 2 arguments. |
42 | #AC_C_INLINE Already checked in MySQL |
43 | -diff -r 962aec0d731c innobase/ib_config.h |
44 | ---- a/innobase/ib_config.h Thu Oct 09 08:28:53 2008 -0700 |
45 | -+++ b/innobase/ib_config.h Thu Oct 09 08:30:28 2008 -0700 |
46 | -@@ -3,6 +3,9 @@ |
47 | - |
48 | +diff -ruN a/innobase/ib_config.h b/innobase/ib_config.h |
49 | +--- a/innobase/ib_config.h 2009-01-30 07:05:03.000000000 +0900 |
50 | ++++ b/innobase/ib_config.h 2009-04-16 16:15:28.000000000 +0900 |
51 | +@@ -7,6 +7,9 @@ |
52 | /* Define to 1 if you have the <aio.h> header file. */ |
53 | #define HAVE_AIO_H 1 |
54 | -+ |
55 | + |
56 | +/* Define to 1 if compiler provides atomic builtins. */ |
57 | +#define HAVE_ATOMIC_BUILTINS 1 |
58 | - |
59 | ++ |
60 | /* Define to 1 if you have the <dlfcn.h> header file. */ |
61 | #define HAVE_DLFCN_H 1 |
62 | -diff -r 962aec0d731c innobase/ib_config.h.in |
63 | ---- a/innobase/ib_config.h.in Thu Oct 09 08:28:53 2008 -0700 |
64 | -+++ b/innobase/ib_config.h.in Thu Oct 09 08:30:28 2008 -0700 |
65 | -@@ -2,6 +2,9 @@ |
66 | |
67 | +diff -ruN a/innobase/ib_config.h.in b/innobase/ib_config.h.in |
68 | +--- a/innobase/ib_config.h.in 2009-01-30 06:56:11.000000000 +0900 |
69 | ++++ b/innobase/ib_config.h.in 2009-04-16 16:15:28.000000000 +0900 |
70 | +@@ -6,6 +6,9 @@ |
71 | /* Define to 1 if you have the <aio.h> header file. */ |
72 | #undef HAVE_AIO_H |
73 | -+ |
74 | + |
75 | +/* Define to 1 if compiler provides atomic builtins. */ |
76 | +#undef HAVE_ATOMIC_BUILTINS |
77 | - |
78 | ++ |
79 | /* Define to 1 if you have the <dlfcn.h> header file. */ |
80 | #undef HAVE_DLFCN_H |
81 | -diff -r 962aec0d731c innobase/include/sync0rw.h |
82 | ---- a/innobase/include/sync0rw.h Thu Oct 09 08:28:53 2008 -0700 |
83 | -+++ b/innobase/include/sync0rw.h Thu Oct 09 08:30:28 2008 -0700 |
84 | + |
85 | +diff -ruN a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h |
86 | +--- a/innobase/include/sync0rw.h 2009-01-30 06:42:20.000000000 +0900 |
87 | ++++ b/innobase/include/sync0rw.h 2009-04-16 16:15:28.000000000 +0900 |
88 | @@ -325,7 +325,17 @@ |
89 | Accessor functions for rw lock. */ |
90 | UNIV_INLINE |
91 | @@ -191,7 +191,7 @@ |
92 | /* NOTE! The structure appears here only for the compiler to know its size. |
93 | Do not use its fields directly! The structure used in the spin lock |
94 | implementation of a read-write lock. Several threads may have a shared lock |
95 | -@@ -417,9 +432,9 @@ |
96 | +@@ -417,9 +438,9 @@ |
97 | field. Then no new readers are allowed in. */ |
98 | |
99 | struct rw_lock_struct { |
100 | @@ -204,7 +204,7 @@ |
101 | os_event_t wait_ex_event; /* This windows specific event is |
102 | used by the thread which has set the |
103 | lock state to RW_LOCK_WAIT_EX. The |
104 | -@@ -427,31 +442,35 @@ |
105 | +@@ -427,31 +448,35 @@ |
106 | thread will be the next one to proceed |
107 | once the current the event gets |
108 | signalled. See LEMMA 2 in sync0sync.c */ |
109 | @@ -249,10 +249,10 @@ |
110 | /* This is TRUE if the writer field is |
111 | RW_LOCK_WAIT_EX; this field is located far |
112 | from the memory update hotspot fields which |
113 | -diff -r 962aec0d731c innobase/include/sync0rw.ic |
114 | ---- a/innobase/include/sync0rw.ic Thu Oct 09 08:28:53 2008 -0700 |
115 | -+++ b/innobase/include/sync0rw.ic Thu Oct 09 08:30:28 2008 -0700 |
116 | -@@ -47,20 +47,52 @@ |
117 | +diff -ruN a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic |
118 | +--- a/innobase/include/sync0rw.ic 2009-01-30 06:42:20.000000000 +0900 |
119 | ++++ b/innobase/include/sync0rw.ic 2009-04-16 17:06:53.000000000 +0900 |
120 | +@@ -47,20 +47,64 @@ |
121 | Accessor functions for rw lock. */ |
122 | UNIV_INLINE |
123 | ulint |
124 | @@ -263,11 +263,13 @@ |
125 | { |
126 | - return(lock->waiters); |
127 | + return(lock->s_waiters); |
128 | -+} |
129 | -+UNIV_INLINE |
130 | + } |
131 | + UNIV_INLINE |
132 | +-void |
133 | +-rw_lock_set_waiters( |
134 | +ulint |
135 | +rw_lock_get_x_waiters( |
136 | -+/*================*/ |
137 | + /*================*/ |
138 | + rw_lock_t* lock) |
139 | +{ |
140 | + return(lock->x_waiters); |
141 | @@ -279,17 +281,19 @@ |
142 | + rw_lock_t* lock) |
143 | +{ |
144 | + return(lock->wait_ex_waiters); |
145 | - } |
146 | - UNIV_INLINE |
147 | - void |
148 | --rw_lock_set_waiters( |
149 | --/*================*/ |
150 | ++} |
151 | ++UNIV_INLINE |
152 | ++void |
153 | +rw_lock_set_s_waiters( |
154 | rw_lock_t* lock, |
155 | ulint flag) |
156 | { |
157 | - lock->waiters = flag; |
158 | ++#ifdef HAVE_ATOMIC_BUILTINS |
159 | ++ __sync_lock_test_and_set(&lock->s_waiters, flag); |
160 | ++#else |
161 | + lock->s_waiters = flag; |
162 | ++#endif |
163 | +} |
164 | +UNIV_INLINE |
165 | +void |
166 | @@ -297,7 +301,11 @@ |
167 | + rw_lock_t* lock, |
168 | + ulint flag) |
169 | +{ |
170 | ++#ifdef HAVE_ATOMIC_BUILTINS |
171 | ++ __sync_lock_test_and_set(&lock->x_waiters, flag); |
172 | ++#else |
173 | + lock->x_waiters = flag; |
174 | ++#endif |
175 | +} |
176 | +UNIV_INLINE |
177 | +void |
178 | @@ -306,11 +314,15 @@ |
179 | + rw_lock_t* lock, |
180 | + ulint flag) |
181 | +{ |
182 | ++#ifdef HAVE_ATOMIC_BUILTINS |
183 | ++ __sync_lock_test_and_set(&lock->wait_ex_waiters, flag); |
184 | ++#else |
185 | + lock->wait_ex_waiters = flag; |
186 | ++#endif |
187 | } |
188 | UNIV_INLINE |
189 | ulint |
190 | -@@ -68,7 +100,19 @@ |
191 | +@@ -68,7 +112,19 @@ |
192 | /*===============*/ |
193 | rw_lock_t* lock) |
194 | { |
195 | @@ -330,7 +342,7 @@ |
196 | } |
197 | UNIV_INLINE |
198 | void |
199 | -@@ -96,6 +140,7 @@ |
200 | +@@ -96,6 +152,7 @@ |
201 | { |
202 | lock->reader_count = count; |
203 | } |
204 | @@ -338,7 +350,7 @@ |
205 | UNIV_INLINE |
206 | mutex_t* |
207 | rw_lock_get_mutex( |
208 | -@@ -104,6 +149,7 @@ |
209 | +@@ -104,6 +161,7 @@ |
210 | { |
211 | return(&(lock->mutex)); |
212 | } |
213 | @@ -346,7 +358,7 @@ |
214 | |
215 | /********************************************************************** |
216 | Returns the value of writer_count for the lock. Does not reserve the lock |
217 | -@@ -133,14 +179,26 @@ |
218 | +@@ -133,14 +191,26 @@ |
219 | const char* file_name, /* in: file name where lock requested */ |
220 | ulint line) /* in: line where requested */ |
221 | { |
222 | @@ -374,7 +386,7 @@ |
223 | |
224 | #ifdef UNIV_SYNC_DEBUG |
225 | rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name, |
226 | -@@ -167,11 +225,15 @@ |
227 | +@@ -167,11 +237,15 @@ |
228 | const char* file_name, /* in: file name where requested */ |
229 | ulint line) /* in: line where lock requested */ |
230 | { |
231 | @@ -391,7 +403,7 @@ |
232 | |
233 | lock->last_s_file_name = file_name; |
234 | lock->last_s_line = line; |
235 | -@@ -199,7 +261,11 @@ |
236 | +@@ -199,7 +273,11 @@ |
237 | |
238 | rw_lock_set_writer(lock, RW_LOCK_EX); |
239 | lock->writer_thread = os_thread_get_curr_id(); |
240 | @@ -403,7 +415,7 @@ |
241 | lock->pass = 0; |
242 | |
243 | lock->last_x_file_name = file_name; |
244 | -@@ -241,15 +307,21 @@ |
245 | +@@ -241,15 +319,21 @@ |
246 | ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */ |
247 | #endif /* UNIV_SYNC_DEBUG */ |
248 | |
249 | @@ -425,7 +437,7 @@ |
250 | |
251 | rw_lock_s_lock_spin(lock, pass, file_name, line); |
252 | |
253 | -@@ -272,11 +344,23 @@ |
254 | +@@ -272,11 +356,23 @@ |
255 | { |
256 | ibool success = FALSE; |
257 | |
258 | @@ -449,7 +461,7 @@ |
259 | |
260 | #ifdef UNIV_SYNC_DEBUG |
261 | rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name, |
262 | -@@ -289,7 +373,9 @@ |
263 | +@@ -289,7 +385,9 @@ |
264 | success = TRUE; |
265 | } |
266 | |
267 | @@ -459,20 +471,20 @@ |
268 | |
269 | return(success); |
270 | } |
271 | -@@ -309,6 +395,55 @@ |
272 | +@@ -309,6 +407,54 @@ |
273 | { |
274 | ibool success = FALSE; |
275 | os_thread_id_t curr_thread = os_thread_get_curr_id(); |
276 | +#ifdef HAVE_ATOMIC_BUILTINS |
277 | -+ if ((lock->lock_word == RW_LOCK_BIAS) |
278 | -+ && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) { |
279 | -+ /* try x-lock */ |
280 | -+ if(__sync_sub_and_fetch(&(lock->lock_word), |
281 | -+ RW_LOCK_BIAS) == 0) { |
282 | ++ if (lock->reader_count == 0) { |
283 | ++ /* try to lock writer */ |
284 | ++ if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX) |
285 | ++ == RW_LOCK_NOT_LOCKED) { |
286 | + /* success */ |
287 | -+ /* try to lock writer */ |
288 | -+ if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX) |
289 | -+ == RW_LOCK_NOT_LOCKED) { |
290 | ++retry_x_lock: |
291 | ++ /* try x-lock */ |
292 | ++ if(__sync_sub_and_fetch(&(lock->lock_word), |
293 | ++ RW_LOCK_BIAS) == 0) { |
294 | + /* success */ |
295 | + lock->writer_thread = curr_thread; |
296 | + lock->pass = 0; |
297 | @@ -492,30 +504,29 @@ |
298 | + |
299 | + return(TRUE); |
300 | + } else { |
301 | -+ /* x-unlock */ |
302 | -+ __sync_fetch_and_add(&(lock->lock_word), |
303 | -+ RW_LOCK_BIAS); |
304 | ++ /* fail (x-lock) */ |
305 | ++ if (__sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS) |
306 | ++ == 0) |
307 | ++ goto retry_x_lock; |
308 | + } |
309 | -+ } else { |
310 | -+ /* fail (x-lock) */ |
311 | -+ __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS); |
312 | ++ |
313 | ++ __sync_lock_test_and_set(&(lock->writer),RW_LOCK_NOT_LOCKED); |
314 | + } |
315 | + } |
316 | + |
317 | + if (lock->pass == 0 |
318 | -+ && os_thread_eq(lock->writer_thread, curr_thread) |
319 | -+ && rw_lock_get_writer(lock) == RW_LOCK_EX) { |
320 | ++ && os_thread_eq(lock->writer_thread, curr_thread)) { |
321 | + goto relock; |
322 | + } |
323 | + |
324 | -+ ut_ad(rw_lock_validate(lock)); |
325 | ++ //ut_ad(rw_lock_validate(lock)); |
326 | + |
327 | + return(FALSE); |
328 | +#else |
329 | mutex_enter(rw_lock_get_mutex(lock)); |
330 | |
331 | if (UNIV_UNLIKELY(rw_lock_get_reader_count(lock) != 0)) { |
332 | -@@ -339,6 +474,7 @@ |
333 | +@@ -339,6 +485,7 @@ |
334 | ut_ad(rw_lock_validate(lock)); |
335 | |
336 | return(success); |
337 | @@ -523,7 +534,7 @@ |
338 | } |
339 | |
340 | /********************************************************************** |
341 | -@@ -354,16 +490,33 @@ |
342 | +@@ -354,16 +501,33 @@ |
343 | #endif |
344 | ) |
345 | { |
346 | @@ -558,37 +569,37 @@ |
347 | |
348 | #ifdef UNIV_SYNC_DEBUG |
349 | rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED); |
350 | -@@ -372,20 +525,36 @@ |
351 | +@@ -372,22 +536,39 @@ |
352 | /* If there may be waiters and this was the last s-lock, |
353 | signal the object */ |
354 | |
355 | - if (UNIV_UNLIKELY(lock->waiters) |
356 | +#ifdef HAVE_ATOMIC_BUILTINS |
357 | -+ if (UNIV_UNLIKELY(last && lock->wait_ex_waiters)) { |
358 | ++ if (UNIV_UNLIKELY(last && __sync_lock_test_and_set(&lock->wait_ex_waiters, 0))) { |
359 | ++ os_event_set(lock->wait_ex_event); |
360 | ++ sync_array_object_signalled(sync_primary_wait_array); |
361 | ++ } |
362 | ++ else if (UNIV_UNLIKELY(last && __sync_lock_test_and_set(&lock->x_waiters, 0))) { |
363 | ++ os_event_set(lock->x_event); |
364 | ++ sync_array_object_signalled(sync_primary_wait_array); |
365 | ++ } |
366 | +#else |
367 | + if (UNIV_UNLIKELY(lock->wait_ex_waiters) |
368 | && lock->reader_count == 0) { |
369 | - sg = TRUE; |
370 | -+#endif |
371 | + wx_sg = TRUE; |
372 | |
373 | - rw_lock_set_waiters(lock, 0); |
374 | + rw_lock_set_wx_waiters(lock, 0); |
375 | + } |
376 | -+#ifdef HAVE_ATOMIC_BUILTINS |
377 | -+ else if (UNIV_UNLIKELY(last && lock->x_waiters)) { |
378 | -+#else |
379 | + else if (UNIV_UNLIKELY(lock->x_waiters) |
380 | + && lock->reader_count == 0) { |
381 | -+#endif |
382 | + x_sg = TRUE; |
383 | + |
384 | + rw_lock_set_x_waiters(lock, 0); |
385 | } |
386 | |
387 | -+#ifndef HAVE_ATOMIC_BUILTINS |
388 | mutex_exit(mutex); |
389 | -+#endif |
390 | |
391 | - if (UNIV_UNLIKELY(sg)) { |
392 | -#ifdef __WIN__ |
393 | @@ -601,8 +612,11 @@ |
394 | + os_event_set(lock->x_event); |
395 | sync_array_object_signalled(sync_primary_wait_array); |
396 | } |
397 | - |
398 | -@@ -409,13 +578,22 @@ |
399 | ++#endif |
400 | + |
401 | + ut_ad(rw_lock_validate(lock)); |
402 | + |
403 | +@@ -409,13 +590,22 @@ |
404 | |
405 | ut_ad(lock->reader_count > 0); |
406 | |
407 | @@ -625,7 +639,7 @@ |
408 | ut_ad(rw_lock_validate(lock)); |
409 | #ifdef UNIV_SYNC_PERF_STAT |
410 | rw_s_exit_count++; |
411 | -@@ -435,41 +613,81 @@ |
412 | +@@ -435,41 +625,83 @@ |
413 | #endif |
414 | ) |
415 | { |
416 | @@ -658,10 +672,7 @@ |
417 | + /* FIXME: It is a value of bad manners for pthread. |
418 | + But we shouldn't keep an ID of not-owner. */ |
419 | + lock->writer_thread = -1; |
420 | -+ |
421 | -+ /* atomic operation may be safer about memory order. */ |
422 | -+ rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED); |
423 | -+ __sync_synchronize(); |
424 | ++ __sync_lock_test_and_set(&(lock->writer),RW_LOCK_NOT_LOCKED); |
425 | + } |
426 | +#else |
427 | lock->writer_count--; |
428 | @@ -683,9 +694,15 @@ |
429 | - rw_lock_set_waiters(lock, 0); |
430 | +#ifdef HAVE_ATOMIC_BUILTINS |
431 | + if (last) { |
432 | ++ if(__sync_lock_test_and_set(&lock->s_waiters, 0)){ |
433 | ++ s_sg = TRUE; |
434 | ++ } |
435 | ++ if(__sync_lock_test_and_set(&lock->x_waiters, 0)){ |
436 | ++ x_sg = TRUE; |
437 | ++ } |
438 | ++ } |
439 | +#else |
440 | + if (lock->writer_count == 0) { |
441 | -+#endif |
442 | + if(lock->s_waiters){ |
443 | + s_sg = TRUE; |
444 | + rw_lock_set_s_waiters(lock, 0); |
445 | @@ -696,7 +713,6 @@ |
446 | + } |
447 | } |
448 | |
449 | -+#ifndef HAVE_ATOMIC_BUILTINS |
450 | mutex_exit(&(lock->mutex)); |
451 | +#endif |
452 | |
453 | @@ -715,7 +731,7 @@ |
454 | sync_array_object_signalled(sync_primary_wait_array); |
455 | } |
456 | |
457 | -@@ -494,9 +712,13 @@ |
458 | +@@ -494,9 +726,13 @@ |
459 | |
460 | ut_ad(lock->writer_count > 0); |
461 | |
462 | @@ -729,7 +745,7 @@ |
463 | rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED); |
464 | } |
465 | |
466 | -@@ -504,7 +726,12 @@ |
467 | +@@ -504,7 +740,12 @@ |
468 | rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX); |
469 | #endif |
470 | |
471 | @@ -742,9 +758,9 @@ |
472 | ut_ad(rw_lock_validate(lock)); |
473 | |
474 | #ifdef UNIV_SYNC_PERF_STAT |
475 | -diff -r 962aec0d731c innobase/sync/sync0arr.c |
476 | ---- a/innobase/sync/sync0arr.c Thu Oct 09 08:28:53 2008 -0700 |
477 | -+++ b/innobase/sync/sync0arr.c Thu Oct 09 08:30:28 2008 -0700 |
478 | +diff -ruN a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c |
479 | +--- a/innobase/sync/sync0arr.c 2009-01-30 06:42:24.000000000 +0900 |
480 | ++++ b/innobase/sync/sync0arr.c 2009-04-16 16:15:28.000000000 +0900 |
481 | @@ -309,13 +309,13 @@ |
482 | { |
483 | if (type == SYNC_MUTEX) { |
484 | @@ -877,9 +893,9 @@ |
485 | } |
486 | } |
487 | } |
488 | -diff -r 962aec0d731c innobase/sync/sync0rw.c |
489 | ---- a/innobase/sync/sync0rw.c Thu Oct 09 08:28:53 2008 -0700 |
490 | -+++ b/innobase/sync/sync0rw.c Thu Oct 09 08:30:28 2008 -0700 |
491 | +diff -ruN a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c |
492 | +--- a/innobase/sync/sync0rw.c 2009-01-30 06:42:24.000000000 +0900 |
493 | ++++ b/innobase/sync/sync0rw.c 2009-04-16 17:33:59.000000000 +0900 |
494 | @@ -99,6 +99,7 @@ |
495 | object is created, then the following call initializes |
496 | the sync system. */ |
497 | @@ -1036,7 +1052,7 @@ |
498 | |
499 | - rw_lock_set_waiters(lock, 1); |
500 | + rw_lock_set_s_waiters(lock, 1); |
501 | - |
502 | ++ |
503 | +#ifdef HAVE_ATOMIC_BUILTINS |
504 | + /* like sync0sync.c doing */ |
505 | + for (i = 0; i < 4; i++) { |
506 | @@ -1045,10 +1061,10 @@ |
507 | + return; /* Success */ |
508 | + } |
509 | + } |
510 | -+ |
511 | + |
512 | + /* If wait_ex_waiter stalls, wakes it. */ |
513 | -+ if (lock->wait_ex_waiters && lock->lock_word == RW_LOCK_BIAS) { |
514 | -+ rw_lock_set_wx_waiters(lock, 0); |
515 | ++ if (lock->reader_count == 0 |
516 | ++ && __sync_lock_test_and_set(&lock->wait_ex_waiters, 0)) { |
517 | + os_event_set(lock->wait_ex_event); |
518 | + sync_array_object_signalled(sync_primary_wait_array); |
519 | + } |
520 | @@ -1058,7 +1074,7 @@ |
521 | |
522 | if (srv_print_latch_waits) { |
523 | fprintf(stderr, |
524 | -@@ -318,13 +358,19 @@ |
525 | +@@ -318,13 +365,19 @@ |
526 | { |
527 | ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX)); |
528 | |
529 | @@ -1078,13 +1094,13 @@ |
530 | } |
531 | |
532 | /********************************************************************** |
533 | -@@ -342,6 +388,89 @@ |
534 | +@@ -342,6 +395,89 @@ |
535 | const char* file_name,/* in: file name where lock requested */ |
536 | ulint line) /* in: line where requested */ |
537 | { |
538 | +#ifdef HAVE_ATOMIC_BUILTINS |
539 | + os_thread_id_t curr_thread = os_thread_get_curr_id(); |
540 | -+ |
541 | ++retry_writer: |
542 | + /* try to lock writer */ |
543 | + if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX) |
544 | + == RW_LOCK_NOT_LOCKED) { |
545 | @@ -1160,15 +1176,15 @@ |
546 | + |
547 | + break; |
548 | + |
549 | -+ default: /* ??? */ |
550 | -+ return(RW_LOCK_NOT_LOCKED); |
551 | ++ default: /* RW_LOCK_NOT_LOCKED? maybe impossible */ |
552 | ++ goto retry_writer; |
553 | + } |
554 | +#else /* HAVE_ATOMIC_BUILTINS */ |
555 | + |
556 | #ifdef UNIV_SYNC_DEBUG |
557 | ut_ad(mutex_own(rw_lock_get_mutex(lock))); |
558 | #endif /* UNIV_SYNC_DEBUG */ |
559 | -@@ -423,6 +552,7 @@ |
560 | +@@ -423,6 +559,7 @@ |
561 | /* Locking succeeded, we may return */ |
562 | return(RW_LOCK_EX); |
563 | } |
564 | @@ -1176,7 +1192,7 @@ |
565 | |
566 | /* Locking did not succeed */ |
567 | return(RW_LOCK_NOT_LOCKED); |
568 | -@@ -448,19 +578,33 @@ |
569 | +@@ -448,19 +585,33 @@ |
570 | ulint line) /* in: line where requested */ |
571 | { |
572 | ulint index; /* index of the reserved wait cell */ |
573 | @@ -1211,7 +1227,7 @@ |
574 | if (state == RW_LOCK_EX) { |
575 | |
576 | return; /* Locking succeeded */ |
577 | -@@ -468,10 +612,9 @@ |
578 | +@@ -468,10 +619,9 @@ |
579 | } else if (state == RW_LOCK_NOT_LOCKED) { |
580 | |
581 | /* Spin waiting for the writer field to become free */ |
582 | @@ -1220,11 +1236,11 @@ |
583 | - while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED |
584 | - && i < SYNC_SPIN_ROUNDS) { |
585 | + while (i < SYNC_SPIN_ROUNDS |
586 | -+ && rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) { |
587 | ++ && lock->lock_word != RW_LOCK_BIAS) { |
588 | if (srv_spin_wait_delay) { |
589 | ut_delay(ut_rnd_interval(0, |
590 | srv_spin_wait_delay)); |
591 | -@@ -485,9 +628,12 @@ |
592 | +@@ -485,9 +635,12 @@ |
593 | } else if (state == RW_LOCK_WAIT_EX) { |
594 | |
595 | /* Spin waiting for the reader count field to become zero */ |
596 | @@ -1238,7 +1254,7 @@ |
597 | && i < SYNC_SPIN_ROUNDS) { |
598 | if (srv_spin_wait_delay) { |
599 | ut_delay(ut_rnd_interval(0, |
600 | -@@ -500,7 +646,6 @@ |
601 | +@@ -500,7 +653,6 @@ |
602 | os_thread_yield(); |
603 | } |
604 | } else { |
605 | @@ -1246,7 +1262,7 @@ |
606 | ut_error; |
607 | } |
608 | |
609 | -@@ -516,34 +661,69 @@ |
610 | +@@ -516,34 +668,69 @@ |
611 | /* We try once again to obtain the lock. Acquire the mutex protecting |
612 | the rw-lock fields */ |
613 | |
614 | @@ -1269,7 +1285,7 @@ |
615 | |
616 | return; /* Locking succeeded */ |
617 | } |
618 | -+ |
619 | + |
620 | +#ifdef HAVE_ATOMIC_BUILTINS |
621 | + /* like sync0sync.c doing */ |
622 | + i++; |
623 | @@ -1278,7 +1294,7 @@ |
624 | + goto spin_loop; |
625 | + } |
626 | +#endif |
627 | - |
628 | ++ |
629 | rw_x_system_call_count++; |
630 | |
631 | sync_array_reserve_cell(sync_primary_wait_array, |
632 | @@ -1322,7 +1338,7 @@ |
633 | |
634 | if (srv_print_latch_waits) { |
635 | fprintf(stderr, |
636 | -@@ -718,7 +898,9 @@ |
637 | +@@ -718,7 +905,9 @@ |
638 | ut_ad(lock); |
639 | ut_ad(rw_lock_validate(lock)); |
640 | |
641 | @@ -1332,7 +1348,7 @@ |
642 | |
643 | info = UT_LIST_GET_FIRST(lock->debug_list); |
644 | |
645 | -@@ -728,7 +910,9 @@ |
646 | +@@ -728,7 +917,9 @@ |
647 | && (info->pass == 0) |
648 | && (info->lock_type == lock_type)) { |
649 | |
650 | @@ -1342,7 +1358,7 @@ |
651 | /* Found! */ |
652 | |
653 | return(TRUE); |
654 | -@@ -736,7 +920,9 @@ |
655 | +@@ -736,7 +927,9 @@ |
656 | |
657 | info = UT_LIST_GET_NEXT(list, info); |
658 | } |
659 | @@ -1352,7 +1368,7 @@ |
660 | |
661 | return(FALSE); |
662 | } |
663 | -@@ -758,21 +944,25 @@ |
664 | +@@ -758,21 +951,25 @@ |
665 | ut_ad(lock); |
666 | ut_ad(rw_lock_validate(lock)); |
667 | |
668 | @@ -1379,7 +1395,7 @@ |
669 | |
670 | return(ret); |
671 | } |
672 | -@@ -801,16 +991,26 @@ |
673 | +@@ -801,16 +998,26 @@ |
674 | |
675 | count++; |
676 | |
677 | @@ -1409,7 +1425,7 @@ |
678 | } else { |
679 | putc('\n', stderr); |
680 | } |
681 | -@@ -822,7 +1022,9 @@ |
682 | +@@ -822,7 +1029,9 @@ |
683 | } |
684 | } |
685 | |
686 | @@ -1419,7 +1435,7 @@ |
687 | lock = UT_LIST_GET_NEXT(list, lock); |
688 | } |
689 | |
690 | -@@ -847,10 +1049,18 @@ |
691 | +@@ -847,10 +1056,18 @@ |
692 | |
693 | if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) |
694 | || (rw_lock_get_reader_count(lock) != 0) |
695 | @@ -1441,7 +1457,7 @@ |
696 | } else { |
697 | putc('\n', stderr); |
698 | } |
699 | -@@ -909,14 +1119,18 @@ |
700 | +@@ -909,14 +1126,18 @@ |
701 | lock = UT_LIST_GET_FIRST(rw_lock_list); |
702 | |
703 | while (lock != NULL) { |
704 | @@ -1460,9 +1476,9 @@ |
705 | lock = UT_LIST_GET_NEXT(list, lock); |
706 | } |
707 | |
708 | -diff -r 962aec0d731c patch_info/innodb_rw_lock.info |
709 | ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
710 | -+++ b/patch_info/innodb_rw_lock.info Thu Oct 09 08:30:28 2008 -0700 |
711 | +diff -ruN a/patch_info/innodb_rw_lock.info b/patch_info/innodb_rw_lock.info |
712 | +--- a/patch_info/innodb_rw_lock.info 1970-01-01 09:00:00.000000000 +0900 |
713 | ++++ b/patch_info/innodb_rw_lock.info 2009-04-16 16:15:28.000000000 +0900 |
714 | @@ -0,0 +1,6 @@ |
715 | +File=innodb_rw_lock.patch |
716 | +Name=Fix of InnoDB rw_locks |