Skip to content

Commit 8d010c4

Browse files
committed
MDEV-11296 - InnoDB stalls under OLTP RW on P8
Simplified away rw_lock_get_waiters(), rw_lock_set_waiter_flag(), rw_lock_reset_waiter_flag(). Let waiters have predictable data type.
1 parent bb7e84b commit 8d010c4

File tree

5 files changed

+10
-69
lines changed

5 files changed

+10
-69
lines changed

storage/innobase/include/sync0rw.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -484,14 +484,6 @@ ulint
484484
rw_lock_get_sx_lock_count(
485485
/*======================*/
486486
const rw_lock_t* lock); /*!< in: rw-lock */
487-
/********************************************************************//**
488-
Check if there are threads waiting for the rw-lock.
489-
@return 1 if waiters, 0 otherwise */
490-
UNIV_INLINE
491-
ulint
492-
rw_lock_get_waiters(
493-
/*================*/
494-
const rw_lock_t* lock); /*!< in: rw-lock */
495487
/******************************************************************//**
496488
Returns the write-status of the lock - this function made more sense
497489
with the old rw_lock implementation.
@@ -620,7 +612,7 @@ struct rw_lock_t
620612
volatile lint lock_word;
621613

622614
/** 1: there are waiters */
623-
volatile ulint waiters;
615+
volatile uint32_t waiters;
624616

625617
/** Default value FALSE which means the lock is non-recursive.
626618
The value is typically set to TRUE making normal rw_locks recursive.

storage/innobase/include/sync0rw.ic

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -66,52 +66,6 @@ rw_lock_remove_debug_info(
6666
ulint lock_type); /*!< in: lock type */
6767
#endif /* UNIV_DEBUG */
6868

