~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to include/atomic/generic-msvc.h

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
/*
20
20
  We don't implement anything specific for MY_ATOMIC_MODE_DUMMY, always use
21
21
  intrinsics.
22
 
*/
 
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 >= 1400)
 
34
#include <intrin.h>
 
35
#else
 
36
C_MODE_START
 
37
/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
 
38
LONG _InterlockedExchange (LONG volatile *Target,LONG Value);
 
39
LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
 
40
LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value);
 
41
C_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
 
23
58
#define MY_ATOMIC_MODE "msvc-intrinsics"
24
 
#define IL_EXCHG_ADD32   InterlockedExchangeAdd
25
 
#define IL_COMP_EXCHG32  InterlockedCompareExchange
26
 
#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
27
 
#define IL_EXCHG32       InterlockedExchange
28
 
#define IL_EXCHGptr      InterlockedExchangePointer
 
59
#define IL_EXCHG_ADD32(A,B)    InterlockedExchangeAdd((LONG volatile*)A,B)
 
60
#define IL_COMP_EXCHG32(A,B,C) InterlockedCompareExchange((LONG volatile*)A,B,C)
 
61
#define IL_COMP_EXCHGptr       InterlockedCompareExchangePointer
 
62
#define IL_EXCHG32(A,B)        InterlockedExchange((LONG volatile*)A,B)
 
63
#define IL_EXCHGptr            InterlockedExchangePointer
29
64
#define make_atomic_add_body(S) \
30
65
  v= IL_EXCHG_ADD ## S (a, v)
31
66
#define make_atomic_cas_body(S)                                 \
38
73
  ret= 0; /* avoid compiler warning */ \
39
74
  ret= IL_COMP_EXCHG ## S (a, ret, ret);
40
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
 
 
91
static __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()
41
107
#else /* cleanup */
42
108
 
43
109
#undef IL_EXCHG_ADD32