int MemMapper::addRange(int virtAddress, int length) { int virtPage = virtAddress >> 8; if ((virtAddress & 0xff) || virtPage < 0 || virtPage >= FLASH_PAGE_SIZE) { return MEM_MAPPER_INVALID_ADDRESS; } if ((length & 0xff) != 0) { return MEM_MAPPER_INVALID_LENGTH; } byte pages = length >> 8; for (int page = virtPage; page < (pages + virtPage); page++) { byte flashPageNum = allocTable[page] ^ 0xff; if (flashPageNum == 0) { // not yet allocated in flash memory int result = allocatePage(page); if (result != MEM_MAPPER_SUCCESS) { return result; } flashMemModified = true; doFlash(); } } allocTableModified = true; doFlash(); return MEM_MAPPER_SUCCESS; }
BTreeNode *BTreeBuildLevel::allocateAndLinkNewNode() { PageId prevPageId = pageId; BTreeNode &node = allocatePage(); // Ugly: we have to go back and fix up the rightSibling link on the // previous page. There are better ways, but they require messing with // SegPageLock. BTreePageLock prevPageLock; prevPageLock.accessSegment(builder.treeDescriptor.segmentAccessor); prevPageLock.lockExclusive(prevPageId); BTreeNode &prevNode = prevPageLock.getNodeForWrite(); builder.setRightSibling( prevNode, prevPageId, pageId); // Let the cache know we're not planning to revisit the page we just // finished. builder.getCacheAccessor()->nicePage(prevPageLock.getPage()); ++iNode; if (nEntriesPerNode) { // Recalculate balancing. nEntriesPerNode = builder.calculateChildEntriesPerNode( builder.getLevel(iLevel + 1).nEntriesTotal, nEntriesTotal, iNode); } return &node; }
/** * @brief 扩展一个文件的空间 * * @param [in/out] head : struct dbSysHead * * @param [in] fid : long 文件标识 * @param [in] extendPage : long 要扩展的页数 * @return int * * @author mengxi * @date 2015/10/20 **/ int extendFileSpace(struct dbSysHead *head, long fid, int extendPage) { long segmentAddr; struct Segment newSegment; struct Segment lastSegment; int allocStaPage; int i; int count; int nPage; int numPage; int idx; numPage = extendPage; allocStaPage = allocatePage(head, numPage); if (allocStaPage < 0) { printf("extendFileSpace error:out of disk space."); exit(0); } segmentAddr = getLastSegmentAddr(head, fid); getSegmentValue(head, segmentAddr, &lastSegment); if (lastSegment.count < PAGE_PER_SEGMENT) { nPage = (numPage < (PAGE_PER_SEGMENT - lastSegment.count)) ? numPage : (PAGE_PER_SEGMENT - lastSegment.count); count = lastSegment.count; for (i = 0; i<nPage; i++) { lastSegment.pageNo[count + i] = allocStaPage; allocStaPage++; } lastSegment.count += nPage; writeSegmentValue(head, segmentAddr, &lastSegment); numPage -= nPage; } if (numPage > 0) { while (numPage > 0) { nPage = (numPage < PAGE_PER_SEGMENT) ? numPage : PAGE_PER_SEGMENT; initSegment(&newSegment, allocStaPage, nPage, fid, segmentAddr, -1); allocStaPage += nPage; lastSegment.nextAddr = (head->desc).segmentAddr + (head->desc).segmentCur * sizeof(struct Segment); newSegment.preAddr = segmentAddr; writeSegmentValue(head, segmentAddr, &lastSegment); segmentAddr = lastSegment.nextAddr; (head->desc).segmentCur++; (head->desc).segmentNum++; lastSegment.count = newSegment.count; lastSegment.nextAddr = newSegment.nextAddr; lastSegment.preAddr = newSegment.preAddr; for (i = 0; i<newSegment.count; i++) { lastSegment.pageNo[i] = newSegment.pageNo[i]; } numPage -= nPage; } writeSegmentValue(head, segmentAddr, &newSegment); } idx = queryFileID(head, fid); head->desc.fileDesc[idx].filePageNum += extendPage; return 0; }
unsigned int ClassTable::registerClass(Oop clazz) { WriteLock<SharedMutex> l(sharedMutex); auto pageIndex = size / OopsPerPage; auto elementIndex = size % OopsPerPage; if(elementIndex == 0 && pageIndex == pageTable.size()) allocatePage(); pageTable[pageIndex][elementIndex] = clazz; clazz.header->identityHash = (unsigned int)size; return (unsigned int) (size++); }
void ClassTable::addSpecialClass(ClassDescription *description, size_t index) { WriteLock<SharedMutex> l(sharedMutex); auto pageIndex = index / OopsPerPage; auto elementIndex = index % OopsPerPage; for(size_t i = pageTable.size(); i < pageIndex + 1; ++i) allocatePage(); pageTable[pageIndex][elementIndex] = Oop::fromPointer(description); size = std::max(size, index + 1); description->object_header_.identityHash = (unsigned int)index; }
// Allocate another page for a fixed size pool void ObjectMemory::FixedSizePool::moreChunks() { const int nOverhead = 0;//12; const int nBlockSize = dwPageSize - nOverhead; const int nChunks = nBlockSize / m_nChunkSize; BYTE* pStart = allocatePage(); #ifdef _DEBUG if (abs(Interpreter::executionTrace) > 0) { tracelock lock(TRACESTREAM); TRACESTREAM<< L"FixedSizePool(" << this << L" new page @ " << pStart << L" (" << m_nPages<< L" pages of " << nChunks <<" chunks of " << m_nChunkSize <<" bytes, total waste " << m_nPages*(nBlockSize-(nChunks*m_nChunkSize)) << L')' << std::endl; } memset(pStart, 0xCD, nBlockSize); #else // We don't know whether the chunks are to contain zeros or nils, so we don't bother to init the space #endif BYTE* pLast = &pStart[(nChunks-1) * m_nChunkSize]; #ifdef _DEBUG // ASSERT that pLast is correct by causing a GPF if it isn't! memset(static_cast<BYTE*>(pLast), 0xCD, m_nChunkSize); #endif const unsigned chunkSize = m_nChunkSize; // Loop invariant for (BYTE* p = pStart; p < pLast; p += chunkSize) reinterpret_cast<Link*>(p)->next = reinterpret_cast<Link*>(p + chunkSize); reinterpret_cast<Link*>(pLast)->next = 0; m_pFreeChunks = reinterpret_cast<Link*>(pStart); #ifdef _DEBUG m_nPages++; m_pages = static_cast<void**>(realloc(m_pages, m_nPages*sizeof(void*))); m_pages[m_nPages-1] = pStart; #endif }
/** * @brief 创建一个文件,为它分配空间 * * @param [in/out] head : struct dbSysHead * * @return int * @retval 返回文件的标识号,即fid * * @author mengxi * @date 2015/10/20 **/ long creatFileSpace(struct dbSysHead *head) { struct Segment newSegment; long segmentAddr; long alloStaPage; int i; if ((head->desc).curFileNum >= MAX_FILE_NUM) { printf("creatFile Space error:total files cannot be more than %d.\n", (head->desc).curFileNum); return -1; } segmentAddr = (head->desc).segmentAddr + sizeof(struct Segment) * (head->desc).segmentCur; alloStaPage = allocatePage(head, PAGE_PER_SEGMENT); if (alloStaPage >= 0) { for (i = 0; i<MAX_FILE_NUM; i++) { if ((head->desc).fileDesc[i].fileID <= 0) { break; } } (head->desc).fileDesc[i].fileID = (head->desc).curfid; (head->desc).fileDesc[i].fileAddr = segmentAddr; (head->desc).fileDesc[i].filePageNum = PAGE_PER_SEGMENT; (head->desc).curFileNum++; initSegment(&newSegment, alloStaPage, PAGE_PER_SEGMENT, (head->desc).fileDesc[i].fileID, -1, -1); rewind(head->fpdesc); fseek(head->fpdesc, (head->desc).fileDesc[i].fileAddr, SEEK_SET); fwrite(&newSegment, sizeof(struct Segment), 1, head->fpdesc); (head->desc).segmentNum++; (head->desc).segmentCur++; (head->desc).curfid++; } else { printf("creatFileSpace error:creat error"); exit(0); } return (head->desc).fileDesc[i].fileID; }