sinval.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:5k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * sinval.c
  4.  *   POSTGRES shared cache invalidation communication code.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.15 1999/05/28 17:03:29 tgl Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. /* #define INVALIDDEBUG 1 */
  15. #include <sys/types.h>
  16. #include "postgres.h"
  17. #include "storage/backendid.h"
  18. #include "storage/sinval.h"
  19. #include "storage/sinvaladt.h"
  20. #include "storage/spin.h"
  21. extern SISeg *shmInvalBuffer; /* the shared buffer segment, set by */
  22.  /* SISegmentAttach()    */
  23. extern BackendId MyBackendId;
  24. extern BackendTag MyBackendTag;
  25. SPINLOCK SInvalLock = (SPINLOCK) NULL;
  26. /****************************************************************************/
  27. /* CreateSharedInvalidationState()  Create a buffer segment */
  28. /* */
  29. /* should be called only by the POSTMASTER */
  30. /****************************************************************************/
  31. void
  32. CreateSharedInvalidationState(IPCKey key, int maxBackends)
  33. {
  34. int status;
  35. /*
  36.  * REMOVED SISyncKill(IPCKeyGetSIBufferMemorySemaphoreKey(key));
  37.  * SISyncInit(IPCKeyGetSIBufferMemorySemaphoreKey(key));
  38.  */
  39. /* SInvalLock gets set in spin.c, during spinlock init */
  40. status = SISegmentInit(true, IPCKeyGetSIBufferMemoryBlock(key),
  41.    maxBackends);
  42. if (status == -1)
  43. elog(FATAL, "CreateSharedInvalidationState: failed segment init");
  44. }
  45. /****************************************************************************/
  46. /* AttachSharedInvalidationState(key)  Attach a buffer segment */
  47. /* */
  48. /* should be called only by the POSTMASTER */
  49. /****************************************************************************/
  50. void
  51. AttachSharedInvalidationState(IPCKey key)
  52. {
  53. int status;
  54. if (key == PrivateIPCKey)
  55. {
  56. CreateSharedInvalidationState(key, 16);
  57. return;
  58. }
  59. /* SInvalLock gets set in spin.c, during spinlock init */
  60. status = SISegmentInit(false, IPCKeyGetSIBufferMemoryBlock(key), 0);
  61. if (status == -1)
  62. elog(FATAL, "AttachSharedInvalidationState: failed segment init");
  63. }
  64. void
  65. InitSharedInvalidationState(void)
  66. {
  67. SpinAcquire(SInvalLock);
  68. if (!SIBackendInit(shmInvalBuffer))
  69. {
  70. SpinRelease(SInvalLock);
  71. elog(FATAL, "Backend cache invalidation initialization failed");
  72. }
  73. SpinRelease(SInvalLock);
  74. }
  75. /*
  76.  * RegisterSharedInvalid
  77.  * Returns a new local cache invalidation state containing a new entry.
  78.  *
  79.  * Note:
  80.  * Assumes hash index is valid.
  81.  * Assumes item pointer is valid.
  82.  */
  83. /****************************************************************************/
  84. /* RegisterSharedInvalid(cacheId, hashIndex, pointer) */
  85. /* */
  86. /* register a message in the buffer */
  87. /* should be called by a backend */
  88. /****************************************************************************/
  89. void
  90. RegisterSharedInvalid(int cacheId, /* XXX */
  91.   Index hashIndex,
  92.   ItemPointer pointer)
  93. {
  94. SharedInvalidData newInvalid;
  95. /*
  96.  * This code has been hacked to accept two types of messages.  This
  97.  * might be treated more generally in the future.
  98.  *
  99.  * (1) cacheId= system cache id hashIndex= system cache hash index for a
  100.  * (possibly) cached tuple pointer= pointer of (possibly) cached tuple
  101.  *
  102.  * (2) cacheId= special non-syscache id hashIndex= object id contained in
  103.  * (possibly) cached relation descriptor pointer= null
  104.  */
  105. newInvalid.cacheId = cacheId;
  106. newInvalid.hashIndex = hashIndex;
  107. if (ItemPointerIsValid(pointer))
  108. ItemPointerCopy(pointer, &newInvalid.pointerData);
  109. else
  110. ItemPointerSetInvalid(&newInvalid.pointerData);
  111. SpinAcquire(SInvalLock);
  112. if (!SISetDataEntry(shmInvalBuffer, &newInvalid))
  113. {
  114. /* buffer full */
  115. /* release a message, mark process cache states to be invalid */
  116. SISetProcStateInvalid(shmInvalBuffer);
  117. if (!SIDelDataEntry(shmInvalBuffer))
  118. {
  119. /* inconsistent buffer state -- shd never happen */
  120. SpinRelease(SInvalLock);
  121. elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
  122. }
  123. /* write again */
  124. SISetDataEntry(shmInvalBuffer, &newInvalid);
  125. }
  126. SpinRelease(SInvalLock);
  127. }
  128. /*
  129.  * InvalidateSharedInvalid
  130.  * Processes all entries in a shared cache invalidation state.
  131.  */
  132. /****************************************************************************/
  133. /* InvalidateSharedInvalid(invalFunction, resetFunction) */
  134. /* */
  135. /* invalidate a message in the buffer  (read and clean up) */
  136. /* should be called by a backend */
  137. /****************************************************************************/
  138. void
  139. InvalidateSharedInvalid(void (*invalFunction) (),
  140. void (*resetFunction) ())
  141. {
  142. SpinAcquire(SInvalLock);
  143. SIReadEntryData(shmInvalBuffer, MyBackendId,
  144. invalFunction, resetFunction);
  145. SIDelExpiredDataEntries(shmInvalBuffer);
  146. SpinRelease(SInvalLock);
  147. }