summaryrefslogtreecommitdiff
path: root/storage/innobase/include/os0sync.ic
blob: d1307134172164c254b41962b12d6edf60a73295 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/******************************************************
The interface to the operating system synchronization primitives.

(c) 1995 Innobase Oy

Created 9/6/1995 Heikki Tuuri
*******************************************************/

#ifdef __WIN__
#include <winbase.h>
#endif

/**************************************************************
Acquires ownership of a fast mutex. Currently in Windows this is the same
as os_fast_mutex_lock! */
UNIV_INLINE
ulint
os_fast_mutex_trylock(
/*==================*/
						/* out: 0 if success, != 0 if
						was reserved by another
						thread */
	os_fast_mutex_t*	fast_mutex)	/* in: mutex to acquire */
{
#ifdef __WIN__
	EnterCriticalSection(fast_mutex);

	return(0);
#else
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
	/* Since the hot backup version is standalone, MySQL does not redefine
	pthread_mutex_trylock for HP-UX-10.20, and consequently we must invert
	the return value here */

	return((ulint) (1 - pthread_mutex_trylock(fast_mutex)));
#else
	/* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock
	so that it returns 0 on success. In the operating system
	libraries, HP-UX-10.20 follows the old Posix 1003.4a Draft 4 and
	returns 1 on success (but MySQL remaps that to 0), while Linux,
	FreeBSD, Solaris, AIX, Tru64 Unix, HP-UX-11.0 return 0 on success. */

	return((ulint) pthread_mutex_trylock(fast_mutex));
#endif
#endif
}

#ifdef UNIV_SYNC_ATOMIC
/**************************************************************
Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins
or Solaris atomic_* functions. */
UNIV_INLINE
ibool
os_compare_and_swap(
/*================*/
					/* out: true if swapped */
	volatile lint* 	ptr,		/* in: pointer to target */
	lint		oldVal,		/* in: value to compare to */
	lint		newVal)		/* in: value to swap in */
{
#ifdef HAVE_GCC_ATOMIC_BUILTINS
	return (__sync_bool_compare_and_swap(ptr, oldVal, newVal));
#elif HAVE_SOLARIS_ATOMIC
	lint retVal = (lint)atomic_cas_ulong((volatile ulong_t *)ptr,
		oldVal, newVal);
	return (retVal == oldVal);
#elif WIN_ATOMICS32
        lint retVal = (lint)InterlockedCompareExchange(ptr, newVal, oldVal);
        return (retVal == oldVal);
#elif WIN_ATOMICS64
        lint retVal = (lint)InterlockedCompareExchange64(ptr, newVal, oldVal);
        return (retVal == oldVal);
#else
#error "Need support for atomic ops"
#endif
}

/**************************************************************
Memory barrier for load */
UNIV_INLINE
void
os_memory_barrier_load()
{
#ifdef HAVE_GCC_ATOMIC_BUILTINS
  __sync_synchronize();
#elif HAVE_SOLARIS_ATOMIC
  membar_consumer();
#elif WIN_ATOMICS32
  MemoryBarrier();
#elif WIN_ATOMICS64
  MemoryBarrier();
#endif
}

/**************************************************************
Memory barrier for store */
UNIV_INLINE
void
os_memory_barrier_store()
{
#ifdef HAVE_GCC_ATOMIC_BUILTINS
  __sync_synchronize();
#elif HAVE_SOLARIS_ATOMIC
  membar_producer();
#elif WIN_ATOMICS32
  MemoryBarrier();
#elif WIN_ATOMICS64
  MemoryBarrier();
#endif
}

/**************************************************************
Memory barrier */
UNIV_INLINE
void
os_memory_barrier()
{
#ifdef HAVE_GCC_ATOMIC_BUILTINS
  __sync_synchronize();
#elif HAVE_SOLARIS_ATOMIC
  membar_enter();
#elif WIN_ATOMICS32
  MemoryBarrier();
#elif WIN_ATOMICS64
  MemoryBarrier();
#endif
}


/**************************************************************
Atomic increment for InnoDB. Currently requires GCC atomic builtins. */
UNIV_INLINE
lint
os_atomic_increment(
/*================*/
					/* out: resulting value */
	volatile lint*	ptr,		/* in: pointer to target */
	lint		amount)		/* in: amount of increment */
{
#ifdef HAVE_GCC_ATOMIC_BUILTINS
	return (__sync_add_and_fetch(ptr, amount));
#elif HAVE_SOLARIS_ATOMIC
	return ((lint)atomic_add_long_nv((volatile ulong_t *)ptr, amount));
#elif WIN_ATOMICS32
        return ((lint)InterlockedExchangeAdd(ptr, amount) + amount);
#elif WIN_ATOMICS64
        return ((lint)InterlockedExchangeAdd64(ptr, amount) + amount);
#else
#error "Need support for atomic ops"
#endif
}
#endif /* UNIV_SYNC_ATOMIC */