1 #ifndef THR_COND_INCLUDED
2 #define THR_COND_INCLUDED
4 /* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; version 2 of the License.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20 MySQL condition variable implementation.
22 There are three "layers":
24 Functions that map directly down to OS primitives.
25 Windows - ConditionVariable
28 Functions that use SAFE_MUTEX (default for debug).
29 Otherwise native_cond_*() is used.
31 Functions that include Performance Schema instrumentation.
32 See include/mysql/psi/mysql_thread.h
35 #include "my_thread.h"
36 #include "thr_mutex.h"
41 typedef CONDITION_VARIABLE native_cond_t;
43 typedef pthread_cond_t native_cond_t;
48 Convert abstime to milliseconds
51 static DWORD get_milliseconds(const struct timespec *abstime)
53 #ifndef HAVE_STRUCT_TIMESPEC
60 GetSystemTimeAsFileTime(&now.ft);
63 Calculate time left to abstime
64 - subtract start time from current time(values are in 100ns units)
65 - convert to millisec by dividing with 10000
67 millis= (abstime->tv.i64 - now.i64) / 10000;
69 /* Don't allow the timeout to be negative */
74 Make sure the calculated timeout does not exceed original timeout
75 value which could cause "wait for ever" if system time changes
77 if (millis > abstime->max_timeout_msec)
78 millis= abstime->max_timeout_msec;
80 if (millis > UINT_MAX)
86 Convert timespec to millis and subtract current time.
87 my_getsystime() returns time in 100 ns units.
89 ulonglong future= abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000;
90 ulonglong now= my_getsystime() / 10000;
91 /* Don't allow the timeout to be negative. */
94 return (DWORD)(future - now);
99 static inline int native_cond_init(native_cond_t *cond)
102 InitializeConditionVariable(cond);
105 /* pthread_condattr_t is not used in MySQL */
106 return pthread_cond_init(cond, NULL);
110 static inline int native_cond_destroy(native_cond_t *cond)
113 return 0; /* no destroy function */
115 return pthread_cond_destroy(cond);
119 static inline int native_cond_timedwait(native_cond_t *cond,
120 native_mutex_t *mutex,
121 const struct timespec *abstime)
124 DWORD timeout= get_milliseconds(abstime);
125 if (!SleepConditionVariableCS(cond, mutex, timeout))
129 return pthread_cond_timedwait(cond, mutex, abstime);
133 static inline int native_cond_wait(native_cond_t *cond, native_mutex_t *mutex)
136 if (!SleepConditionVariableCS(cond, mutex, INFINITE))
140 return pthread_cond_wait(cond, mutex);
144 static inline int native_cond_signal(native_cond_t *cond)
147 WakeConditionVariable(cond);
150 return pthread_cond_signal(cond);
154 static inline int native_cond_broadcast(native_cond_t *cond)
157 WakeAllConditionVariable(cond);
160 return pthread_cond_broadcast(cond);
165 int safe_cond_wait(native_cond_t *cond, my_mutex_t *mp,
166 const char *file, uint line);
167 int safe_cond_timedwait(native_cond_t *cond, my_mutex_t *mp,
168 const struct timespec *abstime,
169 const char *file, uint line);
172 static inline int my_cond_timedwait(native_cond_t *cond, my_mutex_t *mp,
173 const struct timespec *abstime
175 , const char *file, uint line
180 return safe_cond_timedwait(cond, mp, abstime, file, line);
182 return native_cond_timedwait(cond, mp, abstime);
186 static inline int my_cond_wait(native_cond_t *cond, my_mutex_t *mp
188 , const char *file, uint line
193 return safe_cond_wait(cond, mp, file, line);
195 return native_cond_wait(cond, mp);
201 #endif /* THR_COND_INCLUDED */