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

Commit7f60b81

Browse files
committed
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 lockis known to be free. Also, make sure that code will eventually time outand report a stuck spinlock, rather than looping forever. Small cleanupsin s_lock.h, too.
1 parent7d363c4 commit7f60b81

File tree

4 files changed

+194
-177
lines changed

4 files changed

+194
-177
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 27 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.45 2000/12/28 13:00:08 vadim Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.46 2000/12/29 21:31:21 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -411,7 +411,7 @@ begin:;
411411
}
412412
}
413413
}
414-
s_lock_sleep(i++);
414+
S_LOCK_SLEEP(&(XLogCtl->insert_lck),i++);
415415
if (!TAS(&(XLogCtl->insert_lck)))
416416
break;
417417
}
@@ -599,17 +599,10 @@ begin:;
599599

600600
if (updrqst)
601601
{
602-
for (;;)
603-
{
604-
if (!TAS(&(XLogCtl->info_lck)))
605-
{
606-
if (XLByteLT(XLogCtl->LgwrRqst.Write,LgwrRqst.Write))
607-
XLogCtl->LgwrRqst.Write=LgwrRqst.Write;
608-
S_UNLOCK(&(XLogCtl->info_lck));
609-
break;
610-
}
611-
s_lock_sleep(i++);
612-
}
602+
S_LOCK(&(XLogCtl->info_lck));
603+
if (XLByteLT(XLogCtl->LgwrRqst.Write,LgwrRqst.Write))
604+
XLogCtl->LgwrRqst.Write=LgwrRqst.Write;
605+
S_UNLOCK(&(XLogCtl->info_lck));
613606
}
614607

615608
END_CRIT_CODE;
@@ -622,7 +615,7 @@ XLogFlush(XLogRecPtr record)
622615
XLogRecPtrWriteRqst;
623616
charbuffer[BLCKSZ];
624617
char*usebuf=NULL;
625-
unsignedi=0;
618+
unsignedspins=0;
626619
boolforce_lgwr= false;
627620

628621
if (XLOG_DEBUG)
@@ -715,7 +708,7 @@ XLogFlush(XLogRecPtr record)
715708
break;
716709
}
717710
}
718-
s_lock_sleep(i++);
711+
S_LOCK_SLEEP(&(XLogCtl->lgwr_lck),spins++);
719712
}
720713

721714
if (logFile >=0&& (LgwrResult.Write.xlogid!=logId||
@@ -740,18 +733,12 @@ XLogFlush(XLogRecPtr record)
740733
logId,logSeg);
741734
LgwrResult.Flush=LgwrResult.Write;
742735

743-
for (i=0;;)
744-
{
745-
if (!TAS(&(XLogCtl->info_lck)))
746-
{
747-
XLogCtl->LgwrResult=LgwrResult;
748-
if (XLByteLT(XLogCtl->LgwrRqst.Write,LgwrResult.Write))
749-
XLogCtl->LgwrRqst.Write=LgwrResult.Write;
750-
S_UNLOCK(&(XLogCtl->info_lck));
751-
break;
752-
}
753-
s_lock_sleep(i++);
754-
}
736+
S_LOCK(&(XLogCtl->info_lck));
737+
XLogCtl->LgwrResult=LgwrResult;
738+
if (XLByteLT(XLogCtl->LgwrRqst.Write,LgwrResult.Write))
739+
XLogCtl->LgwrRqst.Write=LgwrResult.Write;
740+
S_UNLOCK(&(XLogCtl->info_lck));
741+
755742
XLogCtl->Write.LgwrResult=LgwrResult;
756743

757744
S_UNLOCK(&(XLogCtl->lgwr_lck));
@@ -767,6 +754,7 @@ GetFreeXLBuffer()
767754
XLogCtlInsert*Insert=&XLogCtl->Insert;
768755
XLogCtlWrite*Write=&XLogCtl->Write;
769756
uint16curridx=NextBufIdx(Insert->curridx);
757+
unsignedspins=0;
770758

771759
LgwrRqst.Write=XLogCtl->xlblocks[Insert->curridx];
772760
for (;;)
@@ -809,9 +797,8 @@ GetFreeXLBuffer()
809797
InitXLBuffer(curridx);
810798
return;
811799
}
800+
S_LOCK_SLEEP(&(XLogCtl->lgwr_lck),spins++);
812801
}
813-
814-
return;
815802
}
816803

