mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 15:50:51 +03:00 
			
		
		
		
	Fix for Percona reported bug with manual merge and fix of bug in
patch (changed to use of UNIV_SYNC_ATOMIC from faulty HAVE_ATOMIC_BUILTINS).
This commit is contained in:
		| @@ -57,10 +57,25 @@ UNIV_INLINE | |||||||
| void | void | ||||||
| rw_lock_set_waiters( | rw_lock_set_waiters( | ||||||
| /*================*/ | /*================*/ | ||||||
| 	rw_lock_t*	lock, | 	rw_lock_t*	lock) | ||||||
| 	ulint		flag) |  | ||||||
| { | { | ||||||
| 	lock->waiters = flag; | #ifdef UNIV_SYNC_ATOMIC | ||||||
|  | 	os_compare_and_swap(&(lock->waiters), 0, 1); | ||||||
|  | #else /* UNIV_SYNC_ATOMIC */ | ||||||
|  | 	lock->waiters = 1; | ||||||
|  | #endif /* UNIV_SYNC_ATOMIC */ | ||||||
|  | } | ||||||
|  | UNIV_INLINE | ||||||
|  | void | ||||||
|  | rw_lock_reset_waiters( | ||||||
|  | /*================*/ | ||||||
|  | 	rw_lock_t*	lock) | ||||||
|  | { | ||||||
|  | #ifdef UNIV_SYNC_ATOMIC | ||||||
|  | 	os_compare_and_swap(&(lock->waiters), 1, 0); | ||||||
|  | #else /* UNIV_SYNC_ATOMIC */ | ||||||
|  | 	lock->waiters = 0; | ||||||
|  | #endif /* UNIV_SYNC_ATOMIC */ | ||||||
| } | } | ||||||
|  |  | ||||||
| /********************************************************************** | /********************************************************************** | ||||||
| @@ -454,7 +469,7 @@ rw_lock_s_unlock_direct( | |||||||
| 	/* Decrease reader count by incrementing lock_word */ | 	/* Decrease reader count by incrementing lock_word */ | ||||||
| 	lock->lock_word++; | 	lock->lock_word++; | ||||||
|  |  | ||||||
| 	ut_ad(!lock->waiters); | 	ut_ad(!rw_lock_get_waiters(lock)); | ||||||
| 	ut_ad(rw_lock_validate(lock)); | 	ut_ad(rw_lock_validate(lock)); | ||||||
| #ifdef UNIV_SYNC_PERF_STAT | #ifdef UNIV_SYNC_PERF_STAT | ||||||
| 	rw_s_exit_count++; | 	rw_s_exit_count++; | ||||||
| @@ -494,8 +509,8 @@ rw_lock_x_unlock_func( | |||||||
| 		/* Lock is now free. May have to signal read/write waiters. | 		/* Lock is now free. May have to signal read/write waiters. | ||||||
|                 We do not need to signal wait_ex waiters, since they cannot |                 We do not need to signal wait_ex waiters, since they cannot | ||||||
|                 exist when there is a writer. */ |                 exist when there is a writer. */ | ||||||
| 		if(lock->waiters) { | 		if(rw_lock_get_waiters(lock)) { | ||||||
| 			rw_lock_set_waiters(lock, 0); | 			rw_lock_reset_waiters(lock); | ||||||
| 			os_event_set(lock->event); | 			os_event_set(lock->event); | ||||||
| 			sync_array_object_signalled(sync_primary_wait_array); | 			sync_array_object_signalled(sync_primary_wait_array); | ||||||
| 		} | 		} | ||||||
| @@ -532,7 +547,7 @@ rw_lock_x_unlock_direct( | |||||||
|  |  | ||||||
| 	lock->lock_word += X_LOCK_DECR; | 	lock->lock_word += X_LOCK_DECR; | ||||||
|  |  | ||||||
| 	ut_ad(!lock->waiters); | 	ut_ad(!rw_lock_get_waiters(lock)); | ||||||
| 	ut_ad(rw_lock_validate(lock)); | 	ut_ad(rw_lock_validate(lock)); | ||||||
|  |  | ||||||
| #ifdef UNIV_SYNC_PERF_STAT | #ifdef UNIV_SYNC_PERF_STAT | ||||||
|   | |||||||
| @@ -549,7 +549,8 @@ sync_array_find_thread( | |||||||
| 		cell = sync_array_get_nth_cell(arr, i); | 		cell = sync_array_get_nth_cell(arr, i); | ||||||
|  |  | ||||||
| 		if (cell->wait_object != NULL | 		if (cell->wait_object != NULL | ||||||
| 		    && os_thread_eq(cell->thread, thread)) { | 		    && os_thread_eq(cell->thread, thread) | ||||||
|  | 		    && cell->waiting)) { | ||||||
|  |  | ||||||
| 			return(cell);	/* Found */ | 			return(cell);	/* Found */ | ||||||
| 		} | 		} | ||||||
| @@ -887,6 +888,10 @@ sync_arr_wake_threads_if_sema_free(void) | |||||||
| 		} | 		} | ||||||
| 			count++; | 			count++; | ||||||
|  |  | ||||||
|  | 		if (!cell->waiting) { | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 			if (sync_arr_cell_can_wake_up(cell)) { | 			if (sync_arr_cell_can_wake_up(cell)) { | ||||||
|  |  | ||||||
| 			event = sync_cell_get_event(cell); | 			event = sync_cell_get_event(cell); | ||||||
|   | |||||||
| @@ -209,7 +209,7 @@ rw_lock_create_func( | |||||||
| #endif /* UNIV_SYNC_ATOMIC */ | #endif /* UNIV_SYNC_ATOMIC */ | ||||||
|  |  | ||||||
| 	lock->lock_word = X_LOCK_DECR; | 	lock->lock_word = X_LOCK_DECR; | ||||||
| 	rw_lock_set_waiters(lock, 0); | 	lock->waiters = 0; | ||||||
| 	lock->writer_thread = -1; | 	lock->writer_thread = -1; | ||||||
| 	lock->pass = 0; | 	lock->pass = 0; | ||||||
|  |  | ||||||
| @@ -369,7 +369,7 @@ lock_loop: | |||||||
|  |  | ||||||
| 		/* Set waiters before checking lock_word to ensure wake-up | 		/* Set waiters before checking lock_word to ensure wake-up | ||||||
|                 signal is sent. This may lead to some unnecessary signals. */ |                 signal is sent. This may lead to some unnecessary signals. */ | ||||||
| 		rw_lock_set_waiters(lock, 1); | 		rw_lock_set_waiters(lock); | ||||||
|  |  | ||||||
| 		if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) { | 		if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) { | ||||||
| 			sync_array_free_cell(sync_primary_wait_array, index); | 			sync_array_free_cell(sync_primary_wait_array, index); | ||||||
| @@ -634,7 +634,7 @@ lock_loop: | |||||||
|  |  | ||||||
| 	/* Waiters must be set before checking lock_word, to ensure signal | 	/* Waiters must be set before checking lock_word, to ensure signal | ||||||
| 	is sent. This could lead to a few unnecessary wake-up signals. */ | 	is sent. This could lead to a few unnecessary wake-up signals. */ | ||||||
| 	rw_lock_set_waiters(lock, 1); | 	rw_lock_set_waiters(lock); | ||||||
|  |  | ||||||
| 	if (rw_lock_x_lock_low(lock, pass, file_name, line)) { | 	if (rw_lock_x_lock_low(lock, pass, file_name, line)) { | ||||||
| 		sync_array_free_cell(sync_primary_wait_array, index); | 		sync_array_free_cell(sync_primary_wait_array, index); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user