69-
/********************************************************************//**
70-
Check if there are threads waiting for the rw-lock.
71-
@return 1 if waiters, 0 otherwise */
72-
UNIV_INLINE
73-
ulint
74-
rw_lock_get_waiters(
75-
/*================*/
76-
const rw_lock_t* lock) /*!< in: rw-lock */
77-
{
78-
return(lock->waiters);
79-
}
80-
81-
/********************************************************************//**
82-
Sets lock->waiters to 1. It is not an error if lock->waiters is already
83-
1. On platforms where ATOMIC builtins are used this function enforces a
84-
memory barrier. */
85-
UNIV_INLINE
86-
void
87-
rw_lock_set_waiter_flag(
88-
/*====================*/
89-
rw_lock_t* lock) /*!< in/out: rw-lock */
90-
{
91-
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
92-
my_atomic_storelint(&lock->waiters, 1);
93-
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
94-
lock->waiters = 1;
95-
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
96-
}
97-
98-
/********************************************************************//**
99-
Resets lock->waiters to 0. It is not an error if lock->waiters is already
100-
0. On platforms where ATOMIC builtins are used this function enforces a
101-
memory barrier. */
102-
UNIV_INLINE
103-
void
104-
rw_lock_reset_waiter_flag(
105-
/*======================*/
106-
rw_lock_t* lock) /*!< in/out: rw-lock */
107-
{
108-
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
109-
my_atomic_storelint(&lock->waiters, 0);
110-
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
111-
lock->waiters = 0;
112-
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
113-
}
114-
11569
/******************************************************************//**
11670
Returns the write-status of the lock - this function made more sense
11771
with the old rw_lock implementation.
@@ -555,7 +509,7 @@ rw_lock_x_unlock_func(
555509
We do not need to signal wait_ex waiters, since they cannot
556510
exist when there is a writer. */
557511
if (lock->waiters) {
558-
rw_lock_reset_waiter_flag(lock);
512+
my_atomic_store32((int32*) &lock->waiters, 0);
559513
os_event_set(lock->event);
560514
sync_array_object_signalled();
561515
}
@@ -606,7 +560,7 @@ rw_lock_sx_unlock_func(
606560
since they cannot exist when there is an sx-lock
607561
holder. */
608562
if (lock->waiters) {
609-
rw_lock_reset_waiter_flag(lock);
563+
my_atomic_store32((int32*) &lock->waiters, 0);
610564
os_event_set(lock->event);
611565
sync_array_object_signalled();
612566
}

storage/innobase/include/sync0types.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,12 +1258,10 @@ enum rw_lock_flag_t {
12581258

12591259
#ifdef _WIN64
12601260
#define my_atomic_addlint(A,B) my_atomic_add64((int64*) (A), (B))
1261-
#define my_atomic_storelint(A,B) my_atomic_store64((int64*) (A), (B))
12621261
#define my_atomic_loadlint(A) my_atomic_load64((int64*) (A))
12631262
#define my_atomic_caslint(A,B,C) my_atomic_cas64((int64*) (A), (int64*) (B), (C))
12641263
#else
12651264
#define my_atomic_addlint my_atomic_addlong
1266-
#define my_atomic_storelint my_atomic_storelong
12671265
#define my_atomic_loadlint my_atomic_loadlong
12681266
#define my_atomic_caslint my_atomic_caslong
12691267
#endif

storage/innobase/row/row0merge.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,8 +2090,7 @@ row_merge_read_clustered_index(
20902090
}
20912091

20922092
if (dbug_run_purge
2093-
|| rw_lock_get_waiters(
2094-
dict_index_get_lock(clust_index))) {
2093+
|| dict_index_get_lock(clust_index)->waiters) {
20952094
/* There are waiters on the clustered
20962095
index tree lock, likely the purge
20972096
thread. Store and restore the cursor

storage/innobase/sync/sync0rw.cc

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ rw_lock_s_lock_spin(
399399

400400
/* Set waiters before checking lock_word to ensure wake-up
401401
signal is sent. This may lead to some unnecessary signals. */
402-
rw_lock_set_waiter_flag(lock);
402+
my_atomic_store32((int32*) &lock->waiters, 1);
403403

404404
if (rw_lock_s_lock_low(lock, pass, file_name, line)) {
405405

@@ -806,7 +806,7 @@ rw_lock_x_lock_func(
806806

807807
/* Waiters must be set before checking lock_word, to ensure signal
808808
is sent. This could lead to a few unnecessary wake-up signals. */
809-
rw_lock_set_waiter_flag(lock);
809+
my_atomic_store32((int32*) &lock->waiters, 1);
810810

811811
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
812812
sync_array_free_cell(sync_arr, cell);
@@ -911,7 +911,7 @@ rw_lock_sx_lock_func(
911911

912912
/* Waiters must be set before checking lock_word, to ensure signal
913913
is sent. This could lead to a few unnecessary wake-up signals. */
914-
rw_lock_set_waiter_flag(lock);
914+
my_atomic_store32((int32*) &lock->waiters, 1);
915915

916916
if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
917917

@@ -950,16 +950,14 @@ rw_lock_validate(
950950
/*=============*/
951951
const rw_lock_t* lock) /*!< in: rw-lock */
952952
{
953-
ulint waiters;
954953
lint lock_word;
955954

956955
ut_ad(lock);
957956

958-
waiters = rw_lock_get_waiters(lock);
959957
lock_word = lock->lock_word;
960958

961959
ut_ad(lock->magic_n == RW_LOCK_MAGIC_N);
962-
ut_ad(waiters == 0 || waiters == 1);
960+
ut_ad(lock->waiters < 2);
963961
ut_ad(lock_word > -(2 * X_LOCK_DECR));
964962
ut_ad(lock_word <= X_LOCK_DECR);
965963

@@ -1229,7 +1227,7 @@ rw_lock_list_print_info(
12291227

12301228
fprintf(file, "RW-LOCK: %p ", (void*) lock);
12311229

1232-
if (rw_lock_get_waiters(lock)) {
1230+
if (lock->waiters) {
12331231
fputs(" Waiters for the lock exist\n", file);
12341232
} else {
12351233
putc('\n', file);
@@ -1283,7 +1281,7 @@ rw_lock_print(
12831281

12841282
if (lock->lock_word != X_LOCK_DECR) {
12851283

1286-
if (rw_lock_get_waiters(lock)) {
1284+
if (lock->waiters) {
12871285
fputs(" Waiters for the lock exist\n", stderr);
12881286
} else {
12891287
putc('\n', stderr);

0 commit comments

Comments
 (0)