aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-12-29 21:31:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-12-29 21:31:21 +0000
commit7f60b81e1ab7cbb27298e980f25445dfa58d50bb (patch)
treef1ace7fa85f8f4037bf254008b41e65c9a7ce7f8 /src/backend/access/transam/xlog.c
parent7d363c4c3376459bc9389b250bc7b70e9cf7aa75 (diff)
downloadpostgresql-7f60b81e1ab7cbb27298e980f25445dfa58d50bb.tar.gz
postgresql-7f60b81e1ab7cbb27298e980f25445dfa58d50bb.zip
Fix failure in CreateCheckPoint on some Alpha boxes --- it's not OK to
assume that TAS() will always succeed the first time, even if the lock is known to be free. Also, make sure that code will eventually time out and report a stuck spinlock, rather than looping forever. Small cleanups in s_lock.h, too.
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c82
1 files changed, 27 insertions, 55 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 7294b97ff34..ff8916cd37b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.45 2000/12/28 13:00:08 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.46 2000/12/29 21:31:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -411,7 +411,7 @@ begin:;
}
}
}
- s_lock_sleep(i++);
+ S_LOCK_SLEEP(&(XLogCtl->insert_lck), i++);
if (!TAS(&(XLogCtl->insert_lck)))
break;
}
@@ -599,17 +599,10 @@ begin:;
if (updrqst)
{
- for (;;)
- {
- if (!TAS(&(XLogCtl->info_lck)))
- {
- if (XLByteLT(XLogCtl->LgwrRqst.Write, LgwrRqst.Write))
- XLogCtl->LgwrRqst.Write = LgwrRqst.Write;
- S_UNLOCK(&(XLogCtl->info_lck));
- break;
- }
- s_lock_sleep(i++);
- }
+ S_LOCK(&(XLogCtl->info_lck));
+ if (XLByteLT(XLogCtl->LgwrRqst.Write, LgwrRqst.Write))
+ XLogCtl->LgwrRqst.Write = LgwrRqst.Write;
+ S_UNLOCK(&(XLogCtl->info_lck));
}
END_CRIT_CODE;
@@ -622,7 +615,7 @@ XLogFlush(XLogRecPtr record)
XLogRecPtr WriteRqst;
char buffer[BLCKSZ];
char *usebuf = NULL;
- unsigned i = 0;
+ unsigned spins = 0;
bool force_lgwr = false;
if (XLOG_DEBUG)
@@ -715,7 +708,7 @@ XLogFlush(XLogRecPtr record)
break;
}
}
- s_lock_sleep(i++);
+ S_LOCK_SLEEP(&(XLogCtl->lgwr_lck), spins++);
}
if (logFile >= 0 && (LgwrResult.Write.xlogid != logId ||
@@ -740,18 +733,12 @@ XLogFlush(XLogRecPtr record)
logId, logSeg);
LgwrResult.Flush = LgwrResult.Write;
- for (i = 0;;)
- {
- if (!TAS(&(XLogCtl->info_lck)))
- {
- XLogCtl->LgwrResult = LgwrResult;
- if (XLByteLT(XLogCtl->LgwrRqst.Write, LgwrResult.Write))
- XLogCtl->LgwrRqst.Write = LgwrResult.Write;
- S_UNLOCK(&(XLogCtl->info_lck));
- break;
- }
- s_lock_sleep(i++);
- }
+ S_LOCK(&(XLogCtl->info_lck));
+ XLogCtl->LgwrResult = LgwrResult;
+ if (XLByteLT(XLogCtl->LgwrRqst.Write, LgwrResult.Write))
+ XLogCtl->LgwrRqst.Write = LgwrResult.Write;
+ S_UNLOCK(&(XLogCtl->info_lck));
+
XLogCtl->Write.LgwrResult = LgwrResult;
S_UNLOCK(&(XLogCtl->lgwr_lck));
@@ -767,6 +754,7 @@ GetFreeXLBuffer()
XLogCtlInsert *Insert = &XLogCtl->Insert;
XLogCtlWrite *Write = &XLogCtl->Write;
uint16 curridx = NextBufIdx(Insert->curridx);
+ unsigned spins = 0;
LgwrRqst.Write = XLogCtl->xlblocks[Insert->curridx];
for (;;)
@@ -809,9 +797,8 @@ GetFreeXLBuffer()
InitXLBuffer(curridx);
return;
}
+ S_LOCK_SLEEP(&(XLogCtl->lgwr_lck), spins++);
}
-
- return;
}
static void
@@ -820,7 +807,6 @@ XLogWrite(char *buffer)
XLogCtlWrite *Write = &XLogCtl->Write;
char *from;
uint32 wcnt = 0;
- int i = 0;
bool usexistent;
for (; XLByteLT(LgwrResult.Write, LgwrRqst.Write);)
@@ -919,18 +905,12 @@ XLogWrite(char *buffer)
LgwrResult.Flush = LgwrResult.Write;
}
- for (;;)
- {
- if (!TAS(&(XLogCtl->info_lck)))
- {
- XLogCtl->LgwrResult = LgwrResult;
- if (XLByteLT(XLogCtl->LgwrRqst.Write, LgwrResult.Write))
- XLogCtl->LgwrRqst.Write = LgwrResult.Write;
- S_UNLOCK(&(XLogCtl->info_lck));
- break;
- }
- s_lock_sleep(i++);
- }
+ S_LOCK(&(XLogCtl->info_lck));
+ XLogCtl->LgwrResult = LgwrResult;
+ if (XLByteLT(XLogCtl->LgwrRqst.Write, LgwrResult.Write))
+ XLogCtl->LgwrRqst.Write = LgwrResult.Write;
+ S_UNLOCK(&(XLogCtl->info_lck));
+
Write->LgwrResult = LgwrResult;
}
@@ -2062,18 +2042,17 @@ CreateCheckPoint(bool shutdown)
uint32 _logId;
uint32 _logSeg;
char archdir[MAXPGPATH];
+ unsigned spins = 0;
if (MyLastRecPtr.xrecoff != 0)
elog(ERROR, "CreateCheckPoint: cannot be called inside transaction block");
START_CRIT_CODE;
+
+ /* Grab lock, using larger than normal sleep between tries (1 sec) */
while (TAS(&(XLogCtl->chkp_lck)))
{
- struct timeval delay = {2, 0};
-
- if (shutdown)
- elog(STOP, "Checkpoint lock is busy while data base is shutting down");
- (void) select(0, NULL, NULL, NULL, &delay);
+ S_LOCK_SLEEP_INTERVAL(&(XLogCtl->chkp_lck), spins++, 1000000);
}
memset(&checkPoint, 0, sizeof(checkPoint));
@@ -2087,14 +2066,7 @@ CreateCheckPoint(bool shutdown)
checkPoint.Shutdown = shutdown;
/* Get REDO record ptr */
- while (TAS(&(XLogCtl->insert_lck)))
- {
- struct timeval delay = {1, 0};
-
- if (shutdown)
- elog(STOP, "XLog insert lock is busy while data base is shutting down");
- (void) select(0, NULL, NULL, NULL, &delay);
- }
+ S_LOCK(&(XLogCtl->insert_lck));
freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos;
if (freespace < SizeOfXLogRecord)
{