Drizzled Public API Documentation

os0sync.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003 Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
00004 Copyright (C) 2008, Google Inc.
00005 
00006 Portions of this file contain modifications contributed and copyrighted by
00007 Google, Inc. Those modifications are gratefully acknowledged and are described
00008 briefly in the InnoDB documentation. The contributions by Google are
00009 incorporated with their permission, and subject to the conditions contained in
00010 the file COPYING.Google.
00011 
00012 This program is free software; you can redistribute it and/or modify it under
00013 the terms of the GNU General Public License as published by the Free Software
00014 Foundation; version 2 of the License.
00015 
00016 This program is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License along with
00021 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
00022 St, Fifth Floor, Boston, MA 02110-1301 USA
00023 
00024 *****************************************************************************/
00025 
00026 /**************************************************/
00034 #pragma once
00035 #ifndef os0sync_h
00036 #define os0sync_h
00037 
00038 #include "univ.i"
00039 #include "ut0lst.h"
00040 
00041 #ifdef __WIN__
00042 
00043 typedef HANDLE      os_native_event_t;
00045 typedef CRITICAL_SECTION  os_fast_mutex_t;
00047 typedef CONDITION_VARIABLE  os_cond_t;
00048 #else
00049 
00050 typedef pthread_mutex_t   os_fast_mutex_t;
00052 typedef pthread_cond_t    os_cond_t;
00053 #endif
00054 
00056 typedef struct os_event_struct  os_event_struct_t;
00058 typedef os_event_struct_t*  os_event_t;
00059 
00061 struct os_event_struct {
00062 #ifdef __WIN__
00063   HANDLE    handle;   
00065 #endif
00066   os_fast_mutex_t os_mutex; 
00068   ibool   is_set;   
00072   ib_int64_t  signal_count; 
00074   os_cond_t cond_var; 
00076   UT_LIST_NODE_T(os_event_struct_t) os_event_list;
00078 };
00079 
00081 #define OS_SYNC_INFINITE_TIME   ULINT_UNDEFINED
00082 
00084 #define OS_SYNC_TIME_EXCEEDED   1
00085 
00087 typedef struct os_mutex_struct  os_mutex_str_t;
00089 typedef os_mutex_str_t*   os_mutex_t;
00090 
00092 extern os_mutex_t os_sync_mutex;
00093 
00096 extern ulint    os_thread_count;
00097 
00098 extern ulint    os_event_count;
00099 extern ulint    os_mutex_count;
00100 extern ulint    os_fast_mutex_count;
00101 
00102 /*********************************************************/
00104 UNIV_INTERN
00105 void
00106 os_sync_init(void);
00107 /*==============*/
00108 /*********************************************************/
00110 UNIV_INTERN
00111 void
00112 os_sync_free(void);
00113 /*==============*/
00114 /*********************************************************/
00119 UNIV_INTERN
00120 os_event_t
00121 os_event_create(
00122 /*============*/
00123   const char* name);  
00125 /**********************************************************/
00128 UNIV_INTERN
00129 void
00130 os_event_set(
00131 /*=========*/
00132   os_event_t  event); 
00133 /**********************************************************/
00140 UNIV_INTERN
00141 ib_int64_t
00142 os_event_reset(
00143 /*===========*/
00144   os_event_t  event); 
00145 /**********************************************************/
00147 UNIV_INTERN
00148 void
00149 os_event_free(
00150 /*==========*/
00151   os_event_t  event); 
00153 /**********************************************************/
00173 UNIV_INTERN
00174 void
00175 os_event_wait_low(
00176 /*==============*/
00177   os_event_t  event,    
00178   ib_int64_t  reset_sig_count);
00182 #define os_event_wait(event) os_event_wait_low(event, 0)
00183 #define os_event_wait_time(e, t) os_event_wait_time_low(event, t, 0)
00184 
00185 /**********************************************************/
00189 UNIV_INTERN
00190 ulint
00191 os_event_wait_time_low(
00192 /*===================*/
00193   os_event_t  event,      
00194   ulint   time_in_usec,   
00197   ib_int64_t  reset_sig_count); 
00200 /*********************************************************/
00204 UNIV_INTERN
00205 os_mutex_t
00206 os_mutex_create(void);
00207 /*=================*/
00208 /**********************************************************/
00210 UNIV_INTERN
00211 void
00212 os_mutex_enter(
00213 /*===========*/
00214   os_mutex_t  mutex); 
00215 /**********************************************************/
00217 UNIV_INTERN
00218 void
00219 os_mutex_exit(
00220 /*==========*/
00221   os_mutex_t  mutex); 
00222 /**********************************************************/
00224 UNIV_INTERN
00225 void
00226 os_mutex_free(
00227 /*==========*/
00228   os_mutex_t  mutex); 
00229 /**********************************************************/
00233 UNIV_INLINE
00234 ulint
00235 os_fast_mutex_trylock(
00236 /*==================*/
00237   os_fast_mutex_t*  fast_mutex);  
00238 /**********************************************************/
00240 UNIV_INTERN
00241 void
00242 os_fast_mutex_unlock(
00243 /*=================*/
00244   os_fast_mutex_t*  fast_mutex);  
00245 /*********************************************************/
00247 UNIV_INTERN
00248 void
00249 os_fast_mutex_init(
00250 /*===============*/
00251   os_fast_mutex_t*  fast_mutex);  
00252 /**********************************************************/
00254 UNIV_INTERN
00255 void
00256 os_fast_mutex_lock(
00257 /*===============*/
00258   os_fast_mutex_t*  fast_mutex);  
00259 /**********************************************************/
00261 UNIV_INTERN
00262 void
00263 os_fast_mutex_free(
00264 /*===============*/
00265   os_fast_mutex_t*  fast_mutex);  
00267 /**********************************************************/
00270 #if defined(HAVE_GCC_ATOMIC_BUILTINS)
00271 
00272 #define HAVE_ATOMIC_BUILTINS
00273 
00274 /**********************************************************/
00278 # define os_compare_and_swap(ptr, old_val, new_val) \
00279   __sync_bool_compare_and_swap(ptr, old_val, new_val)
00280 
00281 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
00282   os_compare_and_swap(ptr, old_val, new_val)
00283 
00284 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
00285   os_compare_and_swap(ptr, old_val, new_val)
00286 
00287 # ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
00288 #  define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00289   os_compare_and_swap(ptr, old_val, new_val)
00290 #  define INNODB_RW_LOCKS_USE_ATOMICS
00291 #  define IB_ATOMICS_STARTUP_MSG \
00292   "Mutexes and rw_locks use GCC atomic builtins"
00293 # else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
00294 #  define IB_ATOMICS_STARTUP_MSG \
00295   "Mutexes use GCC atomic builtins, rw_locks do not"
00296 # endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
00297 
00298 /**********************************************************/
00302 # define os_atomic_increment(ptr, amount) \
00303   __sync_add_and_fetch(ptr, amount)
00304 
00305 # define os_atomic_increment_lint(ptr, amount) \
00306   os_atomic_increment(ptr, amount)
00307 
00308 # define os_atomic_increment_ulint(ptr, amount) \
00309   os_atomic_increment(ptr, amount)
00310 
00311 /**********************************************************/
00314 # define os_atomic_test_and_set_byte(ptr, new_val) \
00315   __sync_lock_test_and_set(ptr, (byte) new_val)
00316 
00317 #elif defined(HAVE_SOLARIS_ATOMICS)
00318 
00319 #define HAVE_ATOMIC_BUILTINS
00320 
00321 /* If not compiling with GCC or GCC doesn't support the atomic
00322 intrinsics and running on Solaris >= 10 use Solaris atomics */
00323 
00324 #include <atomic.h>
00325 
00326 /**********************************************************/
00330 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
00331   (atomic_cas_ulong(ptr, old_val, new_val) == old_val)
00332 
00333 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
00334   ((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
00335 
00336 # ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
00337 #  if SIZEOF_PTHREAD_T == 4
00338 #   define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00339   ((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
00340 #  elif SIZEOF_PTHREAD_T == 8
00341 #   define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00342   ((pthread_t)atomic_cas_64(ptr, old_val, new_val) == old_val)
00343 #  else
00344 #   error "SIZEOF_PTHREAD_T != 4 or 8"
00345 #  endif /* SIZEOF_PTHREAD_T CHECK */
00346 #  define INNODB_RW_LOCKS_USE_ATOMICS
00347 #  define IB_ATOMICS_STARTUP_MSG \
00348   "Mutexes and rw_locks use Solaris atomic functions"
00349 # else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
00350 #  define IB_ATOMICS_STARTUP_MSG \
00351   "Mutexes use Solaris atomic functions, rw_locks do not"
00352 # endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
00353 
00354 /**********************************************************/
00358 # define os_atomic_increment_lint(ptr, amount) \
00359   atomic_add_long_nv((ulong_t*) ptr, amount)
00360 
00361 # define os_atomic_increment_ulint(ptr, amount) \
00362   atomic_add_long_nv(ptr, amount)
00363 
00364 /**********************************************************/
00367 # define os_atomic_test_and_set_byte(ptr, new_val) \
00368   atomic_swap_uchar(ptr, new_val)
00369 
00370 #elif defined(HAVE_WINDOWS_ATOMICS)
00371 
00372 #define HAVE_ATOMIC_BUILTINS
00373 
00374 /* On Windows, use Windows atomics / interlocked */
00375 # ifdef _WIN64
00376 #  define win_cmp_and_xchg InterlockedCompareExchange64
00377 #  define win_xchg_and_add InterlockedExchangeAdd64
00378 # else /* _WIN64 */
00379 #  define win_cmp_and_xchg InterlockedCompareExchange
00380 #  define win_xchg_and_add InterlockedExchangeAdd
00381 # endif
00382 
00383 /**********************************************************/
00387 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
00388   (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
00389 
00390 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
00391   (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
00392 
00393 /* windows thread objects can always be passed to windows atomic functions */
00394 # define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
00395   (InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
00396 # define INNODB_RW_LOCKS_USE_ATOMICS
00397 # define IB_ATOMICS_STARTUP_MSG \
00398   "Mutexes and rw_locks use Windows interlocked functions"
00399 
00400 /**********************************************************/
00404 # define os_atomic_increment_lint(ptr, amount) \
00405   (win_xchg_and_add(ptr, amount) + amount)
00406 
00407 # define os_atomic_increment_ulint(ptr, amount) \
00408   ((ulint) (win_xchg_and_add(ptr, amount) + amount))
00409 
00410 /**********************************************************/
00415 # define os_atomic_test_and_set_byte(ptr, new_val) \
00416   ((byte) InterlockedExchange(ptr, new_val))
00417 
00418 #else
00419 # define IB_ATOMICS_STARTUP_MSG \
00420   "Mutexes and rw_locks use InnoDB's own implementation"
00421 #endif
00422 
00423 #ifndef UNIV_NONINL
00424 #include "os0sync.ic"
00425 #endif
00426 
00427 #endif