Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbb65cb8

Browse files
committed
Use __sync_lock_test_and_set() for spinlocks on ARM, if available.
Historically we've used the SWPB instruction for TAS() on ARM, but thisis deprecated and not available on ARMv6 and later. Instead, make useof a GCC builtin if available. We'll still fall back to SWPB if not,so as not to break existing ports using older GCC versions.Eventually we might want to try using __sync_lock_test_and_set() on someother architectures too, but for now that seems to present only risk andnot reward.Back-patch to all supported versions, since people might want to use anyof them on more recent ARM chips.Martin Pitt
1 parent1f996ad commitbb65cb8

File tree

4 files changed

+102
-2
lines changed

4 files changed

+102
-2
lines changed

‎configure

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22108,6 +22108,71 @@ fi
2210822108
done
2210922109

2211022110

22111+
{ $as_echo "$as_me:$LINENO: checking for builtin locking functions" >&5
22112+
$as_echo_n "checking for builtin locking functions... " >&6; }
22113+
if test "${pgac_cv_gcc_int_atomics+set}" = set; then
22114+
$as_echo_n "(cached) " >&6
22115+
else
22116+
cat >conftest.$ac_ext <<_ACEOF
22117+
/* confdefs.h. */
22118+
_ACEOF
22119+
cat confdefs.h >>conftest.$ac_ext
22120+
cat >>conftest.$ac_ext <<_ACEOF
22121+
/* end confdefs.h. */
22122+
22123+
int
22124+
main ()
22125+
{
22126+
int lock = 0;
22127+
__sync_lock_test_and_set(&lock, 1);
22128+
__sync_lock_release(&lock);
22129+
;
22130+
return 0;
22131+
}
22132+
_ACEOF
22133+
rm -f conftest.$ac_objext conftest$ac_exeext
22134+
if { (ac_try="$ac_link"
22135+
case "(($ac_try" in
22136+
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
22137+
*) ac_try_echo=$ac_try;;
22138+
esac
22139+
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
22140+
$as_echo "$ac_try_echo") >&5
22141+
(eval "$ac_link") 2>conftest.er1
22142+
ac_status=$?
22143+
grep -v '^ *+' conftest.er1 >conftest.err
22144+
rm -f conftest.er1
22145+
cat conftest.err >&5
22146+
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
22147+
(exit $ac_status); } && {
22148+
test -z "$ac_c_werror_flag" ||
22149+
test ! -s conftest.err
22150+
} && test -s conftest$ac_exeext && {
22151+
test "$cross_compiling" = yes ||
22152+
$as_test_x conftest$ac_exeext
22153+
}; then
22154+
pgac_cv_gcc_int_atomics="yes"
22155+
else
22156+
$as_echo "$as_me: failed program was:" >&5
22157+
sed 's/^/| /' conftest.$ac_ext >&5
22158+
22159+
pgac_cv_gcc_int_atomics="no"
22160+
fi
22161+
22162+
rm -rf conftest.dSYM
22163+
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
22164+
conftest$ac_exeext conftest.$ac_ext
22165+
fi
22166+
{ $as_echo "$as_me:$LINENO: result: $pgac_cv_gcc_int_atomics" >&5
22167+
$as_echo "$pgac_cv_gcc_int_atomics" >&6; }
22168+
if test x"$pgac_cv_gcc_int_atomics" = x"yes"; then
22169+
22170+
cat >>confdefs.h <<\_ACEOF
22171+
#define HAVE_GCC_INT_ATOMICS 1
22172+
_ACEOF
22173+
22174+
fi
22175+
2211122176

2211222177
#
2211322178
# Pthreads

‎configure.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,17 @@ AC_CHECK_FUNCS(atexit, [],
14031403
[AC_CHECK_FUNCS(on_exit, [],
14041404
[AC_MSG_ERROR([neither atexit() nor on_exit() found])])])
14051405

1406+
AC_CACHE_CHECK([for builtin locking functions], pgac_cv_gcc_int_atomics,
1407+
[AC_TRY_LINK([],
1408+
[int lock = 0;
1409+
__sync_lock_test_and_set(&lock, 1);
1410+
__sync_lock_release(&lock);],
1411+
[pgac_cv_gcc_int_atomics="yes"],
1412+
[pgac_cv_gcc_int_atomics="no"])])
1413+
if test x"$pgac_cv_gcc_int_atomics" = x"yes"; then
1414+
AC_DEFINE(HAVE_GCC_INT_ATOMICS, 1, [Define to 1 if you have __sync_lock_test_and_set(int *) and friends.])
1415+
fi
1416+
14061417

14071418
#
14081419
# Pthreads

‎src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@
173173
/* Define to 1 if your compiler understands __FUNCTION__. */
174174
#undef HAVE_FUNCNAME__FUNCTION
175175

176+
/* Define to 1 if you have __sync_lock_test_and_set(int *) and friends. */
177+
#undef HAVE_GCC_INT_ATOMICS
178+
176179
/* Define to 1 if you have the `getaddrinfo' function. */
177180
#undef HAVE_GETADDRINFO
178181

‎src/include/storage/s_lock.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,33 @@ tas(volatile slock_t *lock)
252252
#endif/* __ia64__ || __ia64 */
253253

254254

255+
/*
256+
* On ARM, we use __sync_lock_test_and_set(int *, int) if available, and if
257+
* not fall back on the SWPB instruction. SWPB does not work on ARMv6 or
258+
* later, so the compiler builtin is preferred if available. Note also that
259+
* the int-width variant of the builtin works on more chips than other widths.
260+
*/
255261
#if defined(__arm__)|| defined(__arm)
256262
#defineHAS_TEST_AND_SET
257263

258-
typedefunsignedcharslock_t;
259-
260264
#defineTAS(lock) tas(lock)
261265

266+
#ifdefHAVE_GCC_INT_ATOMICS
267+
268+
typedefintslock_t;
269+
270+
static __inline__int
271+
tas(volatileslock_t*lock)
272+
{
273+
return__sync_lock_test_and_set(lock,1);
274+
}
275+
276+
#defineS_UNLOCK(lock) __sync_lock_release(lock)
277+
278+
#else/* !HAVE_GCC_INT_ATOMICS */
279+
280+
typedefunsignedcharslock_t;
281+
262282
static __inline__int
263283
tas(volatileslock_t*lock)
264284
{
@@ -272,6 +292,7 @@ tas(volatile slock_t *lock)
272292
return (int)_res;
273293
}
274294

295+
#endif/* HAVE_GCC_INT_ATOMICS */
275296
#endif/* __arm__ */
276297

277298

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp