Re: Fix performance of generic atomics

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: Sokolov Yura <funny.falcon@postgrespro.ru>
Cc: pgsql-hackers@postgresql.org
Date: 2017-05-25T14:39:13Z
Lists: pgsql-hackers
Sokolov Yura <funny.falcon@postgrespro.ru> writes:
@@ -382,12 +358,8 @@ static inline uint64
 pg_atomic_fetch_and_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 and_)
 {
 	uint64 old;
-	while (true)
-	{
-		old = pg_atomic_read_u64_impl(ptr);
-		if (pg_atomic_compare_exchange_u64_impl(ptr, &old, old & and_))
-			break;
-	}
+	old = pg_atomic_read_u64_impl(ptr);
+	while (!pg_atomic_compare_exchange_u64_impl(ptr, &old, old & and_));
 	return old;
 }
 #endif

FWIW, I do not think that writing the loops like that is good style.
It looks like a typo and will confuse readers.  You could perhaps
write the same code with better formatting, eg

	while (!pg_atomic_compare_exchange_u64_impl(ptr, &old, old & and_))
		/* skip */ ;

but why not leave the formulation with while(true) and a break alone?

(I take no position on whether moving the read of "old" outside the
loop is a valid optimization.)

			regards, tom lane


Commits

  1. Further marginal hacking on generic atomic ops.

  2. Use more of gcc's __sync_fetch_and_xxx builtin functions for atomic ops.

  3. Remove duplicate reads from the inner loops in generic atomic ops.