/* * StrategyInitialize -- initialize the buffer cache replacement * strategy. * * Assumes: All of the buffers are already built into a linked list. * Only called by postmaster and only during initialization. */ void StrategyInitialize(bool init) { bool found; /* * Initialize the shared buffer lookup hashtable. * * Since we can't tolerate running out of lookup table entries, we must be * sure to specify an adequate table size here. The maximum steady-state * usage is of course NBuffers entries, but BufferAlloc() tries to insert * a new entry before deleting the old. In principle this could be * happening in each partition concurrently, so we could need as many as * NBuffers + NUM_BUFFER_PARTITIONS entries. */ InitBufTable(NBuffers + NUM_BUFFER_PARTITIONS); /* * Get or create the shared strategy control block */ StrategyControl = (BufferStrategyControl *) ShmemInitStruct("Buffer Strategy Status", sizeof(BufferStrategyControl), &found); if (!found) { /* * Only done once, usually in postmaster */ Assert(init); /* * Grab the whole linked list of free buffers for our strategy. We * assume it was previously set up by InitBufferPool(). */ StrategyControl->firstFreeBuffer = 0; StrategyControl->lastFreeBuffer = NBuffers - 1; /* Initialize the clock sweep pointer */ StrategyControl->nextVictimBuffer = 0; /* Clear statistics */ StrategyControl->completePasses = 0; StrategyControl->numBufferAllocs = 0; /* No pending notification */ StrategyControl->bgwriterLatch = NULL; StrategyControl->lastUnpinned = NULL; StrategyControl->firstUnpinned = NULL; StrategyControl->a1Head = NULL; StrategyControl->a1Tail = NULL; } else Assert(!init); }
/* * StrategyInitialize -- initialize the buffer cache replacement * strategy. * * Assumes: All of the buffers are already built into a linked list. * Only called by postmaster and only during initialization. */ void StrategyInitialize(bool init) { bool found; /* * Initialize the shared buffer lookup hashtable. * * Since we can't tolerate running out of lookup table entries, we * must be sure to specify an adequate table size here. The maximum * steady-state usage is of course NBuffers entries, but BufferAlloc() * tries to insert a new entry before deleting the old. */ InitBufTable(NBuffers + 1); /* * Get or create the shared strategy control block */ StrategyControl = (BufferStrategyControl *) ShmemInitStruct("Buffer Strategy Status", sizeof(BufferStrategyControl), &found); if (!found) { /* * Only done once, usually in postmaster */ Assert(init); /* * Grab the whole linked list of free buffers for our strategy. We * assume it was previously set up by InitBufferPool(). */ StrategyControl->firstFreeBuffer = 0; StrategyControl->lastFreeBuffer = NBuffers - 1; /* Initialize the clock sweep pointer */ StrategyControl->nextVictimBuffer = 0; } else Assert(!init); }
/* * StrategyInitialize -- initialize the buffer cache replacement * strategy. * * Assumes: All of the buffers are already built into a linked list. * Only called by postmaster and only during initialization. */ void StrategyInitialize(bool init) { bool found; /* * Initialize the shared buffer lookup hashtable. */ InitBufTable(NBuffers); /* * Get or create the shared strategy control block */ StrategyControl = (BufferStrategyControl *) ShmemInitStruct("Buffer Strategy Status", sizeof(BufferStrategyControl), &found); if (!found) { /* * Only done once, usually in postmaster */ Assert(init); /* * Grab the whole linked list of free buffers for our strategy. We * assume it was previously set up by InitBufferPool(). */ StrategyControl->firstFreeBuffer = 0; StrategyControl->lastFreeBuffer = NBuffers - 1; /* Initialize the clock sweep pointer */ StrategyControl->nextVictimBuffer = 0; } else Assert(!init); }
/* * Initialize shared buffer pool * * This is called once during shared-memory initialization (either in the * postmaster, or in a standalone backend). */ void InitBufferPool(void) { char *BufferBlocks; bool foundBufs, foundDescs; int i; Data_Descriptors = NBuffers; Free_List_Descriptor = Data_Descriptors; Lookup_List_Descriptor = Data_Descriptors + 1; Num_Descriptors = Data_Descriptors + 1; /* * It's probably not really necessary to grab the lock --- if there's * anyone else attached to the shmem at this point, we've got * problems. */ LWLockAcquire(BufMgrLock, LW_EXCLUSIVE); #ifdef BMTRACE CurTraceBuf = (long *) ShmemInitStruct("Buffer trace", (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long), &foundDescs); if (!foundDescs) MemSet(CurTraceBuf, 0, (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long)); TraceBuf = (bmtrace *) & (CurTraceBuf[1]); #endif BufferDescriptors = (BufferDesc *) ShmemInitStruct("Buffer Descriptors", Num_Descriptors * sizeof(BufferDesc), &foundDescs); BufferBlocks = (char *) ShmemInitStruct("Buffer Blocks", NBuffers * BLCKSZ, &foundBufs); if (foundDescs || foundBufs) { /* both should be present or neither */ Assert(foundDescs && foundBufs); } else { BufferDesc *buf; char *block; buf = BufferDescriptors; block = BufferBlocks; /* * link the buffers into a circular, doubly-linked list to * initialize free list, and initialize the buffer headers. Still * don't know anything about replacement strategy in this file. */ for (i = 0; i < Data_Descriptors; block += BLCKSZ, buf++, i++) { Assert(ShmemIsValid((unsigned long) block)); buf->freeNext = i + 1; buf->freePrev = i - 1; CLEAR_BUFFERTAG(&(buf->tag)); buf->buf_id = i; buf->data = MAKE_OFFSET(block); buf->flags = (BM_DELETED | BM_FREE | BM_VALID); buf->refcount = 0; buf->io_in_progress_lock = LWLockAssign(); buf->cntx_lock = LWLockAssign(); buf->cntxDirty = false; buf->wait_backend_id = 0; } /* close the circular queue */ BufferDescriptors[0].freePrev = Data_Descriptors - 1; BufferDescriptors[Data_Descriptors - 1].freeNext = 0; } /* Init other shared buffer-management stuff */ InitBufTable(); InitFreeList(!foundDescs); LWLockRelease(BufMgrLock); }
/* * StrategyInitialize -- initialize the buffer cache replacement * strategy. * * Assume: All of the buffers are already building a linked list. * Only called by postmaster and only during initialization. */ void StrategyInitialize(bool init) { /* A1out list can hold 50% of NBuffers, per Johnson and Shasha */ int nCDBs = NBuffers + NBuffers / 2; bool found; int i; /* * Initialize the shared CDB lookup hashtable */ InitBufTable(nCDBs); /* * Get or create the shared strategy control block and the CDB's */ StrategyControl = (BufferStrategyControl *) ShmemInitStruct("Buffer Strategy Status", sizeof(BufferStrategyControl) + sizeof(BufferStrategyCDB) * (nCDBs - 1), &found); StrategyCDB = &(StrategyControl->cdb[0]); if (!found) { /* * Only done once, usually in postmaster */ Assert(init); /* * Grab the whole linked list of free buffers for our strategy. We * assume it was previously set up by InitBufferPool(). */ StrategyControl->listFreeBuffers = 0; /* * We set the target T1 size to 1/4th of available buffers. * Possibly this should be a runtime tunable. */ StrategyControl->target_T1_size = NBuffers / 4; /* * Initialize all lists to be empty */ for (i = 0; i < STRAT_NUM_LISTS; i++) { StrategyControl->listHead[i] = -1; StrategyControl->listTail[i] = -1; StrategyControl->listSize[i] = 0; StrategyControl->num_hit[i] = 0; } StrategyControl->num_lookup = 0; StrategyControl->stat_report = 0; /* * All CDB's are linked as the listUnusedCDB */ for (i = 0; i < nCDBs; i++) { StrategyCDB[i].next = i + 1; StrategyCDB[i].list = STRAT_LIST_UNUSED; CLEAR_BUFFERTAG(StrategyCDB[i].buf_tag); StrategyCDB[i].buf_id = -1; } StrategyCDB[nCDBs - 1].next = -1; StrategyControl->listUnusedCDB = 0; } else Assert(!init); }
/* * StrategyInitialize -- initialize the buffer cache replacement * strategy. * * Assumes: All of the buffers are already built into a linked list. * Only called by postmaster and only during initialization. */ void StrategyInitialize(bool init) { bool found; int i; volatile BufferDesc *buf; /* * Initialize the shared buffer lookup hashtable. * * Since we can't tolerate running out of lookup table entries, we must be * sure to specify an adequate table size here. The maximum steady-state * usage is of course NBuffers entries, but BufferAlloc() tries to insert * a new entry before deleting the old. In principle this could be * happening in each partition concurrently, so we could need as many as * NBuffers + NUM_BUFFER_PARTITIONS entries. */ InitBufTable(NBuffers + NUM_BUFFER_PARTITIONS); /* * Get or create the shared strategy control block */ StrategyControl = (BufferStrategyControl *) ShmemInitStruct("Buffer Strategy Status", sizeof(BufferStrategyControl), &found); if (!found) { /* * Only done once, usually in postmaster */ Assert(init); /* * Grab the whole linked list of free buffers for our strategy. We * assume it was previously set up by InitBufferPool(). */ StrategyControl->firstFreeBuffer = 0; StrategyControl->lastFreeBuffer = NBuffers - 1; /* Initialize the clock sweep pointer */ StrategyControl->nextVictimBuffer = 0; /* Clear statistics */ StrategyControl->completePasses = 0; StrategyControl->numBufferAllocs = 0; /* CS186 TODO: Initialize any data you added to StrategyControlData here */ StrategyControl->head = NULL; StrategyControl->tail = NULL; StrategyControl->listSize = 0; StrategyControl->headA1 = NULL; StrategyControl->tailA1 = NULL; StrategyControl->sizeA1 = 0; for(i = 0; i < NBuffers; i++){ buf = &BufferDescriptors[i]; buf->next = NULL; buf->prev = NULL; buf->nextA1 = NULL; buf->prevA1 = NULL; buf->inList = false; buf->inA1 = false; } } else Assert(!init); }