PageRenderTime 15ms CodeModel.GetById 12ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/External/Mysql-5.0/include/atomic/generic-msvc.h

http://awoe.googlecode.com/
C++ Header | 115 lines | 60 code | 12 blank | 43 comment | 3 complexity | f0de77b830c5e76ccf34d5b6b8535394 MD5 | raw file
  1/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
  2
  3   This program is free software; you can redistribute it and/or modify
  4   it under the terms of the GNU General Public License as published by
  5   the Free Software Foundation; version 2 of the License.
  6
  7   This program is distributed in the hope that it will be useful,
  8   but WITHOUT ANY WARRANTY; without even the implied warranty of
  9   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10   GNU General Public License for more details.
 11
 12   You should have received a copy of the GNU General Public License
 13   along with this program; if not, write to the Free Software
 14   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 15
 16#ifndef _atomic_h_cleanup_
 17#define _atomic_h_cleanup_ "atomic/generic-msvc.h"
 18
 19/*
 20  We don't implement anything specific for MY_ATOMIC_MODE_DUMMY, always use
 21  intrinsics.
 22  8 and 16-bit atomics are not implemented, but it can be done if necessary.
 23*/
 24
 25/*
 26  x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate 
 27  function calls to kernel32 instead, even in the optimized build. 
 28  We force intrinsics as described in MSDN documentation for 
 29  _InterlockedCompareExchange.
 30*/
 31#ifdef _M_IX86
 32
 33#if (_MSC_VER >= 1500)
 34#include <intrin.h>
 35#else
 36C_MODE_START
 37/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
 38LONG _InterlockedExchange (LONG volatile *Target,LONG Value);
 39LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
 40LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value);
 41C_MODE_END
 42
 43#pragma intrinsic(_InterlockedExchangeAdd)
 44#pragma intrinsic(_InterlockedCompareExchange)
 45#pragma intrinsic(_InterlockedExchange)
 46#endif
 47
 48#define InterlockedExchange        _InterlockedExchange
 49#define InterlockedExchangeAdd     _InterlockedExchangeAdd
 50#define InterlockedCompareExchange _InterlockedCompareExchange
 51/*
 52 No need to do something special for InterlockedCompareExchangePointer
 53 as it is a #define to InterlockedCompareExchange. The same applies to
 54 InterlockedExchangePointer. 
 55*/
 56#endif /*_M_IX86*/
 57
 58#define MY_ATOMIC_MODE "msvc-intrinsics"
 59#define IL_EXCHG_ADD32(X,Y)     InterlockedExchangeAdd((volatile LONG *)(X),(Y))
 60#define IL_COMP_EXCHG32(X,Y,Z)  InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
 61#define IL_COMP_EXCHGptr        InterlockedCompareExchangePointer
 62#define IL_EXCHG32(X,Y)         InterlockedExchange((volatile LONG *)(X),(Y))
 63#define IL_EXCHGptr             InterlockedExchangePointer
 64#define make_atomic_add_body(S) \
 65  v= IL_EXCHG_ADD ## S (a, v)
 66#define make_atomic_cas_body(S)                                 \
 67  int ## S initial_cmp= *cmp;                                   \
 68  int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
 69  if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
 70#define make_atomic_swap_body(S) \
 71  v= IL_EXCHG ## S (a, v)
 72#define make_atomic_load_body(S)       \
 73  ret= 0; /* avoid compiler warning */ \
 74  ret= IL_COMP_EXCHG ## S (a, ret, ret);
 75
 76/*
 77  my_yield_processor (equivalent of x86 PAUSE instruction) should be used
 78  to improve performance on hyperthreaded CPUs. Intel recommends to use it in
 79  spin loops also on non-HT machines to reduce power consumption (see e.g 
 80  http://softwarecommunity.intel.com/articles/eng/2004.htm)
 81
 82  Running benchmarks for spinlocks implemented with InterlockedCompareExchange
 83  and YieldProcessor shows that much better performance is achieved by calling
 84  YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting
 85  loop count in the range 200-300 brought best results.
 86 */
 87#ifndef YIELD_LOOPS
 88#define YIELD_LOOPS 200
 89#endif
 90
 91static __inline int my_yield_processor()
 92{
 93  int i;
 94  for(i=0; i<YIELD_LOOPS; i++)
 95  {
 96#if (_MSC_VER <= 1310)
 97    /* On older compilers YieldProcessor is not available, use inline assembly*/
 98    __asm { rep nop }
 99#else
100    YieldProcessor();
101#endif
102  }
103  return 1;
104}
105
106#define LF_BACKOFF my_yield_processor()
107#else /* cleanup */
108
109#undef IL_EXCHG_ADD32
110#undef IL_COMP_EXCHG32
111#undef IL_COMP_EXCHGptr
112#undef IL_EXCHG32
113#undef IL_EXCHGptr
114
115#endif