]> git.pld-linux.org Git - packages/mysql.git/blob - mysql-innodb_rw_lock.patch
- up to 5.1.44
[packages/mysql.git] / mysql-innodb_rw_lock.patch
1 diff -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
100 diff -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
589 diff -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                 }
724 diff -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  
1300 diff -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.179869 seconds and 3 git commands to generate.