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

Commit8add6d7

Browse files
committed
Modify sinval so that InvalidateSharedInvalid() does not hold
the SInval spinlock while it is calling the passed invalFunction orresetFunction. This is necessary to avoid deadlock with lmgr change;InvalidateSharedInvalid can be called recursively now. It should bea good performance improvement anyway --- holding a spinlock for morethan a very short interval is a no-no.
1 parentae01c7f commit8add6d7

File tree

3 files changed

+114
-93
lines changed

3 files changed

+114
-93
lines changed

‎src/backend/storage/ipc/sinval.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.16 1999/07/15 22:39:49 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.17 1999/09/04 18:36:45 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,9 +21,9 @@
2121
#include"storage/sinval.h"
2222
#include"storage/sinvaladt.h"
2323

24-
externSISeg*shmInvalBuffer;/* the shared buffer segment, set by */
25-
26-
/* SISegmentAttach() */
24+
externSISeg*shmInvalBuffer;/* the shared buffer segment, set by
25+
* SISegmentAttach()
26+
*/
2727
externBackendIdMyBackendId;
2828
externBackendTagMyBackendTag;
2929

@@ -127,21 +127,20 @@ RegisterSharedInvalid(int cacheId,/* XXX */
127127
ItemPointerSetInvalid(&newInvalid.pointerData);
128128

129129
SpinAcquire(SInvalLock);
130-
if (!SISetDataEntry(shmInvalBuffer,&newInvalid))
130+
while (!SISetDataEntry(shmInvalBuffer,&newInvalid))
131131
{
132132
/* buffer full */
133133
/* release a message, mark process cache states to be invalid */
134134
SISetProcStateInvalid(shmInvalBuffer);
135135

136-
if (!SIDelDataEntry(shmInvalBuffer))
136+
if (!SIDelDataEntries(shmInvalBuffer,1))
137137
{
138138
/* inconsistent buffer state -- shd never happen */
139139
SpinRelease(SInvalLock);
140140
elog(FATAL,"RegisterSharedInvalid: inconsistent buffer state");
141141
}
142142

143-
/* write again */
144-
SISetDataEntry(shmInvalBuffer,&newInvalid);
143+
/* loop around to try write again */
145144
}
146145
SpinRelease(SInvalLock);
147146
}
@@ -157,13 +156,41 @@ RegisterSharedInvalid(int cacheId,/* XXX */
157156
/*should be called by a backend*/
158157
/****************************************************************************/
159158
void
160-
InvalidateSharedInvalid(void (*invalFunction) (),
161-
void (*resetFunction) ())
159+
InvalidateSharedInvalid(void (*invalFunction) (),
160+
void (*resetFunction) ())
162161
{
163-
SpinAcquire(SInvalLock);
164-
SIReadEntryData(shmInvalBuffer,MyBackendId,
165-
invalFunction,resetFunction);
162+
SharedInvalidDatadata;
163+
intgetResult;
164+
boolgotMessage= false;
166165

167-
SIDelExpiredDataEntries(shmInvalBuffer);
168-
SpinRelease(SInvalLock);
166+
for (;;)
167+
{
168+
SpinAcquire(SInvalLock);
169+
getResult=SIGetDataEntry(shmInvalBuffer,MyBackendId,&data);
170+
SpinRelease(SInvalLock);
171+
if (getResult==0)
172+
break;/* nothing more to do */
173+
if (getResult<0)
174+
{
175+
/* got a reset message */
176+
elog(NOTICE,"InvalidateSharedInvalid: cache state reset");
177+
resetFunction();
178+
}
179+
else
180+
{
181+
/* got a normal data message */
182+
invalFunction(data.cacheId,
183+
data.hashIndex,
184+
&data.pointerData);
185+
}
186+
gotMessage= true;
187+
}
188+
189+
/* If we got any messages, try to release dead messages */
190+
if (gotMessage)
191+
{
192+
SpinAcquire(SInvalLock);
193+
SIDelExpiredDataEntries(shmInvalBuffer);
194+
SpinRelease(SInvalLock);
195+
}
169196
}

‎src/backend/storage/ipc/sinvaladt.c

Lines changed: 68 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.23 1999/07/17 20:17:44 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.24 1999/09/04 18:36:45 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -450,20 +450,11 @@ SIGetLastDataEntry(SISeg *segP)
450450
/************************************************************************/
451451
/* SIGetNextDataEntry(segP, offset) returns next data entry*/
452452
/************************************************************************/
453-
staticSISegEntry*
454-
SIGetNextDataEntry(SISeg*segP,Offsetoffset)
455-
{
456-
SISegEntry*eP;
457-
458-
if (offset==InvalidOffset)
459-
returnNULL;
460-
461-
eP= (SISegEntry*) ((Pointer)segP+
462-
SIGetStartEntrySection(segP)+
463-
offset);
464-
returneP;
465-
}
466-
453+
#defineSIGetNextDataEntry(segP,offset) \
454+
(((offset) == InvalidOffset) ? (SISegEntry *) NULL : \
455+
(SISegEntry *) ((Pointer) (segP) + \
456+
(segP)->startEntrySection + \
457+
(Offset) (offset)))
467458

468459
/************************************************************************/
469460
/* SIGetNthDataEntry(segP, n)returns the n-th data entry in chain*/
@@ -566,31 +557,38 @@ SIDecProcLimit(SISeg *segP, int num)
566557

567558

568559
/************************************************************************/
569-
/*SIDelDataEntry(segP)- free the FIRSTentry*/
560+
/*SIDelDataEntries(segP, n)- free the FIRSTn entries*/
570561
/************************************************************************/
571562
bool
572-
SIDelDataEntry(SISeg*segP)
563+
SIDelDataEntries(SISeg*segP,intn)
573564
{
574-
SISegEntry*e1P;
565+
inti;
566+
567+
if (n <=0)
568+
return false;
575569

576-
if (!SIDecNumEntries(segP,1))
570+
if (!SIDecNumEntries(segP,n))
577571
{
578-
/*no entries in buffer */
572+
/*not that many entries in buffer */
579573
return false;
580574
}
581575

582-
e1P=SIGetFirstDataEntry(segP);
583-
SISetStartEntryChain(segP,e1P->next);
584-
if (SIGetStartEntryChain(segP)==InvalidOffset)
576+
for (i=1;i <=n;i++)
585577
{
586-
/* it was the last entry */
587-
SISetEndEntryChain(segP,InvalidOffset);
578+
SISegEntry*e1P=SIGetFirstDataEntry(segP);
579+
SISetStartEntryChain(segP,e1P->next);
580+
if (SIGetStartEntryChain(segP)==InvalidOffset)
581+
{
582+
/* it was the last entry */
583+
SISetEndEntryChain(segP,InvalidOffset);
584+
}
585+
/* free the entry */
586+
e1P->isfree= true;
587+
e1P->next=SIGetStartFreeSpace(segP);
588+
SISetStartFreeSpace(segP,SIEntryOffset(segP,e1P));
588589
}
589-
/* free the entry */
590-
e1P->isfree= true;
591-
e1P->next=SIGetStartFreeSpace(segP);
592-
SISetStartFreeSpace(segP,SIEntryOffset(segP,e1P));
593-
SIDecProcLimit(segP,1);
590+
591+
SIDecProcLimit(segP,n);
594592
return true;
595593
}
596594

@@ -621,51 +619,51 @@ SISetProcStateInvalid(SISeg *segP)
621619
}
622620

623621
/************************************************************************/
624-
/* SIReadEntryData(segP, backendId, function)*/
625-
/*- marks messages to be read by id*/
626-
/* and executes function*/
622+
/* SIGetDataEntry(segP, backendId, data)*/
623+
/*get next SI message for specified backend, if there is one*/
624+
/**/
625+
/*Possible return values:*/
626+
/*0: no SI message available*/
627+
/*1: next SI message has been extracted into *data*/
628+
/*(there may be more messages available after this one!)*/
629+
/* -1: SI reset message extracted*/
627630
/************************************************************************/
628-
void
629-
SIReadEntryData(SISeg*segP,
630-
intbackendId,
631-
void (*invalFunction) (),
632-
void (*resetFunction) ())
631+
int
632+
SIGetDataEntry(SISeg*segP,intbackendId,
633+
SharedInvalidData*data)
633634
{
634-
inti=0;
635-
SISegEntry*data;
635+
SISegEntry*msg;
636636

637637
Assert(segP->procState[backendId-1].tag==MyBackendTag);
638638

639-
if (!segP->procState[backendId-1].resetState)
639+
if (segP->procState[backendId-1].resetState)
640640
{
641-
/* invalidate data, but only those, you have not seen yet !! */
642-
/* therefore skip read messages */
643-
data=SIGetNthDataEntry(segP,
644-
SIGetProcStateLimit(segP,backendId-1)+1);
645-
while (data!=NULL)
646-
{
647-
i++;
648-
segP->procState[backendId-1].limit++;/* one more message read */
649-
invalFunction(data->entryData.cacheId,
650-
data->entryData.hashIndex,
651-
&data->entryData.pointerData);
652-
data=SIGetNextDataEntry(segP,data->next);
653-
}
654-
/* SIDelExpiredDataEntries(segP); */
655-
}
656-
else
657-
{
658-
/* backend must not read messages, its own state has to be reset */
659-
elog(NOTICE,"SIReadEntryData: cache state reset");
660-
resetFunction();/* XXXX call it here, parameters? */
661-
662641
/* new valid state--mark all messages "read" */
663642
segP->procState[backendId-1].resetState= false;
664643
segP->procState[backendId-1].limit=SIGetNumEntries(segP);
644+
return-1;
665645
}
666-
/* check whether we can remove dead messages*/
667-
if (i>MAXNUMMESSAGES)
668-
elog(FATAL,"SIReadEntryData: Invalid segment state");
646+
647+
/* Get next message for this backend, if any */
648+
649+
/* This is fairly inefficient if there are many messages,
650+
* but normally there should not be...
651+
*/
652+
msg=SIGetNthDataEntry(segP,
653+
SIGetProcStateLimit(segP,backendId-1)+1);
654+
655+
if (msg==NULL)
656+
return0;/* nothing to read */
657+
658+
*data=msg->entryData;/* return contents of message */
659+
660+
segP->procState[backendId-1].limit++;/* one more message read */
661+
662+
/* There may be other backends that haven't read the message,
663+
* so we cannot delete it here.
664+
* SIDelExpiredDataEntries() should be called to remove dead messages.
665+
*/
666+
return1;/* got a message */
669667
}
670668

