]> git.pld-linux.org Git - packages/mysql.git/blame - mysql-innodb_rw_lock.patch
- up to 5.1.44
[packages/mysql.git] / mysql-innodb_rw_lock.patch
CommitLineData
31696e2e
AM
1diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.h mysql-5.1.29-rc/storage/innobase/include/sync0rw.h
2--- mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.h 2008-10-12 06:54:14.000000000 +0900
3+++ mysql-5.1.29-rc/storage/innobase/include/sync0rw.h 2008-11-17 15:34:00.000000000 +0900
4@@ -328,7 +328,17 @@
5 Accessor functions for rw lock. */
6 UNIV_INLINE
7 ulint
8-rw_lock_get_waiters(
9+rw_lock_get_s_waiters(
10+/*==================*/
11+ rw_lock_t* lock);
12+UNIV_INLINE
13+ulint
14+rw_lock_get_x_waiters(
15+/*==================*/
16+ rw_lock_t* lock);
17+UNIV_INLINE
18+ulint
19+rw_lock_get_wx_waiters(
20 /*================*/
21 rw_lock_t* lock);
22 UNIV_INLINE
23@@ -412,6 +422,11 @@
24 rw_lock_debug_t* info); /* in: debug struct */
25 #endif /* UNIV_SYNC_DEBUG */
26
27+#ifdef HAVE_GCC_ATOMIC_BUILTINS
28+/* This value means NOT_LOCKED */
29+#define RW_LOCK_BIAS 0x00100000
30+#endif
31+
32 /* NOTE! The structure appears here only for the compiler to know its size.
33 Do not use its fields directly! The structure used in the spin lock
34 implementation of a read-write lock. Several threads may have a shared lock
35@@ -421,9 +436,9 @@
36 field. Then no new readers are allowed in. */
37
38 struct rw_lock_struct {
39- os_event_t event; /* Used by sync0arr.c for thread queueing */
40-
41-#ifdef __WIN__
42+ /* Used by sync0arr.c for thread queueing */
43+ os_event_t s_event; /* Used for s_lock */
44+ os_event_t x_event; /* Used for x_lock */
45 os_event_t wait_ex_event; /* This windows specific event is
46 used by the thread which has set the
47 lock state to RW_LOCK_WAIT_EX. The
48@@ -431,30 +446,34 @@
49 thread will be the next one to proceed
50 once the current the event gets
51 signalled. See LEMMA 2 in sync0sync.c */
52+
53+#ifdef HAVE_GCC_ATOMIC_BUILTINS
54+ volatile lint lock_word; /* Used by using atomic builtin */
55 #endif
56
57- ulint reader_count; /* Number of readers who have locked this
58+ volatile ulint reader_count; /* Number of readers who have locked this
59 lock in the shared mode */
60- ulint writer; /* This field is set to RW_LOCK_EX if there
61+ volatile ulint writer; /* This field is set to RW_LOCK_EX if there
62 is a writer owning the lock (in exclusive
63 mode), RW_LOCK_WAIT_EX if a writer is
64 queueing for the lock, and
65 RW_LOCK_NOT_LOCKED, otherwise. */
66- os_thread_id_t writer_thread;
67+ volatile os_thread_id_t writer_thread;
68 /* Thread id of a possible writer thread */
69- ulint writer_count; /* Number of times the same thread has
70+ volatile ulint writer_count; /* Number of times the same thread has
71 recursively locked the lock in the exclusive
72 mode */
73+#ifndef HAVE_GCC_ATOMIC_BUILTINS
74 mutex_t mutex; /* The mutex protecting rw_lock_struct */
75+#endif
76 ulint pass; /* Default value 0. This is set to some
77 value != 0 given by the caller of an x-lock
78 operation, if the x-lock is to be passed to
79 another thread to unlock (which happens in
80 asynchronous i/o). */
81- ulint waiters; /* This ulint is set to 1 if there are
82- waiters (readers or writers) in the global
83- wait array, waiting for this rw_lock.
84- Otherwise, == 0. */
85+ volatile ulint s_waiters; /* 1: there are waiters (s_lock) */
86+ volatile ulint x_waiters; /* 1: there are waiters (x_lock) */
87+ volatile ulint wait_ex_waiters; /* 1: there are waiters (wait_ex) */
88 UT_LIST_NODE_T(rw_lock_t) list;
89 /* All allocated rw locks are put into a
90 list */
91@@ -467,7 +486,7 @@
92 const char* cfile_name;/* File name where lock created */
93 const char* last_s_file_name;/* File name where last s-locked */
94 const char* last_x_file_name;/* File name where last x-locked */
95- ibool writer_is_wait_ex;
96+ volatile ibool writer_is_wait_ex;
97 /* This is TRUE if the writer field is
98 RW_LOCK_WAIT_EX; this field is located far
99 from the memory update hotspot fields which
100diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.ic mysql-5.1.29-rc/storage/innobase/include/sync0rw.ic
101--- mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.ic 2008-10-12 06:54:14.000000000 +0900
102+++ mysql-5.1.29-rc/storage/innobase/include/sync0rw.ic 2008-11-17 16:07:32.000000000 +0900
103@@ -47,20 +47,52 @@
104 Accessor functions for rw lock. */
105 UNIV_INLINE
106 ulint
107-rw_lock_get_waiters(
108+rw_lock_get_s_waiters(
109 /*================*/
110 rw_lock_t* lock)
111 {
112- return(lock->waiters);
113+ return(lock->s_waiters);
114 }
115 UNIV_INLINE
116-void
117-rw_lock_set_waiters(
118+ulint
119+rw_lock_get_x_waiters(
120+/*================*/
121+ rw_lock_t* lock)
122+{
123+ return(lock->x_waiters);
124+}
125+UNIV_INLINE
126+ulint
127+rw_lock_get_wx_waiters(
128 /*================*/
129+ rw_lock_t* lock)
130+{
131+ return(lock->wait_ex_waiters);
132+}
133+UNIV_INLINE
134+void
135+rw_lock_set_s_waiters(
136+ rw_lock_t* lock,
137+ ulint flag)
138+{
139+ lock->s_waiters = flag;
140+}
141+UNIV_INLINE
142+void
143+rw_lock_set_x_waiters(
144 rw_lock_t* lock,
145 ulint flag)
146 {
147- lock->waiters = flag;
148+ lock->x_waiters = flag;
149+}
150+UNIV_INLINE
151+void
152+rw_lock_set_wx_waiters(
153+/*================*/
154+ rw_lock_t* lock,
155+ ulint flag)
156+{
157+ lock->wait_ex_waiters = flag;
158 }
159 UNIV_INLINE
160 ulint
161@@ -68,7 +100,19 @@
162 /*===============*/
163 rw_lock_t* lock)
164 {
165+#ifdef HAVE_GCC_ATOMIC_BUILTINS
166+ if (lock->writer == RW_LOCK_NOT_LOCKED) {
167+ return(RW_LOCK_NOT_LOCKED);
168+ }
169+
170+ if (lock->writer_is_wait_ex) {
171+ return(RW_LOCK_WAIT_EX);
172+ } else {
173+ return(RW_LOCK_EX);
174+ }
175+#else
176 return(lock->writer);
177+#endif
178 }
179 UNIV_INLINE
180 void
181@@ -96,6 +140,7 @@
182 {
183 lock->reader_count = count;
184 }
185+#ifndef HAVE_GCC_ATOMIC_BUILTINS
186 UNIV_INLINE
187 mutex_t*
188 rw_lock_get_mutex(
189@@ -104,6 +149,7 @@
190 {
191 return(&(lock->mutex));
192 }
193+#endif
194
195 /**********************************************************************
196 Returns the value of writer_count for the lock. Does not reserve the lock
197@@ -133,13 +179,27 @@
198 const char* file_name, /* in: file name where lock requested */
199 ulint line) /* in: line where requested */
200 {
201+#ifndef HAVE_GCC_ATOMIC_BUILTINS
202 ut_ad(mutex_own(rw_lock_get_mutex(lock)));
203+#endif
204
205 /* Check if the writer field is free */
206
207+#ifdef HAVE_GCC_ATOMIC_BUILTINS
208+ if (UNIV_LIKELY(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED)) {
209+ /* try s-lock */
210+ if(__sync_sub_and_fetch(&(lock->lock_word),1) <= 0) {
211+ /* fail */
212+ __sync_fetch_and_add(&(lock->lock_word),1);
213+ return(FALSE); /* locking did not succeed */
214+ }
215+ /* success */
216+ __sync_fetch_and_add(&(lock->reader_count),1);
217+#else
218 if (UNIV_LIKELY(lock->writer == RW_LOCK_NOT_LOCKED)) {
219 /* Set the shared lock by incrementing the reader count */
220 lock->reader_count++;
221+#endif
222
223 #ifdef UNIV_SYNC_DEBUG
224 rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name,
225@@ -166,11 +226,15 @@
226 const char* file_name, /* in: file name where requested */
227 ulint line) /* in: line where lock requested */
228 {
229- ut_ad(lock->writer == RW_LOCK_NOT_LOCKED);
230+ ut_ad(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
231 ut_ad(rw_lock_get_reader_count(lock) == 0);
232
233 /* Set the shared lock by incrementing the reader count */
234+#ifdef HAVE_GCC_ATOMIC_BUILTINS
235+ __sync_fetch_and_add(&(lock->reader_count),1);
236+#else
237 lock->reader_count++;
238+#endif
239
240 lock->last_s_file_name = file_name;
241 lock->last_s_line = line;
242@@ -198,7 +262,11 @@
243
244 rw_lock_set_writer(lock, RW_LOCK_EX);
245 lock->writer_thread = os_thread_get_curr_id();
246+#ifdef HAVE_GCC_ATOMIC_BUILTINS
247+ __sync_fetch_and_add(&(lock->writer_count),1);
248+#else
249 lock->writer_count++;
250+#endif
251 lock->pass = 0;
252
253 lock->last_x_file_name = file_name;
254@@ -240,15 +308,21 @@
255 ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */
256 #endif /* UNIV_SYNC_DEBUG */
257
258+#ifndef HAVE_GCC_ATOMIC_BUILTINS
259 mutex_enter(rw_lock_get_mutex(lock));
260+#endif
261
262 if (UNIV_LIKELY(rw_lock_s_lock_low(lock, pass, file_name, line))) {
263+#ifndef HAVE_GCC_ATOMIC_BUILTINS
264 mutex_exit(rw_lock_get_mutex(lock));
265+#endif
266
267 return; /* Success */
268 } else {
269 /* Did not succeed, try spin wait */
270+#ifndef HAVE_GCC_ATOMIC_BUILTINS
271 mutex_exit(rw_lock_get_mutex(lock));
272+#endif
273
274 rw_lock_s_lock_spin(lock, pass, file_name, line);
275
276@@ -271,11 +345,23 @@
277 {
278 ibool success = FALSE;
279
280+#ifdef HAVE_GCC_ATOMIC_BUILTINS
281+ if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
282+ /* try s-lock */
283+ if(__sync_sub_and_fetch(&(lock->lock_word),1) <= 0) {
284+ /* fail */
285+ __sync_fetch_and_add(&(lock->lock_word),1);
286+ return(FALSE); /* locking did not succeed */
287+ }
288+ /* success */
289+ __sync_fetch_and_add(&(lock->reader_count),1);
290+#else
291 mutex_enter(rw_lock_get_mutex(lock));
292
293 if (lock->writer == RW_LOCK_NOT_LOCKED) {
294 /* Set the shared lock by incrementing the reader count */
295 lock->reader_count++;
296+#endif
297
298 #ifdef UNIV_SYNC_DEBUG
299 rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name,
300@@ -288,7 +374,9 @@
301 success = TRUE;
302 }
303
304+#ifndef HAVE_GCC_ATOMIC_BUILTINS
305 mutex_exit(rw_lock_get_mutex(lock));
306+#endif
307
308 return(success);
309 }
310@@ -308,6 +396,55 @@
311 {
312 ibool success = FALSE;
313 os_thread_id_t curr_thread = os_thread_get_curr_id();
314+#ifdef HAVE_GCC_ATOMIC_BUILTINS
315+ if ((lock->lock_word == RW_LOCK_BIAS)
316+ && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
317+ /* try x-lock */
318+ if(__sync_sub_and_fetch(&(lock->lock_word),
319+ RW_LOCK_BIAS) == 0) {
320+ /* success */
321+ /* try to lock writer */
322+ if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
323+ == RW_LOCK_NOT_LOCKED) {
324+ /* success */
325+ lock->writer_thread = curr_thread;
326+ lock->pass = 0;
327+ lock->writer_is_wait_ex = FALSE;
328+ /* next function may work as memory barrier */
329+ relock:
330+ __sync_fetch_and_add(&(lock->writer_count),1);
331+
332+#ifdef UNIV_SYNC_DEBUG
333+ rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
334+#endif
335+
336+ lock->last_x_file_name = file_name;
337+ lock->last_x_line = line;
338+
339+ ut_ad(rw_lock_validate(lock));
340+
341+ return(TRUE);
342+ } else {
343+ /* x-unlock */
344+ __sync_fetch_and_add(&(lock->lock_word),
345+ RW_LOCK_BIAS);
346+ }
347+ } else {
348+ /* fail (x-lock) */
349+ __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS);
350+ }
351+ }
352+
353+ if (lock->pass == 0
354+ && os_thread_eq(lock->writer_thread, curr_thread)
355+ && rw_lock_get_writer(lock) == RW_LOCK_EX) {
356+ goto relock;
357+ }
358+
359+ ut_ad(rw_lock_validate(lock));
360+
361+ return(FALSE);
362+#else
363 mutex_enter(rw_lock_get_mutex(lock));
364
365 if (UNIV_UNLIKELY(rw_lock_get_reader_count(lock) != 0)) {
366@@ -338,6 +475,7 @@
367 ut_ad(rw_lock_validate(lock));
368
369 return(success);
370+#endif
371 }
372
373 /**********************************************************************
374@@ -353,16 +491,33 @@
375 #endif
376 )
377 {
378+#ifndef HAVE_GCC_ATOMIC_BUILTINS
379 mutex_t* mutex = &(lock->mutex);
380- ibool sg = FALSE;
381+#endif
382+ ibool x_sg = FALSE;
383+ ibool wx_sg = FALSE;
384+#ifdef HAVE_GCC_ATOMIC_BUILTINS
385+ ibool last = FALSE;
386+#endif
387
388+#ifndef HAVE_GCC_ATOMIC_BUILTINS
389 /* Acquire the mutex protecting the rw-lock fields */
390 mutex_enter(mutex);
391+#endif
392
393 /* Reset the shared lock by decrementing the reader count */
394
395 ut_a(lock->reader_count > 0);
396+#ifdef HAVE_GCC_ATOMIC_BUILTINS
397+ /* unlock lock_word */
398+ __sync_fetch_and_add(&(lock->lock_word),1);
399+
400+ if(__sync_sub_and_fetch(&(lock->reader_count),1) == 0) {
401+ last = TRUE;
402+ }
403+#else
404 lock->reader_count--;
405+#endif
406
407 #ifdef UNIV_SYNC_DEBUG
408 rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED);
409@@ -371,20 +526,36 @@
410 /* If there may be waiters and this was the last s-lock,
411 signal the object */
412
413- if (UNIV_UNLIKELY(lock->waiters)
414+#ifdef HAVE_GCC_ATOMIC_BUILTINS
415+ if (UNIV_UNLIKELY(last && lock->wait_ex_waiters)) {
416+#else
417+ if (UNIV_UNLIKELY(lock->wait_ex_waiters)
418 && lock->reader_count == 0) {
419- sg = TRUE;
420+#endif
421+ wx_sg = TRUE;
422
423- rw_lock_set_waiters(lock, 0);
424+ rw_lock_set_wx_waiters(lock, 0);
425 }
426+#ifdef HAVE_GCC_ATOMIC_BUILTINS
427+ else if (UNIV_UNLIKELY(last && lock->x_waiters)) {
428+#else
429+ else if (UNIV_UNLIKELY(lock->x_waiters)
430+ && lock->reader_count == 0) {
431+#endif
432+ x_sg = TRUE;
433
434+ rw_lock_set_x_waiters(lock, 0);
435+ }
436+
437+#ifndef HAVE_GCC_ATOMIC_BUILTINS
438 mutex_exit(mutex);
439+#endif
440
441- if (UNIV_UNLIKELY(sg)) {
442-#ifdef __WIN__
443+ if (UNIV_UNLIKELY(wx_sg)) {
444 os_event_set(lock->wait_ex_event);
445-#endif
446- os_event_set(lock->event);
447+ sync_array_object_signalled(sync_primary_wait_array);
448+ } else if (UNIV_UNLIKELY(x_sg)) {
449+ os_event_set(lock->x_event);
450 sync_array_object_signalled(sync_primary_wait_array);
451 }
452
453@@ -408,13 +579,19 @@
454
455 ut_ad(lock->reader_count > 0);
456
457+#ifdef HAVE_GCC_ATOMIC_BUILTINS
458+ __sync_sub_and_fetch(&(lock->reader_count),1);
459+#else
460 lock->reader_count--;
461+#endif
462
463 #ifdef UNIV_SYNC_DEBUG
464 rw_lock_remove_debug_info(lock, 0, RW_LOCK_SHARED);
465 #endif
466
467- ut_ad(!lock->waiters);
468+ ut_ad(!lock->s_waiters);
469+ ut_ad(!lock->x_waiters);
470+ ut_ad(!lock->wait_ex_waiters);
471 ut_ad(rw_lock_validate(lock));
472 #ifdef UNIV_SYNC_PERF_STAT
473 rw_s_exit_count++;
474@@ -434,41 +611,81 @@
475 #endif
476 )
477 {
478- ibool sg = FALSE;
479+#ifdef HAVE_GCC_ATOMIC_BUILTINS
480+ ibool last = FALSE;
481+#endif
482+ ibool s_sg = FALSE;
483+ ibool x_sg = FALSE;
484
485+#ifndef HAVE_GCC_ATOMIC_BUILTINS
486 /* Acquire the mutex protecting the rw-lock fields */
487 mutex_enter(&(lock->mutex));
488+#endif
489
490 /* Reset the exclusive lock if this thread no longer has an x-mode
491 lock */
492
493 ut_ad(lock->writer_count > 0);
494
495+#ifdef HAVE_GCC_ATOMIC_BUILTINS
496+ if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
497+ last = TRUE;
498+ }
499+
500+ if (last) {
501+ /* unlock lock_word */
502+ __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS);
503+
504+ /* FIXME: It is a value of bad manners for pthread.
505+ But we shouldn't keep an ID of not-owner. */
506+ lock->writer_thread = -1;
507+
508+ /* atomic operation may be safer about memory order. */
509+ rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
510+ __sync_synchronize();
511+ }
512+#else
513 lock->writer_count--;
514
515 if (lock->writer_count == 0) {
516 rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
517 }
518+#endif
519
520 #ifdef UNIV_SYNC_DEBUG
521 rw_lock_remove_debug_info(lock, pass, RW_LOCK_EX);
522 #endif
523
524 /* If there may be waiters, signal the lock */
525- if (UNIV_UNLIKELY(lock->waiters)
526- && lock->writer_count == 0) {
527-
528- sg = TRUE;
529- rw_lock_set_waiters(lock, 0);
530+#ifdef HAVE_GCC_ATOMIC_BUILTINS
531+ if (last) {
532+#else
533+ if (lock->writer_count == 0) {
534+#endif
535+ if(lock->s_waiters){
536+ s_sg = TRUE;
537+ rw_lock_set_s_waiters(lock, 0);
538+ }
539+ if(lock->x_waiters){
540+ x_sg = TRUE;
541+ rw_lock_set_x_waiters(lock, 0);
542+ }
543 }
544
545+#ifndef HAVE_GCC_ATOMIC_BUILTINS
546 mutex_exit(&(lock->mutex));
547+#endif
548
549- if (UNIV_UNLIKELY(sg)) {
550+ if (UNIV_UNLIKELY(s_sg)) {
551+ os_event_set(lock->s_event);
552+ sync_array_object_signalled(sync_primary_wait_array);
553+ }
554+ if (UNIV_UNLIKELY(x_sg)) {
555 #ifdef __WIN__
556+ /* I doubt the necessity of it. */
557 os_event_set(lock->wait_ex_event);
558 #endif
559- os_event_set(lock->event);
560+ os_event_set(lock->x_event);
561 sync_array_object_signalled(sync_primary_wait_array);
562 }
563
564@@ -493,9 +710,13 @@
565
566 ut_ad(lock->writer_count > 0);
567
568+#ifdef HAVE_GCC_ATOMIC_BUILTINS
569+ if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
570+#else
571 lock->writer_count--;
572
573 if (lock->writer_count == 0) {
574+#endif
575 rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
576 }
577
578@@ -503,7 +724,9 @@
579 rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
580 #endif
581
582- ut_ad(!lock->waiters);
583+ ut_ad(!lock->s_waiters);
584+ ut_ad(!lock->x_waiters);
585+ ut_ad(!lock->wait_ex_waiters);
586 ut_ad(rw_lock_validate(lock));
587
588 #ifdef UNIV_SYNC_PERF_STAT
589diff -ruN mysql-5.1.29-rc_orig/storage/innobase/sync/sync0arr.c mysql-5.1.29-rc/storage/innobase/sync/sync0arr.c
590--- mysql-5.1.29-rc_orig/storage/innobase/sync/sync0arr.c 2008-10-12 06:54:15.000000000 +0900
591+++ mysql-5.1.29-rc/storage/innobase/sync/sync0arr.c 2008-11-17 16:17:39.000000000 +0900
592@@ -307,13 +307,13 @@
593 {
594 if (type == SYNC_MUTEX) {
595 return(os_event_reset(((mutex_t *) object)->event));
596-#ifdef __WIN__
597 } else if (type == RW_LOCK_WAIT_EX) {
598 return(os_event_reset(
599 ((rw_lock_t *) object)->wait_ex_event));
600-#endif
601- } else {
602- return(os_event_reset(((rw_lock_t *) object)->event));
603+ } else if (type == RW_LOCK_SHARED) {
604+ return(os_event_reset(((rw_lock_t *) object)->s_event));
605+ } else { /* RW_LOCK_EX */
606+ return(os_event_reset(((rw_lock_t *) object)->x_event));
607 }
608 }
609
610@@ -413,15 +413,12 @@
611
612 if (cell->request_type == SYNC_MUTEX) {
613 event = ((mutex_t*) cell->wait_object)->event;
614-#ifdef __WIN__
615- /* On windows if the thread about to wait is the one which
616- has set the state of the rw_lock to RW_LOCK_WAIT_EX, then
617- it waits on a special event i.e.: wait_ex_event. */
618 } else if (cell->request_type == RW_LOCK_WAIT_EX) {
619 event = ((rw_lock_t*) cell->wait_object)->wait_ex_event;
620-#endif
621+ } else if (cell->request_type == RW_LOCK_SHARED) {
622+ event = ((rw_lock_t*) cell->wait_object)->s_event;
623 } else {
624- event = ((rw_lock_t*) cell->wait_object)->event;
625+ event = ((rw_lock_t*) cell->wait_object)->x_event;
626 }
627
628 cell->waiting = TRUE;
629@@ -462,6 +459,7 @@
630 mutex_t* mutex;
631 rw_lock_t* rwlock;
632 ulint type;
633+ ulint writer;
634
635 type = cell->request_type;
636
637@@ -491,12 +489,10 @@
638 (ulong) mutex->waiters);
639
640 } else if (type == RW_LOCK_EX
641-#ifdef __WIN__
642 || type == RW_LOCK_WAIT_EX
643-#endif
644 || type == RW_LOCK_SHARED) {
645
646- fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
647+ fputs(type == RW_LOCK_SHARED ? "S-lock on" : "X-lock on", file);
648
649 rwlock = cell->old_wait_rw_lock;
650
651@@ -504,22 +500,24 @@
652 " RW-latch at %p created in file %s line %lu\n",
653 (void*) rwlock, rwlock->cfile_name,
654 (ulong) rwlock->cline);
655- if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
656+ writer = rw_lock_get_writer(rwlock);
657+ if (writer != RW_LOCK_NOT_LOCKED) {
658 fprintf(file,
659 "a writer (thread id %lu) has"
660 " reserved it in mode %s",
661 (ulong) os_thread_pf(rwlock->writer_thread),
662- rwlock->writer == RW_LOCK_EX
663+ writer == RW_LOCK_EX
664 ? " exclusive\n"
665 : " wait exclusive\n");
666 }
667
668 fprintf(file,
669- "number of readers %lu, waiters flag %lu\n"
670+ "number of readers %lu, s_waiters flag %lu, x_waiters flag %lu\n"
671 "Last time read locked in file %s line %lu\n"
672 "Last time write locked in file %s line %lu\n",
673 (ulong) rwlock->reader_count,
674- (ulong) rwlock->waiters,
675+ (ulong) rwlock->s_waiters,
676+ (ulong) (rwlock->x_waiters || rwlock->wait_ex_waiters),
677 rwlock->last_s_file_name,
678 (ulong) rwlock->last_s_line,
679 rwlock->last_x_file_name,
680@@ -844,11 +842,15 @@
681 /*========================*/
682 sync_array_t* arr) /* in: wait array */
683 {
684+#ifdef HAVE_GCC_ATOMIC_BUILTINS
685+ __sync_fetch_and_add(&(arr->sg_count),1);
686+#else
687 sync_array_enter(arr);
688
689 arr->sg_count++;
690
691 sync_array_exit(arr);
692+#endif
693 }
694
695 /**************************************************************************
696@@ -889,19 +891,23 @@
697
698 mutex = cell->wait_object;
699 os_event_set(mutex->event);
700-#ifdef __WIN__
701 } else if (cell->request_type
702 == RW_LOCK_WAIT_EX) {
703 rw_lock_t* lock;
704
705 lock = cell->wait_object;
706 os_event_set(lock->wait_ex_event);
707-#endif
708- } else {
709+ } else if (cell->request_type
710+ == RW_LOCK_SHARED) {
711 rw_lock_t* lock;
712
713 lock = cell->wait_object;
714- os_event_set(lock->event);
715+ os_event_set(lock->s_event);
716+ } else {
717+ rw_lock_t* lock;
718+
719+ lock = cell->wait_object;
720+ os_event_set(lock->x_event);
721 }
722 }
723 }
724diff -ruN mysql-5.1.29-rc_orig/storage/innobase/sync/sync0rw.c mysql-5.1.29-rc/storage/innobase/sync/sync0rw.c
725--- mysql-5.1.29-rc_orig/storage/innobase/sync/sync0rw.c 2008-10-12 06:54:15.000000000 +0900
726+++ mysql-5.1.29-rc/storage/innobase/sync/sync0rw.c 2008-11-17 17:43:45.000000000 +0900
727@@ -119,6 +119,7 @@
728 /* If this is the very first time a synchronization object is
729 created, then the following call initializes the sync system. */
730
731+#ifndef HAVE_GCC_ATOMIC_BUILTINS
732 mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
733
734 lock->mutex.cfile_name = cfile_name;
735@@ -128,8 +129,14 @@
736 lock->mutex.cmutex_name = cmutex_name;
737 lock->mutex.mutex_type = 1;
738 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
739+#endif /* !HAVE_GCC_ATOMIC_BUILTINS */
740
741- rw_lock_set_waiters(lock, 0);
742+#ifdef HAVE_GCC_ATOMIC_BUILTINS
743+ lock->lock_word = RW_LOCK_BIAS;
744+#endif
745+ rw_lock_set_s_waiters(lock, 0);
746+ rw_lock_set_x_waiters(lock, 0);
747+ rw_lock_set_wx_waiters(lock, 0);
748 rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
749 lock->writer_count = 0;
750 rw_lock_set_reader_count(lock, 0);
751@@ -151,11 +158,9 @@
752 lock->last_x_file_name = "not yet reserved";
753 lock->last_s_line = 0;
754 lock->last_x_line = 0;
755- lock->event = os_event_create(NULL);
756-
757-#ifdef __WIN__
758+ lock->s_event = os_event_create(NULL);
759+ lock->x_event = os_event_create(NULL);
760 lock->wait_ex_event = os_event_create(NULL);
761-#endif
762
763 mutex_enter(&rw_lock_list_mutex);
764
765@@ -181,19 +186,21 @@
766 {
767 ut_ad(rw_lock_validate(lock));
768 ut_a(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
769- ut_a(rw_lock_get_waiters(lock) == 0);
770+ ut_a(rw_lock_get_s_waiters(lock) == 0);
771+ ut_a(rw_lock_get_x_waiters(lock) == 0);
772+ ut_a(rw_lock_get_wx_waiters(lock) == 0);
773 ut_a(rw_lock_get_reader_count(lock) == 0);
774
775 lock->magic_n = 0;
776
777+#ifndef HAVE_GCC_ATOMIC_BUILTINS
778 mutex_free(rw_lock_get_mutex(lock));
779+#endif
780
781 mutex_enter(&rw_lock_list_mutex);
782- os_event_free(lock->event);
783-
784-#ifdef __WIN__
785+ os_event_free(lock->s_event);
786+ os_event_free(lock->x_event);
787 os_event_free(lock->wait_ex_event);
788-#endif
789
790 if (UT_LIST_GET_PREV(list, lock)) {
791 ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
792@@ -212,6 +219,8 @@
793 Checks that the rw-lock has been initialized and that there are no
794 simultaneous shared and exclusive locks. */
795
796+/* MEMO: If HAVE_GCC_ATOMIC_BUILTINS, we should use this function statically. */
797+
798 ibool
799 rw_lock_validate(
800 /*=============*/
801@@ -219,7 +228,9 @@
802 {
803 ut_a(lock);
804
805+#ifndef HAVE_GCC_ATOMIC_BUILTINS
806 mutex_enter(rw_lock_get_mutex(lock));
807+#endif
808
809 ut_a(lock->magic_n == RW_LOCK_MAGIC_N);
810 ut_a((rw_lock_get_reader_count(lock) == 0)
811@@ -227,11 +238,17 @@
812 ut_a((rw_lock_get_writer(lock) == RW_LOCK_EX)
813 || (rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX)
814 || (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED));
815- ut_a((rw_lock_get_waiters(lock) == 0)
816- || (rw_lock_get_waiters(lock) == 1));
817+ ut_a((rw_lock_get_s_waiters(lock) == 0)
818+ || (rw_lock_get_s_waiters(lock) == 1));
819+ ut_a((rw_lock_get_x_waiters(lock) == 0)
820+ || (rw_lock_get_x_waiters(lock) == 1));
821+ ut_a((rw_lock_get_wx_waiters(lock) == 0)
822+ || (rw_lock_get_wx_waiters(lock) == 1));
823 ut_a((lock->writer != RW_LOCK_EX) || (lock->writer_count > 0));
824
825+#ifndef HAVE_GCC_ATOMIC_BUILTINS
826 mutex_exit(rw_lock_get_mutex(lock));
827+#endif
828
829 return(TRUE);
830 }
831@@ -258,13 +275,14 @@
832 ut_ad(rw_lock_validate(lock));
833
834 lock_loop:
835+ i = 0;
836+spin_loop:
837 rw_s_spin_wait_count++;
838
839 /* Spin waiting for the writer field to become free */
840- i = 0;
841
842- while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
843- && i < SYNC_SPIN_ROUNDS) {
844+ while (i < SYNC_SPIN_ROUNDS
845+ && rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
846 if (srv_spin_wait_delay) {
847 ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
848 }
849@@ -285,15 +303,27 @@
850 lock->cfile_name, (ulong) lock->cline, (ulong) i);
851 }
852
853+#ifndef HAVE_GCC_ATOMIC_BUILTINS
854 mutex_enter(rw_lock_get_mutex(lock));
855+#endif
856
857 /* We try once again to obtain the lock */
858
859 if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
860+#ifndef HAVE_GCC_ATOMIC_BUILTINS
861 mutex_exit(rw_lock_get_mutex(lock));
862+#endif
863
864 return; /* Success */
865 } else {
866+#ifdef HAVE_GCC_ATOMIC_BUILTINS
867+ /* like sync0sync.c doing */
868+ i++;
869+
870+ if (i < SYNC_SPIN_ROUNDS) {
871+ goto spin_loop;
872+ }
873+#endif
874 /* If we get here, locking did not succeed, we may
875 suspend the thread to wait in the wait array */
876
877@@ -304,9 +334,19 @@
878 file_name, line,
879 &index);
880
881- rw_lock_set_waiters(lock, 1);
882+ rw_lock_set_s_waiters(lock, 1);
883
884+#ifdef HAVE_GCC_ATOMIC_BUILTINS
885+ /* like sync0sync.c doing */
886+ for (i = 0; i < 4; i++) {
887+ if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
888+ sync_array_free_cell(sync_primary_wait_array, index);
889+ return; /* Success */
890+ }
891+ }
892+#else
893 mutex_exit(rw_lock_get_mutex(lock));
894+#endif
895
896 if (srv_print_latch_waits) {
897 fprintf(stderr,
898@@ -343,13 +383,19 @@
899 {
900 ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
901
902+#ifndef HAVE_GCC_ATOMIC_BUILTINS
903 mutex_enter(&(lock->mutex));
904+#endif
905
906 lock->writer_thread = os_thread_get_curr_id();
907
908 lock->pass = 0;
909
910+#ifndef HAVE_GCC_ATOMIC_BUILTINS
911 mutex_exit(&(lock->mutex));
912+#else
913+ __sync_synchronize();
914+#endif
915 }
916
917 /**********************************************************************
918@@ -367,6 +413,89 @@
919 const char* file_name,/* in: file name where lock requested */
920 ulint line) /* in: line where requested */
921 {
922+#ifdef HAVE_GCC_ATOMIC_BUILTINS
923+ os_thread_id_t curr_thread = os_thread_get_curr_id();
924+
925+ /* try to lock writer */
926+ if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
927+ == RW_LOCK_NOT_LOCKED) {
928+ /* success */
929+ /* obtain RW_LOCK_WAIT_EX right */
930+ lock->writer_thread = curr_thread;
931+ lock->pass = pass;
932+ lock->writer_is_wait_ex = TRUE;
933+ /* atomic operation may be safer about memory order. */
934+ __sync_synchronize();
935+#ifdef UNIV_SYNC_DEBUG
936+ rw_lock_add_debug_info(lock, pass, RW_LOCK_WAIT_EX,
937+ file_name, line);
938+#endif
939+ }
940+
941+ if (!os_thread_eq(lock->writer_thread, curr_thread)) {
942+ return(RW_LOCK_NOT_LOCKED);
943+ }
944+
945+ switch(rw_lock_get_writer(lock)) {
946+ case RW_LOCK_WAIT_EX:
947+ /* have right to try x-lock */
948+ if (lock->lock_word == RW_LOCK_BIAS) {
949+ /* try x-lock */
950+ if(__sync_sub_and_fetch(&(lock->lock_word),
951+ RW_LOCK_BIAS) == 0) {
952+ /* success */
953+ lock->pass = pass;
954+ lock->writer_is_wait_ex = FALSE;
955+ __sync_fetch_and_add(&(lock->writer_count),1);
956+
957+#ifdef UNIV_SYNC_DEBUG
958+ rw_lock_remove_debug_info(lock, pass, RW_LOCK_WAIT_EX);
959+ rw_lock_add_debug_info(lock, pass, RW_LOCK_EX,
960+ file_name, line);
961+#endif
962+
963+ lock->last_x_file_name = file_name;
964+ lock->last_x_line = line;
965+
966+ /* Locking succeeded, we may return */
967+ return(RW_LOCK_EX);
968+ } else {
969+ /* fail */
970+ __sync_fetch_and_add(&(lock->lock_word),
971+ RW_LOCK_BIAS);
972+ }
973+ }
974+ /* There are readers, we have to wait */
975+ return(RW_LOCK_WAIT_EX);
976+
977+ break;
978+
979+ case RW_LOCK_EX:
980+ /* already have x-lock */
981+ if ((lock->pass == 0)&&(pass == 0)) {
982+ __sync_fetch_and_add(&(lock->writer_count),1);
983+
984+#ifdef UNIV_SYNC_DEBUG
985+ rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name,
986+ line);
987+#endif
988+
989+ lock->last_x_file_name = file_name;
990+ lock->last_x_line = line;
991+
992+ /* Locking succeeded, we may return */
993+ return(RW_LOCK_EX);
994+ }
995+
996+ return(RW_LOCK_NOT_LOCKED);
997+
998+ break;
999+
1000+ default: /* ??? */
1001+ return(RW_LOCK_NOT_LOCKED);
1002+ }
1003+#else /* HAVE_GCC_ATOMIC_BUILTINS */
1004+
1005 ut_ad(mutex_own(rw_lock_get_mutex(lock)));
1006
1007 if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
1008@@ -447,6 +576,7 @@
1009 /* Locking succeeded, we may return */
1010 return(RW_LOCK_EX);
1011 }
1012+#endif /* HAVE_GCC_ATOMIC_BUILTINS */
1013
1014 /* Locking did not succeed */
1015 return(RW_LOCK_NOT_LOCKED);
1016@@ -472,19 +602,33 @@
1017 ulint line) /* in: line where requested */
1018 {
1019 ulint index; /* index of the reserved wait cell */
1020- ulint state; /* lock state acquired */
1021+ ulint state = RW_LOCK_NOT_LOCKED; /* lock state acquired */
1022+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1023+ ulint prev_state = RW_LOCK_NOT_LOCKED;
1024+#endif
1025 ulint i; /* spin round count */
1026
1027 ut_ad(rw_lock_validate(lock));
1028
1029 lock_loop:
1030+ i = 0;
1031+
1032+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1033+ prev_state = state;
1034+#else
1035 /* Acquire the mutex protecting the rw-lock fields */
1036 mutex_enter_fast(&(lock->mutex));
1037+#endif
1038
1039 state = rw_lock_x_lock_low(lock, pass, file_name, line);
1040
1041+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1042+ if (state != prev_state) i=0; /* if progress, reset counter. */
1043+#else
1044 mutex_exit(&(lock->mutex));
1045+#endif
1046
1047+spin_loop:
1048 if (state == RW_LOCK_EX) {
1049
1050 return; /* Locking succeeded */
1051@@ -492,10 +636,9 @@
1052 } else if (state == RW_LOCK_NOT_LOCKED) {
1053
1054 /* Spin waiting for the writer field to become free */
1055- i = 0;
1056
1057- while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
1058- && i < SYNC_SPIN_ROUNDS) {
1059+ while (i < SYNC_SPIN_ROUNDS
1060+ && rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
1061 if (srv_spin_wait_delay) {
1062 ut_delay(ut_rnd_interval(0,
1063 srv_spin_wait_delay));
1064@@ -509,9 +652,12 @@
1065 } else if (state == RW_LOCK_WAIT_EX) {
1066
1067 /* Spin waiting for the reader count field to become zero */
1068- i = 0;
1069
1070+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1071+ while (lock->lock_word != RW_LOCK_BIAS
1072+#else
1073 while (rw_lock_get_reader_count(lock) != 0
1074+#endif
1075 && i < SYNC_SPIN_ROUNDS) {
1076 if (srv_spin_wait_delay) {
1077 ut_delay(ut_rnd_interval(0,
1078@@ -524,7 +670,6 @@
1079 os_thread_yield();
1080 }
1081 } else {
1082- i = 0; /* Eliminate a compiler warning */
1083 ut_error;
1084 }
1085
1086@@ -541,34 +686,69 @@
1087 /* We try once again to obtain the lock. Acquire the mutex protecting
1088 the rw-lock fields */
1089
1090+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1091+ prev_state = state;
1092+#else
1093 mutex_enter(rw_lock_get_mutex(lock));
1094+#endif
1095
1096 state = rw_lock_x_lock_low(lock, pass, file_name, line);
1097
1098+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1099+ if (state != prev_state) i=0; /* if progress, reset counter. */
1100+#endif
1101+
1102 if (state == RW_LOCK_EX) {
1103+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1104 mutex_exit(rw_lock_get_mutex(lock));
1105+#endif
1106
1107 return; /* Locking succeeded */
1108 }
1109
1110+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1111+ /* like sync0sync.c doing */
1112+ i++;
1113+
1114+ if (i < SYNC_SPIN_ROUNDS) {
1115+ goto spin_loop;
1116+ }
1117+#endif
1118+
1119 rw_x_system_call_count++;
1120
1121 sync_array_reserve_cell(sync_primary_wait_array,
1122 lock,
1123-#ifdef __WIN__
1124- /* On windows RW_LOCK_WAIT_EX signifies
1125- that this thread should wait on the
1126- special wait_ex_event. */
1127 (state == RW_LOCK_WAIT_EX)
1128 ? RW_LOCK_WAIT_EX :
1129-#endif
1130 RW_LOCK_EX,
1131 file_name, line,
1132 &index);
1133
1134- rw_lock_set_waiters(lock, 1);
1135+ if (state == RW_LOCK_WAIT_EX) {
1136+ rw_lock_set_wx_waiters(lock, 1);
1137+ } else {
1138+ rw_lock_set_x_waiters(lock, 1);
1139+ }
1140
1141+#ifdef HAVE_GCC_ATOMIC_BUILTINS
1142+ /* like sync0sync.c doing */
1143+ for (i = 0; i < 4; i++) {
1144+ prev_state = state;
1145+ state = rw_lock_x_lock_low(lock, pass, file_name, line);
1146+ if (state == RW_LOCK_EX) {
1147+ sync_array_free_cell(sync_primary_wait_array, index);
1148+ return; /* Locking succeeded */
1149+ }
1150+ if (state != prev_state) {
1151+ /* retry! */
1152+ sync_array_free_cell(sync_primary_wait_array, index);
1153+ goto lock_loop;
1154+ }
1155+ }
1156+#else
1157 mutex_exit(rw_lock_get_mutex(lock));
1158+#endif
1159
1160 if (srv_print_latch_waits) {
1161 fprintf(stderr,
1162@@ -730,7 +910,9 @@
1163 ut_ad(lock);
1164 ut_ad(rw_lock_validate(lock));
1165
1166+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1167 mutex_enter(&(lock->mutex));
1168+#endif
1169
1170 info = UT_LIST_GET_FIRST(lock->debug_list);
1171
1172@@ -740,7 +922,9 @@
1173 && (info->pass == 0)
1174 && (info->lock_type == lock_type)) {
1175
1176+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1177 mutex_exit(&(lock->mutex));
1178+#endif
1179 /* Found! */
1180
1181 return(TRUE);
1182@@ -748,7 +932,9 @@
1183
1184 info = UT_LIST_GET_NEXT(list, info);
1185 }
1186+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1187 mutex_exit(&(lock->mutex));
1188+#endif
1189
1190 return(FALSE);
1191 }
1192@@ -770,21 +956,25 @@
1193 ut_ad(lock);
1194 ut_ad(rw_lock_validate(lock));
1195
1196+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1197 mutex_enter(&(lock->mutex));
1198+#endif
1199
1200 if (lock_type == RW_LOCK_SHARED) {
1201 if (lock->reader_count > 0) {
1202 ret = TRUE;
1203 }
1204 } else if (lock_type == RW_LOCK_EX) {
1205- if (lock->writer == RW_LOCK_EX) {
1206+ if (rw_lock_get_writer(lock) == RW_LOCK_EX) {
1207 ret = TRUE;
1208 }
1209 } else {
1210 ut_error;
1211 }
1212
1213+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1214 mutex_exit(&(lock->mutex));
1215+#endif
1216
1217 return(ret);
1218 }
1219@@ -814,16 +1004,26 @@
1220
1221 count++;
1222
1223+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1224 mutex_enter(&(lock->mutex));
1225+#endif
1226
1227 if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
1228 || (rw_lock_get_reader_count(lock) != 0)
1229- || (rw_lock_get_waiters(lock) != 0)) {
1230+ || (rw_lock_get_s_waiters(lock) != 0)
1231+ || (rw_lock_get_x_waiters(lock) != 0)
1232+ || (rw_lock_get_wx_waiters(lock) != 0)) {
1233
1234 fprintf(file, "RW-LOCK: %p ", (void*) lock);
1235
1236- if (rw_lock_get_waiters(lock)) {
1237- fputs(" Waiters for the lock exist\n", file);
1238+ if (rw_lock_get_s_waiters(lock)) {
1239+ fputs(" s_waiters for the lock exist,", file);
1240+ }
1241+ if (rw_lock_get_x_waiters(lock)) {
1242+ fputs(" x_waiters for the lock exist\n", file);
1243+ }
1244+ if (rw_lock_get_wx_waiters(lock)) {
1245+ fputs(" wait_ex_waiters for the lock exist\n", file);
1246 } else {
1247 putc('\n', file);
1248 }
1249@@ -835,7 +1035,9 @@
1250 }
1251 }
1252
1253+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1254 mutex_exit(&(lock->mutex));
1255+#endif
1256 lock = UT_LIST_GET_NEXT(list, lock);
1257 }
1258
1259@@ -860,10 +1062,18 @@
1260
1261 if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
1262 || (rw_lock_get_reader_count(lock) != 0)
1263- || (rw_lock_get_waiters(lock) != 0)) {
1264+ || (rw_lock_get_s_waiters(lock) != 0)
1265+ || (rw_lock_get_x_waiters(lock) != 0)
1266+ || (rw_lock_get_wx_waiters(lock) != 0)) {
1267
1268- if (rw_lock_get_waiters(lock)) {
1269- fputs(" Waiters for the lock exist\n", stderr);
1270+ if (rw_lock_get_s_waiters(lock)) {
1271+ fputs(" s_waiters for the lock exist,", stderr);
1272+ }
1273+ if (rw_lock_get_x_waiters(lock)) {
1274+ fputs(" x_waiters for the lock exist\n", stderr);
1275+ }
1276+ if (rw_lock_get_wx_waiters(lock)) {
1277+ fputs(" wait_ex_waiters for the lock exist\n", stderr);
1278 } else {
1279 putc('\n', stderr);
1280 }
1281@@ -922,14 +1132,18 @@
1282 lock = UT_LIST_GET_FIRST(rw_lock_list);
1283
1284 while (lock != NULL) {
1285+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1286 mutex_enter(rw_lock_get_mutex(lock));
1287+#endif
1288
1289 if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
1290 || (rw_lock_get_reader_count(lock) != 0)) {
1291 count++;
1292 }
1293
1294+#ifndef HAVE_GCC_ATOMIC_BUILTINS
1295 mutex_exit(rw_lock_get_mutex(lock));
1296+#endif
1297 lock = UT_LIST_GET_NEXT(list, lock);
1298 }
1299
1300diff -ruN mysql-5.1.29-rc_orig/patch_info/innodb_rw_lock.info mysql-5.1.29-rc/patch_info/innodb_rw_lock.info
1301--- /dev/null 1970-01-01 09:00:00.000000000 +0900
1302+++ mysql-5.1.29-rc/patch_info/innodb_rw_lock.info 2008-11-17 15:23:46.000000000 +0900
1303@@ -0,0 +1,6 @@
1304+File=innodb_rw_lock.patch
1305+Name=Fix of InnoDB rw_locks
1306+Version=1.0
1307+Author=Yasufumi Kinoshita
1308+License=BSD
1309+Comment=
This page took 0.223168 seconds and 4 git commands to generate.