~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/sync0sync.ic

  • Committer: Monty Taylor
  • Date: 2009-08-12 06:25:19 UTC
  • mto: (1114.1.1 innodb-plugin-merge)
  • mto: This revision was merged to the branch mainline in revision 1183.
  • Revision ID: mordred@inaugust.com-20090812062519-cij02mrrunvnxblt
Tags: innodb-plugin-1.0.4
InnoDB Plugin 1.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
*****************************************************************************/
25
25
 
26
 
/******************************************************
 
26
/**************************************************//**
 
27
@file include/sync0sync.ic
27
28
Mutex, the basic synchronization primitive
28
29
 
29
30
Created 9/5/1995 Heikki Tuuri
30
31
*******************************************************/
31
32
 
32
 
/**********************************************************************
 
33
/******************************************************************//**
33
34
Sets the waiters field in a mutex. */
34
35
UNIV_INTERN
35
36
void
36
37
mutex_set_waiters(
37
38
/*==============*/
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. */
45
46
void
46
47
mutex_spin_wait(
47
48
/*============*/
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
50
51
                                        requested */
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. */
55
56
UNIV_INTERN
56
57
void
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. */
65
66
UNIV_INTERN
66
67
void
67
68
mutex_signal_object(
68
69
/*================*/
69
 
        mutex_t*        mutex); /* in: mutex */
 
70
        mutex_t*        mutex); /*!< in: mutex */
70
71
 
71
 
/**********************************************************************
 
72
/******************************************************************//**
72
73
Performs an atomic test-and-set instruction to the lock_word field of a
73
 
mutex. */
 
74
mutex.
 
75
@return the previous value of lock_word: 0 or 1 */
74
76
UNIV_INLINE
75
77
byte
76
78
mutex_test_and_set(
77
79
/*===============*/
78
 
                                /* out: the previous value of lock_word: 0 or
79
 
                                1 */
80
 
        mutex_t*        mutex)  /* in: mutex */
 
80
        mutex_t*        mutex)  /*!< in: mutex */
81
81
{
82
 
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
83
 
        byte    res;
84
 
        byte*   lw;             /* assembler code is used to ensure that
85
 
                                lock_word is loaded from memory */
86
 
        ut_ad(mutex);
87
 
        ut_ad(sizeof(byte) == 1);
88
 
 
89
 
        lw = &(mutex->lock_word);
90
 
 
91
 
        __asm   MOV     ECX, lw
92
 
                __asm   MOV     EDX, 1
93
 
                __asm   XCHG    DL, BYTE PTR [ECX]
94
 
                __asm   MOV     res, DL
95
 
 
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:
100
 
 
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. */
110
 
 
111
 
                /* mutex_fence(); */
112
 
 
113
 
                return(res);
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));
116
84
#else
117
85
        ibool   ret;
118
86
 
130
98
#endif
131
99
}
132
100
 
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. */
136
104
UNIV_INLINE
137
105
void
138
106
mutex_reset_lock_word(
139
107
/*==================*/
140
 
        mutex_t*        mutex)  /* in: mutex */
 
108
        mutex_t*        mutex)  /*!< in: mutex */
141
109
{
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 */
145
 
        ut_ad(mutex);
146
 
 
147
 
        lw = &(mutex->lock_word);
148
 
 
149
 
        __asm   MOV     EDX, 0
150
 
                __asm   MOV     ECX, lw
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);
157
115
#else
158
116
        mutex->lock_word = 0;
159
117
 
161
119
#endif
162
120
}
163
121
 
164
 
/**********************************************************************
 
122
/******************************************************************//**
165
123
Gets the value of the lock word. */
166
124
UNIV_INLINE
167
 
byte
 
125
lock_word_t
168
126
mutex_get_lock_word(
169
127
/*================*/
170
 
        const mutex_t*  mutex)  /* in: mutex */
 
128
        const mutex_t*  mutex)  /*!< in: mutex */
171
129
{
172
 
        const volatile byte*    ptr;    /* declared volatile to ensure that
173
 
                                        lock_word is loaded from memory */
174
130
        ut_ad(mutex);
175
131
 
176
 
        ptr = &(mutex->lock_word);
177
 
 
178
 
        return(*ptr);
 
132
        return(mutex->lock_word);
179
133
}
180
134
 
181
 
/**********************************************************************
182
 
Gets the waiters field in a mutex. */
 
135
/******************************************************************//**
 
136
Gets the waiters field in a mutex.
 
137
@return value to set */
183
138
UNIV_INLINE
184
139
ulint
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 */
189
143
{
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 */
192
146
        ut_ad(mutex);
193
147
 
197
151
                                word from memory is atomic */
198
152
}
199
153
 
200
 
/**********************************************************************
 
154
/******************************************************************//**
201
155
Unlocks a mutex owned by the current thread. */
202
156
UNIV_INLINE
203
157
void
204
158
mutex_exit(
205
159
/*=======*/
206
 
        mutex_t*        mutex)  /* in: pointer to mutex */
 
160
        mutex_t*        mutex)  /*!< in: pointer to mutex */
207
161
{
208
162
        ut_ad(mutex_own(mutex));
209
163
 
236
190
#endif
237
191
}
238
192
 
239
 
/**********************************************************************
 
193
/******************************************************************//**
240
194
Locks a mutex for the current thread. If the mutex is reserved, the function
241
195
spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting for the mutex
242
196
before suspending the thread. */
244
198
void
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 */
250
204
{
251
205
        ut_ad(mutex_validate(mutex));
252
206
        ut_ad(!mutex_own(mutex));
254
208
        /* Note that we do not peek at the value of lock_word before trying
255
209
        the atomic test_and_set; we could peek, and possibly save time. */
256
210
 
257
 
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
258
 
        mutex->count_using++;
259
 
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
 
211
        ut_d(mutex->count_using++);
260
212
 
261
213
        if (!mutex_test_and_set(mutex)) {
262
214
                ut_d(mutex->thread_id = os_thread_get_curr_id());