671669
/************************************************************************/
@@ -688,15 +686,12 @@ SIDelExpiredDataEntries(SISeg *segP)
688686
min=h;
689687
}
690688
}
691-
if (min!=9999999)
689+
if (min<9999999&&min>0)
692690
{
693691
/* we can remove min messages */
694-
for (i=1;i <=min;i++)
695-
{
696-
/* this adjusts also the state limits! */
697-
if (!SIDelDataEntry(segP))
698-
elog(FATAL,"SIDelExpiredDataEntries: Invalid segment state");
699-
}
692+
/* this adjusts also the state limits! */
693+
if (!SIDelDataEntries(segP,min))
694+
elog(FATAL,"SIDelExpiredDataEntries: Invalid segment state");
700695
}
701696
}
702697

@@ -784,8 +779,7 @@ SISegmentAttach(IpcMemoryId shmid)
784779
if (shmInvalBuffer==IpcMemAttachFailed)
785780
{
786781
/* XXX use validity function */
787-
elog(NOTICE,"SISegmentAttach: Could not attach segment");
788-
elog(FATAL,"SISegmentAttach: %m");
782+
elog(FATAL,"SISegmentAttach: Could not attach segment: %m");
789783
}
790784
}
791785

‎src/include/storage/sinvaladt.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: sinvaladt.h,v 1.16 1999/07/16 17:07:38 momjian Exp $
9+
* $Id: sinvaladt.h,v 1.17 1999/09/04 18:36:44 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -128,9 +128,9 @@ extern intSISegmentInit(bool killExistingSegment, IPCKey key,
128128

129129
externboolSISetDataEntry(SISeg*segP,SharedInvalidData*data);
130130
externvoidSISetProcStateInvalid(SISeg*segP);
131-
externboolSIDelDataEntry(SISeg*segP);
132-
externvoidSIReadEntryData(SISeg*segP,intbackendId,
133-
void (*invalFunction) (),void (*resetFunction) ());
131+
externintSIGetDataEntry(SISeg*segP,intbackendId,
132+
SharedInvalidData*data);
133+
externboolSIDelDataEntries(SISeg*segP,intn);
134134
externvoidSIDelExpiredDataEntries(SISeg*segP);
135135

136136
#endif/* SINVALADT_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp