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

Commitc01c25f

Browse files
committed
Improve spinlock performance for HP-UX, ia64, non-gcc.
At least on this architecture, it's very important to spin on anon-atomic instruction and only retry the atomic once it appearsthat it will succeed. To fix this, split TAS() into two macros:TAS(), for trying to grab the lock the first time, and TAS_SPIN(),for spinning until we get it. TAS_SPIN() defaults to same as TAS(),but we can override it when we know there's a better way.It's likely that some of the other cases in s_lock.h requiresimilar treatment, but this is the only one we've got conclusiveevidence for at present.
1 parent6e1f1fe commitc01c25f

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

‎src/backend/storage/lmgr/s_lock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ s_lock(volatile slock_t *lock, const char *file, int line)
9696
intdelays=0;
9797
intcur_delay=0;
9898

99-
while (TAS(lock))
99+
while (TAS_SPIN(lock))
100100
{
101101
/* CPU-specific delay each time through the loop */
102102
SPIN_DELAY();

‎src/include/storage/s_lock.h

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,33 @@
3131
*macros at the bottom of the file. Check if your platform can use
3232
*these or needs to override them.
3333
*
34-
* Usually, S_LOCK() is implemented in terms ofaneven lower-levelmacro
35-
*TAS():
34+
* Usually, S_LOCK() is implemented in terms of even lower-levelmacros
35+
*TAS() and TAS_SPIN():
3636
*
3737
*int TAS(slock_t *lock)
3838
*Atomic test-and-set instruction. Attempt to acquire the lock,
3939
*but do *not* wait.Returns 0 if successful, nonzero if unable
4040
*to acquire the lock.
4141
*
42-
*TAS() is NOT part of the API, and should never be called directly.
42+
*int TAS_SPIN(slock_t *lock)
43+
*Like TAS(), but this version is used when waiting for a lock
44+
*previously found to be contended. Typically, this is the
45+
*same as TAS(), but on some architectures it's better to poll a
46+
*contended lock using an unlocked instruction and retry the
47+
*atomic test-and-set only when it appears free.
4348
*
44-
*CAUTION: on some platforms TAS() may sometimes report failure to acquire
45-
*a lock even when the lock is not locked. For example, on Alpha TAS()
46-
*will "fail" if interrupted. Therefore TAS() should always be invoked
47-
*in a retry loop, even if you are certain the lock is free.
49+
*TAS() and TAS_SPIN() are NOT part of the API, and should never be called
50+
*directly.
4851
*
49-
*ANOTHER CAUTION: be sure that TAS() and S_UNLOCK() represent sequence
50-
*points, ie, loads and stores of other values must not be moved across
51-
*a lock or unlock. In most cases it suffices to make the operation be
52-
*done through a "volatile" pointer.
52+
*CAUTION: on some platforms TAS() and/or TAS_SPIN() may sometimes report
53+
*failure to acquire a lock even when the lock is not locked. For example,
54+
*on Alpha TAS() will "fail" if interrupted. Therefore a retry loop must
55+
*always be used, even if you are certain the lock is free.
56+
*
57+
*ANOTHER CAUTION: be sure that TAS(), TAS_SPIN(), and S_UNLOCK() represent
58+
*sequence points, ie, loads and stores of other values must not be moved
59+
*across a lock or unlock. In most cases it suffices to make the operation
60+
*be done through a "volatile" pointer.
5361
*
5462
*On most supported platforms, TAS() uses a tas() function written
5563
*in assembly language to execute a hardware atomic-test-and-set
@@ -727,6 +735,7 @@ typedef unsigned int slock_t;
727735

728736
#include<ia64/sys/inline.h>
729737
#defineTAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE)
738+
#defineTAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
730739

731740
#endif/* HPUX on IA64, non gcc */
732741

@@ -925,6 +934,10 @@ extern inttas(volatile slock_t *lock);/* in port/.../tas.s, or
925934
#defineTAS(lock)tas(lock)
926935
#endif/* TAS */
927936

937+
#if !defined(TAS_SPIN)
938+
#defineTAS_SPIN(lock)TAS(lock)
939+
#endif/* TAS_SPIN */
940+
928941

929942
/*
930943
* Platform-independent out-of-line support routines

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp