MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
os0sync.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2008, Google Inc.
5 
6 Portions of this file contain modifications contributed and copyrighted by
7 Google, Inc. Those modifications are gratefully acknowledged and are described
8 briefly in the InnoDB documentation. The contributions by Google are
9 incorporated with their permission, and subject to the conditions contained in
10 the file COPYING.Google.
11 
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free Software
14 Foundation; version 2 of the License.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc.,
22 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
23 
24 *****************************************************************************/
25 
26 /**************************************************/
34 #ifndef os0sync_h
35 #define os0sync_h
36 
37 #include "univ.i"
38 #include "ut0lst.h"
39 #include "sync0types.h"
40 
41 #ifdef __WIN__
42 
43 typedef HANDLE os_native_event_t;
45 typedef CRITICAL_SECTION fast_mutex_t;
47 typedef CONDITION_VARIABLE os_cond_t;
48 #else
49 
50 typedef pthread_mutex_t fast_mutex_t;
52 typedef pthread_cond_t os_cond_t;
53 #endif
54 
59 #ifdef UNIV_PFS_MUTEX
60  struct PSI_mutex* pfs_psi;
62 #endif
63 };
64 
66 typedef struct os_event* os_event_t;
67 
69 struct os_event {
70 #ifdef __WIN__
71  HANDLE handle;
73 #endif
76  ibool is_set;
80  ib_int64_t signal_count;
84  UT_LIST_NODE_T(os_event_t) os_event_list;
86 };
87 
89 #define OS_SYNC_INFINITE_TIME ULINT_UNDEFINED
90 
92 #define OS_SYNC_TIME_EXCEEDED 1
93 
95 typedef struct os_mutex_t* os_ib_mutex_t;
96 
99 
102 extern ulint os_thread_count;
103 
104 extern ulint os_event_count;
105 extern ulint os_mutex_count;
106 extern ulint os_fast_mutex_count;
107 
108 /*********************************************************/
110 UNIV_INTERN
111 void
112 os_sync_init(void);
113 /*==============*/
114 /*********************************************************/
116 UNIV_INTERN
117 void
118 os_sync_free(void);
119 /*==============*/
120 /*********************************************************/
125 UNIV_INTERN
126 os_event_t
127 os_event_create(void);
128 /*==================*/
129 /**********************************************************/
132 UNIV_INTERN
133 void
135 /*=========*/
136  os_event_t event);
137 /**********************************************************/
144 UNIV_INTERN
145 ib_int64_t
147 /*===========*/
148  os_event_t event);
149 /**********************************************************/
151 UNIV_INTERN
152 void
154 /*==========*/
155  os_event_t event);
157 /**********************************************************/
174 UNIV_INTERN
175 void
177 /*==============*/
178  os_event_t event,
179  ib_int64_t reset_sig_count);
183 #define os_event_wait(event) os_event_wait_low(event, 0)
184 #define os_event_wait_time(event, t) os_event_wait_time_low(event, t, 0)
185 
186 /**********************************************************/
190 UNIV_INTERN
191 ulint
193 /*===================*/
194  os_event_t event,
195  ulint time_in_usec,
198  ib_int64_t reset_sig_count);
201 /*********************************************************/
205 UNIV_INTERN
207 os_mutex_create(void);
208 /*=================*/
209 /**********************************************************/
211 UNIV_INTERN
212 void
214 /*===========*/
215  os_ib_mutex_t mutex);
216 /**********************************************************/
218 UNIV_INTERN
219 void
221 /*==========*/
222  os_ib_mutex_t mutex);
223 /**********************************************************/
225 UNIV_INTERN
226 void
228 /*==========*/
229  os_ib_mutex_t mutex);
230 /**********************************************************/
234 UNIV_INLINE
235 ulint
237 /*==================*/
238  os_fast_mutex_t* fast_mutex);
240 /**********************************************************************
241 Following os_fast_ mutex APIs would be performance schema instrumented:
242 
243 os_fast_mutex_init
244 os_fast_mutex_lock
245 os_fast_mutex_unlock
246 os_fast_mutex_free
247 
248 These mutex APIs will point to corresponding wrapper functions that contain
249 the performance schema instrumentation.
250 
251 NOTE! The following macro should be used in mutex operation, not the
252 corresponding function. */
253 
254 #ifdef UNIV_PFS_MUTEX
255 # define os_fast_mutex_init(K, M) \
256  pfs_os_fast_mutex_init(K, M)
257 
258 # define os_fast_mutex_lock(M) \
259  pfs_os_fast_mutex_lock(M, __FILE__, __LINE__)
260 
261 # define os_fast_mutex_unlock(M) pfs_os_fast_mutex_unlock(M)
262 
263 # define os_fast_mutex_free(M) pfs_os_fast_mutex_free(M)
264 
265 /*********************************************************/
270 UNIV_INLINE
271 void
272 pfs_os_fast_mutex_init(
273 /*===================*/
274  PSI_mutex_key key,
276  os_fast_mutex_t* fast_mutex);
277 /**********************************************************/
282 UNIV_INLINE
283 void
284 pfs_os_fast_mutex_free(
285 /*===================*/
286  os_fast_mutex_t* fast_mutex);
287 /**********************************************************/
291 UNIV_INLINE
292 void
293 pfs_os_fast_mutex_lock(
294 /*===================*/
295  os_fast_mutex_t* fast_mutex,
296  const char* file_name,
298  ulint line);
299 /**********************************************************/
303 UNIV_INLINE
304 void
305 pfs_os_fast_mutex_unlock(
306 /*=====================*/
307  os_fast_mutex_t* fast_mutex);
309 #else /* UNIV_PFS_MUTEX */
310 
311 # define os_fast_mutex_init(K, M) \
312  os_fast_mutex_init_func(&((os_fast_mutex_t*)(M))->mutex)
313 
314 # define os_fast_mutex_lock(M) \
315  os_fast_mutex_lock_func(&((os_fast_mutex_t*)(M))->mutex)
316 
317 # define os_fast_mutex_unlock(M) \
318  os_fast_mutex_unlock_func(&((os_fast_mutex_t*)(M))->mutex)
319 
320 # define os_fast_mutex_free(M) \
321  os_fast_mutex_free_func(&((os_fast_mutex_t*)(M))->mutex)
322 #endif /* UNIV_PFS_MUTEX */
323 
324 /**********************************************************/
326 UNIV_INTERN
327 void
329 /*======================*/
330  fast_mutex_t* fast_mutex);
331 /*********************************************************/
333 UNIV_INTERN
334 void
336 /*====================*/
337  fast_mutex_t* fast_mutex);
338 /**********************************************************/
340 UNIV_INTERN
341 void
343 /*====================*/
344  fast_mutex_t* fast_mutex);
345 /**********************************************************/
347 UNIV_INTERN
348 void
350 /*====================*/
351  fast_mutex_t* fast_mutex);
353 /**********************************************************/
356 #if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
357 
358 # define HAVE_ATOMIC_BUILTINS
359 
360 # ifdef HAVE_IB_GCC_ATOMIC_BUILTINS_64
361 # define HAVE_ATOMIC_BUILTINS_64
362 # endif
363 
364 /**********************************************************/
368 # define os_compare_and_swap(ptr, old_val, new_val) \
369  __sync_bool_compare_and_swap(ptr, old_val, new_val)
370 
371 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
372  os_compare_and_swap(ptr, old_val, new_val)
373 
374 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
375  os_compare_and_swap(ptr, old_val, new_val)
376 
377 # ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
378 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
379  os_compare_and_swap(ptr, old_val, new_val)
380 # define INNODB_RW_LOCKS_USE_ATOMICS
381 # define IB_ATOMICS_STARTUP_MSG \
382  "Mutexes and rw_locks use GCC atomic builtins"
383 # else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
384 # define IB_ATOMICS_STARTUP_MSG \
385  "Mutexes use GCC atomic builtins, rw_locks do not"
386 # endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
387 
388 /**********************************************************/
392 # define os_atomic_increment(ptr, amount) \
393  __sync_add_and_fetch(ptr, amount)
394 
395 # define os_atomic_increment_lint(ptr, amount) \
396  os_atomic_increment(ptr, amount)
397 
398 # define os_atomic_increment_ulint(ptr, amount) \
399  os_atomic_increment(ptr, amount)
400 
401 # define os_atomic_increment_uint64(ptr, amount) \
402  os_atomic_increment(ptr, amount)
403 
404 /* Returns the resulting value, ptr is pointer to target, amount is the
405 amount to decrement. */
406 
407 # define os_atomic_decrement(ptr, amount) \
408  __sync_sub_and_fetch(ptr, amount)
409 
410 # define os_atomic_decrement_lint(ptr, amount) \
411  os_atomic_decrement(ptr, amount)
412 
413 # define os_atomic_decrement_ulint(ptr, amount) \
414  os_atomic_decrement(ptr, amount)
415 
416 # define os_atomic_decrement_uint64(ptr, amount) \
417  os_atomic_decrement(ptr, amount)
418 
419 /**********************************************************/
422 # define os_atomic_test_and_set_byte(ptr, new_val) \
423  __sync_lock_test_and_set(ptr, (byte) new_val)
424 
425 # define os_atomic_test_and_set_ulint(ptr, new_val) \
426  __sync_lock_test_and_set(ptr, new_val)
427 
428 #elif defined(HAVE_IB_SOLARIS_ATOMICS)
429 
430 # define HAVE_ATOMIC_BUILTINS
431 # define HAVE_ATOMIC_BUILTINS_64
432 
433 /* If not compiling with GCC or GCC doesn't support the atomic
434 intrinsics and running on Solaris >= 10 use Solaris atomics */
435 
436 # include <atomic.h>
437 
438 /**********************************************************/
442 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
443  (atomic_cas_ulong(ptr, old_val, new_val) == old_val)
444 
445 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
446  ((lint) atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
447 
448 # ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
449 # if SIZEOF_PTHREAD_T == 4
450 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
451  ((pthread_t) atomic_cas_32(ptr, old_val, new_val) == old_val)
452 # elif SIZEOF_PTHREAD_T == 8
453 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
454  ((pthread_t) atomic_cas_64(ptr, old_val, new_val) == old_val)
455 # else
456 # error "SIZEOF_PTHREAD_T != 4 or 8"
457 # endif /* SIZEOF_PTHREAD_T CHECK */
458 # define INNODB_RW_LOCKS_USE_ATOMICS
459 # define IB_ATOMICS_STARTUP_MSG \
460  "Mutexes and rw_locks use Solaris atomic functions"
461 # else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
462 # define IB_ATOMICS_STARTUP_MSG \
463  "Mutexes use Solaris atomic functions, rw_locks do not"
464 # endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
465 
466 /**********************************************************/
470 # define os_atomic_increment_ulint(ptr, amount) \
471  atomic_add_long_nv(ptr, amount)
472 
473 # define os_atomic_increment_lint(ptr, amount) \
474  os_atomic_increment_ulint((ulong_t*) ptr, amount)
475 
476 # define os_atomic_increment_uint64(ptr, amount) \
477  atomic_add_64_nv(ptr, amount)
478 
479 /* Returns the resulting value, ptr is pointer to target, amount is the
480 amount to decrement. */
481 
482 # define os_atomic_decrement_lint(ptr, amount) \
483  os_atomic_increment_ulint((ulong_t*) ptr, -(amount))
484 
485 # define os_atomic_decrement_ulint(ptr, amount) \
486  os_atomic_increment_ulint(ptr, -(amount))
487 
488 # define os_atomic_decrement_uint64(ptr, amount) \
489  os_atomic_increment_uint64(ptr, -(amount))
490 
491 /**********************************************************/
494 # define os_atomic_test_and_set_byte(ptr, new_val) \
495  atomic_swap_uchar(ptr, new_val)
496 
497 # define os_atomic_test_and_set_ulint(ptr, new_val) \
498  atomic_swap_ulong(ptr, new_val)
499 
500 #elif defined(HAVE_WINDOWS_ATOMICS)
501 
502 # define HAVE_ATOMIC_BUILTINS
503 
504 # ifndef _WIN32
505 # define HAVE_ATOMIC_BUILTINS_64
506 # endif
507 
508 /**********************************************************/
512 UNIV_INLINE
513 lint
514 win_cmp_and_xchg_lint(
515 /*==================*/
516  volatile lint* ptr,
517  lint new_val,
518  lint old_val);
520 /**********************************************************/
523 UNIV_INLINE
524 lint
525 win_xchg_and_add(
526 /*=============*/
527  volatile lint* ptr,
528  lint val);
530 /**********************************************************/
534 UNIV_INLINE
535 ulint
536 win_cmp_and_xchg_ulint(
537 /*===================*/
538  volatile ulint* ptr,
539  ulint new_val,
540  ulint old_val);
542 /**********************************************************/
546 UNIV_INLINE
547 DWORD
548 win_cmp_and_xchg_dword(
549 /*===================*/
550  volatile DWORD* ptr,
551  DWORD new_val,
552  DWORD old_val);
554 /**********************************************************/
558 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
559  (win_cmp_and_xchg_ulint(ptr, new_val, old_val) == old_val)
560 
561 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
562  (win_cmp_and_xchg_lint(ptr, new_val, old_val) == old_val)
563 
564 /* windows thread objects can always be passed to windows atomic functions */
565 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
566  (win_cmp_and_xchg_dword(ptr, new_val, old_val) == old_val)
567 
568 # define INNODB_RW_LOCKS_USE_ATOMICS
569 # define IB_ATOMICS_STARTUP_MSG \
570  "Mutexes and rw_locks use Windows interlocked functions"
571 
572 /**********************************************************/
576 # define os_atomic_increment_lint(ptr, amount) \
577  (win_xchg_and_add(ptr, amount) + amount)
578 
579 # define os_atomic_increment_ulint(ptr, amount) \
580  ((ulint) (win_xchg_and_add((lint*) ptr, (lint) amount) + amount))
581 
582 # define os_atomic_increment_uint64(ptr, amount) \
583  ((ib_uint64_t) (InterlockedExchangeAdd64( \
584  (ib_int64_t*) ptr, \
585  (ib_int64_t) amount) + amount))
586 
587 /**********************************************************/
591 # define os_atomic_decrement_lint(ptr, amount) \
592  (win_xchg_and_add(ptr, -(lint) amount) - amount)
593 
594 # define os_atomic_decrement_ulint(ptr, amount) \
595  ((ulint) (win_xchg_and_add((lint*) ptr, -(lint) amount) - amount))
596 
597 # define os_atomic_decrement_uint64(ptr, amount) \
598  ((ib_uint64_t) (InterlockedExchangeAdd64( \
599  (ib_int64_t*) ptr, \
600  -(ib_int64_t) amount) - amount))
601 
602 /**********************************************************/
607 # define os_atomic_test_and_set_byte(ptr, new_val) \
608  ((byte) InterlockedExchange(ptr, new_val))
609 
610 # define os_atomic_test_and_set_ulong(ptr, new_val) \
611  InterlockedExchange(ptr, new_val)
612 
613 #else
614 # define IB_ATOMICS_STARTUP_MSG \
615  "Mutexes and rw_locks use InnoDB's own implementation"
616 #endif
617 #ifdef HAVE_ATOMIC_BUILTINS
618 #define os_atomic_inc_ulint(m,v,d) os_atomic_increment_ulint(v, d)
619 #define os_atomic_dec_ulint(m,v,d) os_atomic_decrement_ulint(v, d)
620 #else
621 #define os_atomic_inc_ulint(m,v,d) os_atomic_inc_ulint_func(m, v, d)
622 #define os_atomic_dec_ulint(m,v,d) os_atomic_dec_ulint_func(m, v, d)
623 #endif /* HAVE_ATOMIC_BUILTINS */
624 
625 /**********************************************************/
629 #ifdef HAVE_ATOMIC_BUILTINS
630 #define os_increment_counter_by_amount(mutex, counter, amount) \
631  (void) os_atomic_increment_ulint(&counter, amount)
632 
633 #define os_decrement_counter_by_amount(mutex, counter, amount) \
634  (void) os_atomic_increment_ulint(&counter, (-((lint) amount)))
635 #else
636 #define os_increment_counter_by_amount(mutex, counter, amount) \
637  do { \
638  mutex_enter(&(mutex)); \
639  (counter) += (amount); \
640  mutex_exit(&(mutex)); \
641  } while (0)
642 
643 #define os_decrement_counter_by_amount(mutex, counter, amount) \
644  do { \
645  ut_a(counter >= amount); \
646  mutex_enter(&(mutex)); \
647  (counter) -= (amount); \
648  mutex_exit(&(mutex)); \
649  } while (0)
650 #endif /* HAVE_ATOMIC_BUILTINS */
651 
652 #define os_inc_counter(mutex, counter) \
653  os_increment_counter_by_amount(mutex, counter, 1)
654 
655 #define os_dec_counter(mutex, counter) \
656  do { \
657  os_decrement_counter_by_amount(mutex, counter, 1);\
658  } while (0);
659 
660 #ifndef UNIV_NONINL
661 #include "os0sync.ic"
662 #endif
663 
664 #endif