thr_cond.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #ifndef THR_COND_INCLUDED
  2. #define THR_COND_INCLUDED
  3. /* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License, version 2.0,
  6. as published by the Free Software Foundation.
  7. This program is also distributed with certain software (including
  8. but not limited to OpenSSL) that is licensed under separate terms,
  9. as designated in a particular file or component or in included license
  10. documentation. The authors of MySQL hereby grant you an additional
  11. permission to link the program and your derivative works with the
  12. separately licensed software that they have included with MySQL.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License, version 2.0, for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
  20. /**
  21. @file include/thr_cond.h
  22. MySQL condition variable implementation.
  23. There are three "layers":
  24. 1) native_cond_*()
  25. Functions that map directly down to OS primitives.
  26. Windows - ConditionVariable
  27. Other OSes - pthread
  28. 2) my_cond_*()
  29. Functions that use SAFE_MUTEX (default for debug).
  30. Otherwise native_cond_*() is used.
  31. 3) mysql_cond*()
  32. Functions that include Performance Schema instrumentation.
  33. See include/mysql/psi/mysql_thread.h
  34. */
  35. #include <stddef.h>
  36. #include <sys/types.h>
  37. #ifdef _WIN32
  38. #include <time.h>
  39. #include "my_systime.h"
  40. #endif
  41. #include "my_macros.h"
  42. #include "my_thread.h"
  43. #include "mysql/components/services/thr_cond_bits.h"
  44. #include "thr_mutex.h"
  45. #ifdef _WIN32
  46. /**
  47. Convert abstime to milliseconds
  48. */
  49. static DWORD get_milliseconds(const struct timespec *abstime) {
  50. /*
  51. Convert timespec to millis and subtract current time.
  52. my_getsystime() returns time in 100 ns units.
  53. */
  54. ulonglong future = abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000;
  55. ulonglong now = my_getsystime() / 10000;
  56. /* Don't allow the timeout to be negative. */
  57. if (future < now) return 0;
  58. return (DWORD)(future - now);
  59. }
  60. #endif /* _WIN32 */
  61. static inline int native_cond_init(native_cond_t *cond) {
  62. #ifdef _WIN32
  63. InitializeConditionVariable(cond);
  64. return 0;
  65. #else
  66. /* pthread_condattr_t is not used in MySQL */
  67. return pthread_cond_init(cond, NULL);
  68. #endif
  69. }
  70. static inline int native_cond_destroy(
  71. native_cond_t *cond MY_ATTRIBUTE((unused))) {
  72. #ifdef _WIN32
  73. return 0; /* no destroy function */
  74. #else
  75. return pthread_cond_destroy(cond);
  76. #endif
  77. }
  78. static inline int native_cond_timedwait(native_cond_t *cond,
  79. native_mutex_t *mutex,
  80. const struct timespec *abstime) {
  81. #ifdef _WIN32
  82. DWORD timeout = get_milliseconds(abstime);
  83. if (!SleepConditionVariableCS(cond, mutex, timeout)) return ETIMEDOUT;
  84. return 0;
  85. #else
  86. return pthread_cond_timedwait(cond, mutex, abstime);
  87. #endif
  88. }
  89. static inline int native_cond_wait(native_cond_t *cond, native_mutex_t *mutex) {
  90. #ifdef _WIN32
  91. if (!SleepConditionVariableCS(cond, mutex, INFINITE)) return ETIMEDOUT;
  92. return 0;
  93. #else
  94. return pthread_cond_wait(cond, mutex);
  95. #endif
  96. }
  97. static inline int native_cond_signal(native_cond_t *cond) {
  98. #ifdef _WIN32
  99. WakeConditionVariable(cond);
  100. return 0;
  101. #else
  102. return pthread_cond_signal(cond);
  103. #endif
  104. }
  105. static inline int native_cond_broadcast(native_cond_t *cond) {
  106. #ifdef _WIN32
  107. WakeAllConditionVariable(cond);
  108. return 0;
  109. #else
  110. return pthread_cond_broadcast(cond);
  111. #endif
  112. }
  113. #ifdef SAFE_MUTEX
  114. int safe_cond_wait(native_cond_t *cond, safe_mutex_t *mp, const char *file,
  115. uint line);
  116. int safe_cond_timedwait(native_cond_t *cond, safe_mutex_t *mp,
  117. const struct timespec *abstime, const char *file,
  118. uint line);
  119. #endif
  120. static inline int my_cond_timedwait(native_cond_t *cond, my_mutex_t *mp,
  121. const struct timespec *abstime
  122. #ifdef SAFE_MUTEX
  123. ,
  124. const char *file, uint line
  125. #endif
  126. ) {
  127. #ifdef SAFE_MUTEX
  128. return safe_cond_timedwait(cond, mp->m_u.m_safe_ptr, abstime, file, line);
  129. #else
  130. return native_cond_timedwait(cond, &mp->m_u.m_native, abstime);
  131. #endif
  132. }
  133. static inline int my_cond_wait(native_cond_t *cond, my_mutex_t *mp
  134. #ifdef SAFE_MUTEX
  135. ,
  136. const char *file, uint line
  137. #endif
  138. ) {
  139. #ifdef SAFE_MUTEX
  140. return safe_cond_wait(cond, mp->m_u.m_safe_ptr, file, line);
  141. #else
  142. return native_cond_wait(cond, &mp->m_u.m_native);
  143. #endif
  144. }
  145. #endif /* THR_COND_INCLUDED */