You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.6 KiB

  1. /* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; version 2 of the License.
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License
  10. along with this program; if not, write to the Free Software Foundation,
  11. 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
  12. /**
  13. @file storage/perfschema/pfs_atomic.cc
  14. Atomic operations (implementation).
  15. */
  16. #include <my_global.h>
  17. #include <my_pthread.h>
  18. #include "pfs_atomic.h"
  19. /*
  20. Using SAFE_MUTEX is impossible, because of recursion.
  21. - code locks mutex X
  22. - P_S records the event
  23. - P_S needs an atomic counter A
  24. - safe mutex called for m_mutex[hash(A)]
  25. - safe mutex allocates/free memory
  26. - safe mutex locks THR_LOCK_malloc
  27. - P_S records the event
  28. - P_S needs an atomic counter B
  29. - safe mutex called for m_mutex[hash(B)]
  30. When hash(A) == hash(B), safe_mutex complains rightly that
  31. the mutex is already locked.
  32. In some cases, A == B, in particular for events_waits_history_long_index.
  33. In short, the implementation of PFS_atomic should not cause events
  34. to be recorded in the performance schema.
  35. Also, because SAFE_MUTEX redefines pthread_mutex_t, etc,
  36. this code is not inlined in pfs_atomic.h, but located here in pfs_atomic.cc.
  37. What is needed is a plain, unmodified, pthread_mutex_t.
  38. This is provided by my_atomic_rwlock_t.
  39. */
  40. /**
  41. Internal rwlock array.
  42. Using a single rwlock for all atomic operations would be a bottleneck.
  43. Using a rwlock per performance schema structure would be too costly in
  44. memory, and use too many rwlock.
  45. The PFS_atomic implementation computes a hash value from the
  46. atomic variable, to spread the bottleneck across 256 buckets,
  47. while still providing --transparently for the caller-- an atomic
  48. operation.
  49. */
  50. my_atomic_rwlock_t PFS_atomic::m_rwlock_array[256];
  51. static int init_done;
  52. void PFS_atomic::init(void)
  53. {
  54. uint i;
  55. for (i=0; i< array_elements(m_rwlock_array); i++)
  56. my_atomic_rwlock_init(&m_rwlock_array[i]);
  57. init_done= 1;
  58. }
  59. void PFS_atomic::cleanup(void)
  60. {
  61. uint i;
  62. if (!init_done)
  63. return;
  64. for (i=0; i< array_elements(m_rwlock_array); i++)
  65. my_atomic_rwlock_destroy(&m_rwlock_array[i]);
  66. }