24
24
*****************************************************************************/
26
/******************************************************
26
/**************************************************//**
27
@file include/sync0sync.ic
27
28
Mutex, the basic synchronization primitive
29
30
Created 9/5/1995 Heikki Tuuri
30
31
*******************************************************/
32
/**********************************************************************
33
/******************************************************************//**
33
34
Sets the waiters field in a mutex. */
38
mutex_t* mutex, /* in: mutex */
39
ulint n); /* in: value to set */
40
/**********************************************************************
39
mutex_t* mutex, /*!< in: mutex */
40
ulint n); /*!< in: value to set */
41
/******************************************************************//**
41
42
Reserves a mutex for the current thread. If the mutex is reserved, the
42
43
function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting
43
44
for the mutex before suspending the thread. */
48
mutex_t* mutex, /* in: pointer to mutex */
49
const char* file_name, /* in: file name where mutex
49
mutex_t* mutex, /*!< in: pointer to mutex */
50
const char* file_name, /*!< in: file name where mutex
51
ulint line); /* in: line where requested */
52
ulint line); /*!< in: line where requested */
52
53
#ifdef UNIV_SYNC_DEBUG
53
/**********************************************************************
54
/******************************************************************//**
54
55
Sets the debug information for a reserved mutex. */
57
58
mutex_set_debug_info(
58
59
/*=================*/
59
mutex_t* mutex, /* in: mutex */
60
const char* file_name, /* in: file where requested */
61
ulint line); /* in: line where requested */
60
mutex_t* mutex, /*!< in: mutex */
61
const char* file_name, /*!< in: file where requested */
62
ulint line); /*!< in: line where requested */
62
63
#endif /* UNIV_SYNC_DEBUG */
63
/**********************************************************************
64
/******************************************************************//**
64
65
Releases the threads waiting in the primary wait array for this mutex. */
67
68
mutex_signal_object(
68
69
/*================*/
69
mutex_t* mutex); /* in: mutex */
70
mutex_t* mutex); /*!< in: mutex */
71
/**********************************************************************
72
/******************************************************************//**
72
73
Performs an atomic test-and-set instruction to the lock_word field of a
75
@return the previous value of lock_word: 0 or 1 */
76
78
mutex_test_and_set(
77
79
/*===============*/
78
/* out: the previous value of lock_word: 0 or
80
mutex_t* mutex) /* in: mutex */
80
mutex_t* mutex) /*!< in: mutex */
82
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
84
byte* lw; /* assembler code is used to ensure that
85
lock_word is loaded from memory */
87
ut_ad(sizeof(byte) == 1);
89
lw = &(mutex->lock_word);
93
__asm XCHG DL, BYTE PTR [ECX]
96
/* The fence below would prevent this thread from
97
reading the data structure protected by the mutex
98
before the test-and-set operation is committed, but
99
the fence is apparently not needed:
101
In a posting to comp.arch newsgroup (August 10, 1997)
102
Andy Glew said that in P6 a LOCKed instruction like
103
XCHG establishes a fence with respect to memory reads
104
and writes and thus an explicit fence is not
105
needed. In P5 he seemed to agree with a previous
106
newsgroup poster that LOCKed instructions serialize
107
all instruction execution, and, consequently, also
108
memory operations. This is confirmed in Intel Software
109
Dev. Manual, Vol. 3. */
114
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
115
return __sync_lock_test_and_set(&(mutex->lock_word), 1);
82
#if defined(HAVE_ATOMIC_BUILTINS)
83
return(os_atomic_test_and_set_byte(&mutex->lock_word, 1));
133
/**********************************************************************
101
/******************************************************************//**
134
102
Performs a reset instruction to the lock_word field of a mutex. This
135
103
instruction also serializes memory operations to the program order. */
138
106
mutex_reset_lock_word(
139
107
/*==================*/
140
mutex_t* mutex) /* in: mutex */
108
mutex_t* mutex) /*!< in: mutex */
142
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
143
byte* lw; /* assembler code is used to ensure that
144
lock_word is loaded from memory */
147
lw = &(mutex->lock_word);
151
__asm XCHG DL, BYTE PTR [ECX]
152
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
110
#if defined(HAVE_ATOMIC_BUILTINS)
153
111
/* In theory __sync_lock_release should be used to release the lock.
154
112
Unfortunately, it does not work properly alone. The workaround is
155
113
that more conservative __sync_lock_test_and_set is used instead. */
156
__sync_lock_test_and_set(&(mutex->lock_word), 0);
114
os_atomic_test_and_set_byte(&mutex->lock_word, 0);
158
116
mutex->lock_word = 0;
164
/**********************************************************************
122
/******************************************************************//**
165
123
Gets the value of the lock word. */
168
126
mutex_get_lock_word(
169
127
/*================*/
170
const mutex_t* mutex) /* in: mutex */
128
const mutex_t* mutex) /*!< in: mutex */
172
const volatile byte* ptr; /* declared volatile to ensure that
173
lock_word is loaded from memory */
176
ptr = &(mutex->lock_word);
132
return(mutex->lock_word);
181
/**********************************************************************
182
Gets the waiters field in a mutex. */
135
/******************************************************************//**
136
Gets the waiters field in a mutex.
137
@return value to set */
185
140
mutex_get_waiters(
186
141
/*==============*/
187
/* out: value to set */
188
const mutex_t* mutex) /* in: mutex */
142
const mutex_t* mutex) /*!< in: mutex */
190
const volatile ulint* ptr; /* declared volatile to ensure that
144
const volatile ulint* ptr; /*!< declared volatile to ensure that
191
145
the value is read from memory */
245
199
mutex_enter_func(
246
200
/*=============*/
247
mutex_t* mutex, /* in: pointer to mutex */
248
const char* file_name, /* in: file name where locked */
249
ulint line) /* in: line where locked */
201
mutex_t* mutex, /*!< in: pointer to mutex */
202
const char* file_name, /*!< in: file name where locked */
203
ulint line) /*!< in: line where locked */
251
205
ut_ad(mutex_validate(mutex));
252
206
ut_ad(!mutex_own(mutex));