817804
staticvoid
@@ -820,7 +807,6 @@ XLogWrite(char *buffer)
820807
XLogCtlWrite*Write=&XLogCtl->Write;
821808
char*from;
822809
uint32wcnt=0;
823-
inti=0;
824810
boolusexistent;
825811

826812
for (;XLByteLT(LgwrResult.Write,LgwrRqst.Write);)
@@ -919,18 +905,12 @@ XLogWrite(char *buffer)
919905
LgwrResult.Flush=LgwrResult.Write;
920906
}
921907

922-
for (;;)
923-
{
924-
if (!TAS(&(XLogCtl->info_lck)))
925-
{
926-
XLogCtl->LgwrResult=LgwrResult;
927-
if (XLByteLT(XLogCtl->LgwrRqst.Write,LgwrResult.Write))
928-
XLogCtl->LgwrRqst.Write=LgwrResult.Write;
929-
S_UNLOCK(&(XLogCtl->info_lck));
930-
break;
931-
}
932-
s_lock_sleep(i++);
933-
}
908+
S_LOCK(&(XLogCtl->info_lck));
909+
XLogCtl->LgwrResult=LgwrResult;
910+
if (XLByteLT(XLogCtl->LgwrRqst.Write,LgwrResult.Write))
911+
XLogCtl->LgwrRqst.Write=LgwrResult.Write;
912+
S_UNLOCK(&(XLogCtl->info_lck));
913+
934914
Write->LgwrResult=LgwrResult;
935915
}
936916

@@ -2062,18 +2042,17 @@ CreateCheckPoint(bool shutdown)
20622042
uint32_logId;
20632043
uint32_logSeg;
20642044
chararchdir[MAXPGPATH];
2045+
unsignedspins=0;
20652046

20662047
if (MyLastRecPtr.xrecoff!=0)
20672048
elog(ERROR,"CreateCheckPoint: cannot be called inside transaction block");
20682049

20692050
START_CRIT_CODE;
2051+
2052+
/* Grab lock, using larger than normal sleep between tries (1 sec) */
20702053
while (TAS(&(XLogCtl->chkp_lck)))
20712054
{
2072-
structtimevaldelay= {2,0};
2073-
2074-
if (shutdown)
2075-
elog(STOP,"Checkpoint lock is busy while data base is shutting down");
2076-
(void)select(0,NULL,NULL,NULL,&delay);
2055+
S_LOCK_SLEEP_INTERVAL(&(XLogCtl->chkp_lck),spins++,1000000);
20772056
}
20782057

20792058
memset(&checkPoint,0,sizeof(checkPoint));
@@ -2087,14 +2066,7 @@ CreateCheckPoint(bool shutdown)
20872066
checkPoint.Shutdown=shutdown;
20882067

20892068
/* Get REDO record ptr */
2090-
while (TAS(&(XLogCtl->insert_lck)))
2091-
{
2092-
structtimevaldelay= {1,0};
2093-
2094-
if (shutdown)
2095-
elog(STOP,"XLog insert lock is busy while data base is shutting down");
2096-
(void)select(0,NULL,NULL,NULL,&delay);
2097-
}
2069+
S_LOCK(&(XLogCtl->insert_lck));
20982070
freespace= ((char*)Insert->currpage)+BLCKSZ-Insert->currpos;
20992071
if (freespace<SizeOfXLogRecord)
21002072
{

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.100 2000/12/28 13:00:21vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.101 2000/12/29 21:31:21tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1987,7 +1987,7 @@ LockBuffer(Buffer buffer, int mode)
19871987
while (buf->ri_lock||buf->w_lock)
19881988
{
19891989
S_UNLOCK(&(buf->cntx_lock));
1990-
s_lock_sleep(i++);
1990+
S_LOCK_SLEEP(&(buf->cntx_lock),i++);
19911991
S_LOCK(&(buf->cntx_lock));
19921992
}
19931993
(buf->r_locks)++;
@@ -2013,7 +2013,7 @@ LockBuffer(Buffer buffer, int mode)
20132013
buf->ri_lock= true;
20142014
}
20152015
S_UNLOCK(&(buf->cntx_lock));
2016-
s_lock_sleep(i++);
2016+
S_LOCK_SLEEP(&(buf->cntx_lock),i++);
20172017
S_LOCK(&(buf->cntx_lock));
20182018
}
20192019
buf->w_lock= true;

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

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.27 2000/12/11 00:49:51 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.28 2000/12/29 21:31:20 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -25,19 +25,21 @@
2525
* number of microseconds to wait. This accomplishes pseudo random back-off.
2626
* Values are not critical but 10 milliseconds is a common platform
2727
* granularity.
28-
* note: total time to cycle through all 16 entries might be about .07 sec.
28+
*
29+
* Total time to cycle through all 20 entries might be about .07 sec,
30+
* so the given value of S_MAX_BUSY results in timeout after ~70 sec.
2931
*/
3032
#defineS_NSPINCYCLE20
3133
#defineS_MAX_BUSY1000 * S_NSPINCYCLE
3234

3335
ints_spincycle[S_NSPINCYCLE]=
34-
{0,0,0,0,10000,0,0,0,10000,0,
36+
{0,0,0,0,10000,0,0,0,10000,0,
3537
0,10000,0,0,10000,0,10000,0,10000,10000
3638
};
3739

3840

3941
/*
40-
* s_lock_stuck(lock) - complain about a stuck spinlock
42+
* s_lock_stuck() - complain about a stuck spinlock
4143
*/
4244
staticvoid
4345
s_lock_stuck(volatileslock_t*lock,constchar*file,constintline)
@@ -52,13 +54,38 @@ s_lock_stuck(volatile slock_t *lock, const char *file, const int line)
5254
}
5355

5456

57+
/*
58+
* s_lock_sleep() - sleep a pseudo-random amount of time, check for timeout
59+
*
60+
* Normally 'microsec' is 0, specifying to use the next s_spincycle[] value.
61+
* Some callers may pass a nonzero interval, specifying to use exactly that
62+
* delay value rather than a pseudo-random delay.
63+
*/
5564
void
56-
s_lock_sleep(unsignedspin)
65+
s_lock_sleep(unsignedspins,intmicrosec,
66+
volatileslock_t*lock,
67+
constchar*file,constintline)
5768
{
5869
structtimevaldelay;
70+
unsignedmax_spins;
71+
72+
if (microsec>0)
73+
{
74+
delay.tv_sec=0;
75+
delay.tv_usec=microsec;
76+
/* two-minute timeout in this case */
77+
max_spins=120000000 /microsec;
78+
}
79+
else
80+
{
81+
delay.tv_sec=0;
82+
delay.tv_usec=s_spincycle[spins %S_NSPINCYCLE];
83+
max_spins=S_MAX_BUSY;
84+
}
85+
86+
if (spins>max_spins)
87+
s_lock_stuck(lock,file,line);
5988

60-
delay.tv_sec=0;
61-
delay.tv_usec=s_spincycle[spin %S_NSPINCYCLE];
6289
(void)select(0,NULL,NULL,NULL,&delay);
6390
}
6491

@@ -71,14 +98,13 @@ s_lock(volatile slock_t *lock, const char *file, const int line)
7198
{
7299
unsignedspins=0;
73100

101+
/*
102+
* If you are thinking of changing this code, be careful. This same
103+
* loop logic is used in other places that call TAS() directly.
104+
*/
74105
while (TAS(lock))
75106
{
76-
s_lock_sleep(spins);
77-
if (++spins>S_MAX_BUSY)
78-
{
79-
/* It's been over a minute... */
80-
s_lock_stuck(lock,file,line);
81-
}
107+
s_lock_sleep(spins++,0,lock,file,line);
82108
}
83109
}
84110

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp