bool FlashDevice::comparePage(const void* data, flash_addr_t address, page_size_t length) { uint8_t buf[STACK_BUFFER_SIZE]; page_size_t offset = 0; while (offset<length) { page_size_t toRead = min(sizeof(buf), length-offset); if (!readPage(buf, address+offset, toRead)) break; if (!memcmp(buf, as_bytes(data)+offset, toRead)) break; offset += toRead; } return offset==length; }
// Given the offset of the "current" page, find the page immediately preceding // it (if any) and return its granule position. // To do this we back up from the "current" page's offset until we find any // page preceding it and then scan forward to just before the current page. status_t MyVorbisExtractor::findPrevGranulePosition( off64_t pageOffset, uint64_t *granulePos) { *granulePos = 0; off64_t prevPageOffset = 0; off64_t prevGuess = pageOffset; for (;;) { if (prevGuess >= 5000) { prevGuess -= 5000; } else { prevGuess = 0; } LOGV("backing up %lld bytes", pageOffset - prevGuess); status_t err = findNextPage(prevGuess, &prevPageOffset); if (err != OK) { return err; } if (prevPageOffset < pageOffset || prevGuess == 0) { break; } } if (prevPageOffset == pageOffset) { // We did not find a page preceding this one. return UNKNOWN_ERROR; } LOGV("prevPageOffset at %lld, pageOffset at %lld", prevPageOffset, pageOffset); for (;;) { Page prevPage; ssize_t n = readPage(prevPageOffset, &prevPage); if (n <= 0) { return (status_t)n; } prevPageOffset += n; if (prevPageOffset == pageOffset) { *granulePos = prevPage.mGranulePosition; return OK; } } }
page_id_t TPIO::RebaseTPIOTxSession::rebaseForceVisit(page_id_t pgid) { m_visited.insert(pgid); #ifdef VERBOSE_REBASE std::cout << "rebase visit pgid: " << pgid << std::endl; #endif Page pg(readPage(pgid)); mod_info_t mod; pg.updateLinks(&mod, this); return mod.isValid() ? mod.idOvr : pgid; }
//junliang.zhou 2011.12.13 20:40 add uint64_t MyVorbisExtractor::findLastGranule(void) { Page prevPage, curPage; off_t prevPageOffset; for ( prevPageOffset = 0; ; ) { ssize_t n = readPage(prevPageOffset, &curPage); if (n <= 0) { break; } else prevPage = curPage; prevPageOffset += n; } return prevPage.mGranulePosition; }
std::vector<unsigned char> TopazCommands::readPages(int start_page, int stop_page) { std::vector<unsigned char> ret; if (start_page > stop_page) { THROW_EXCEPTION_WITH_LOG(std::invalid_argument, "Start page can't be greater than stop page."); } for (int i = start_page; i <= stop_page; ++i) { std::vector<unsigned char> data = readPage(i); ret.insert(ret.end(), data.begin(), data.end()); } return ret; }
void KeyFile::dump(FILE *f, int flags) { KeyFileHeader header; readHead(header, false); KeyPage page(m_pageInfo); dbAddrDump(header.m_root, 1,f,flags); if(flags & DUMP_HEADER) { _ftprintf(f,_T("Root:%s Last:%s Freelist:("), toString(header.m_root).cstr(), toString(header.m_last).cstr()); } if(flags & DUMP_FREELIST) { for(KeyPageAddr list = header.m_freeList;list != DB_NULLADDR; list = page.getNextFree()) { _ftprintf(f,_T("%s "),toString(list).cstr()); readPage(list, page); } _ftprintf(f,_T(")\n")); } }
int32_t * FileSystem::getFilePageMapping(int *arraySize) { bool mustReleaseLock = getLock(); int32_t *result = (int32_t*)malloc(fileMappingSize * doubleIntsPerPage * INT_SIZE); int32_t *buffer = (int32_t*)malloc(pageSize); int cnt = 0; for (int i = 0; i < fileMappingSize; i++) { readPage(pageCount + pageLayoutSize + i, buffer); for (int k = 0; k < doubleIntsPerPage; k++) result[cnt++] = buffer[k + k]; } free(buffer); *arraySize = fileMappingSize * doubleIntsPerPage; if (mustReleaseLock) releaseLock(); return result; } // end of getFilePageMapping(int*)
int newPage(Buffer *buf, fileDescriptor FD, DiskAddress *diskPage) { // if everything is pinned, return -1 int i; for (i = 0; i < buf->nBufferBlocks; i++) { if (!buf->pin[i]) break; } if (i == buf->nBufferBlocks) return -1; diskPage->FD = FD; diskPage->pageId = tfs_numPages(FD); char *data = (char *)calloc(BLOCKSIZE, 1); tfs_writePage(FD, diskPage->pageId, (unsigned char *)data); free(data); return readPage(buf, *diskPage); }
status_t MyVorbisExtractor::findGranulePositionofPage(off64_t offset,uint64_t *granulePositionofPage) { if (mFirstDataOffset >= 0 && offset < mFirstDataOffset) { // Once we know where the actual audio data starts (past the headers) // don't ever seek to anywhere before that. offset = mFirstDataOffset; } if(((uint64_t)offset) == mFileSize) { findPrevGranulePosition(mFileSize, granulePositionofPage); if((*granulePositionofPage) < 0xFFFFFFFFFFFF) return OK; else return UNKNOWN_ERROR; } off64_t pageOffset; status_t err = findNextPage_l(offset, &pageOffset); if (err != OK) { err = findNextPage(offset, &pageOffset); if((err == OK) && (offset == pageOffset)) { Page page; readPage(offset, &page); *granulePositionofPage = page.mGranulePosition; } else findPrevGranulePosition(mFileSize, granulePositionofPage); if((*granulePositionofPage) < 0xFFFFFFFFFFFF) return OK; else return UNKNOWN_ERROR; } // We found the page we wanted to seek to, but we'll also need // the page preceding it to determine how many valid samples are on // this page. findPrevGranulePosition(pageOffset, granulePositionofPage); if((*granulePositionofPage) < 0xFFFFFFFFFFFF) return OK; else return UNKNOWN_ERROR; }
int Buffer::acquirePage(TransactionID* tid, PagePointer* pp) { int retval; if (!started) return -1; ::pthread_mutex_lock(&dbwriter.mutex); if (tid != NULL) { Statistics::get_statistics(pthread_self()). addPageReads(tid->getSessionId(), tid->getId(), 1); } else { Statistics::get_statistics(pthread_self()). addPageReads(-1, -1, 1); } buffer_addr_t buffer_addr = make_pair(pp->getFileID(), pp->getPageID()); buffer_hash_t::iterator it = buffer_hash.find(buffer_addr); buffer_page* n_page; if (it != buffer_hash.end() && (*it).second.haspage) { n_page = &((*it).second); n_page->lock++; ::pthread_mutex_unlock(&dbwriter.mutex); return 0; } else if (it != buffer_hash.end()) { if ((retval = readPage(tid, pp->getFileID(), pp->getPageID(), n_page)) != 0) { ::pthread_mutex_unlock(&dbwriter.mutex); return retval; } n_page->lock++; (*it).second = *n_page; pp->setPage(n_page->page); ::pthread_mutex_unlock(&dbwriter.mutex); return 0; } else { ::pthread_mutex_unlock(&dbwriter.mutex); return -1; } };
bool YaffsControl::readImage() { int result = 0; memset(&mReadInfo, 0, sizeof(YaffsReadInfo)); if (mImageFile) { while (result == 0) { result = readPage(); if (result == -1) { if (feof(mImageFile)) { mReadInfo.eofHasIncompletePage = true; result = 1; } break; } processPage(); } } mReadInfo.result = (result == 1); mObserver->readComplete(); return mReadInfo.result; }
int main(void) { int ret; int fd; int tries = 0; int tagIdLen = MAX_TAG_ID_LENGTH; unsigned char tagId[MAX_TAG_ID_LENGTH]; bcm2835_init(); #if 0 // We're assuming the caller has made sure there's a tag present /* Check for the tag a few times before giving up */ while ((tries < 10) && (!checkForTag(fd, tagId, &tagIdLen))) { tries++; tagIdLen = MAX_TAG_ID_LENGTH; usleep(50000); } if (tries < 10) #endif { /* We found a tag! */ int page = 4; // skip the first four pages as they hold general info on the tag int pageLen = MAX_TAG_ID_LENGTH; unsigned char pageData[MAX_TAG_ID_LENGTH]; while (readPage(fd, page, pageData, &pageLen)) { int j; for (j = 0; j < pageLen; j++) { #if DEBUG printf("%02x", pageData[j]); #else printf("%c", pageData[j]); #endif } page++; // move onto the next page } } }
// Given the offset of the "current" page, find the page immediately preceding // it (if any) and return its granule position. // To do this we back up from the "current" page's offset until we find any // page preceding it and then scan forward to just before the current page. uint64_t MyVorbisExtractor::findPrevGranulePosition(off_t pageOffset) { off_t prevPageOffset = 0; off_t prevGuess = pageOffset; for (;;) { if (prevGuess >= 5000) { prevGuess -= 5000; } else { prevGuess = 0; } LOGV("backing up %ld bytes", pageOffset - prevGuess); CHECK_EQ(findNextPage(prevGuess, &prevPageOffset), (status_t)OK); if (prevPageOffset < pageOffset || prevGuess == 0) { break; } } if (prevPageOffset == pageOffset) { // We did not find a page preceding this one. return 0; } LOGV("prevPageOffset at %ld, pageOffset at %ld", prevPageOffset, pageOffset); for (;;) { Page prevPage; ssize_t n = readPage(prevPageOffset, &prevPage); if (n <= 0) { return 0; } prevPageOffset += n; if (prevPageOffset == pageOffset) { return prevPage.mGranulePosition; } } }
fs_pageno FileSystem::getPageStatus(fs_pageno page) { bool mustReleaseLock = getLock(); fs_pageno result = FILESYSTEM_ERROR; int pageInTable, pageToRead, offsetInPage; if ((page < 0) || (page >= pageCount)) goto endOfGetPageStatus; pageInTable = page / intsPerPage; pageToRead = pageCount + pageInTable; offsetInPage = (page % intsPerPage) * INT_SIZE; if (readPage(pageToRead, offsetInPage, INT_SIZE, &result) == FILESYSTEM_ERROR) goto endOfGetPageStatus; endOfGetPageStatus: if (mustReleaseLock) releaseLock(); return result; } // end of getPageStatus(fs_pageno)
fs_pageno FileSystem::getPageCount(fs_fileno fileHandle) { bool mustReleaseLock = getLock(); fs_pageno result = FILESYSTEM_ERROR; int pageInTable, pageToRead, offsetInPage; if ((fileHandle < 0) || (fileHandle >= fileMappingSize * doubleIntsPerPage)) goto endOfGetPageCount; pageInTable = fileHandle / doubleIntsPerPage; pageToRead = pageCount + pageLayoutSize + pageInTable; offsetInPage = (fileHandle % doubleIntsPerPage) * 2 * INT_SIZE + INT_SIZE; if (readPage(pageToRead, offsetInPage, INT_SIZE, &result) == FILESYSTEM_ERROR) goto endOfGetPageCount; endOfGetPageCount: if (mustReleaseLock) releaseLock(); return result; } // end of getPageCount(fs_fileno)
void MyVorbisExtractor::buildTableOfContents() { off64_t offset = mFirstDataOffset; Page page; ssize_t pageSize; while ((pageSize = readPage(offset, &page)) > 0) { mTableOfContents.push(); TOCEntry &entry = mTableOfContents.editItemAt(mTableOfContents.size() - 1); entry.mPageOffset = offset; entry.mTimeUs = page.mGranulePosition * 1000000ll / mVi.rate; offset += (size_t)pageSize; } // Limit the maximum amount of RAM we spend on the table of contents, // if necessary thin out the table evenly to trim it down to maximum // size. static const size_t kMaxTOCSize = 8192; static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry); size_t numerator = mTableOfContents.size(); if (numerator > kMaxNumTOCEntries) { size_t denom = numerator - kMaxNumTOCEntries; size_t accum = 0; for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) { accum += denom; if (accum >= numerator) { mTableOfContents.removeAt(i); accum -= numerator; } } } }
status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) { *out = NULL; MediaBuffer *buffer = NULL; int64_t timeUs = -1; for (;;) { size_t i; size_t packetSize = 0; bool gotFullPacket = false; for (i = mNextLaceIndex; i < mCurrentPage.mNumSegments; ++i) { uint8_t lace = mCurrentPage.mLace[i]; packetSize += lace; if (lace < 255) { gotFullPacket = true; ++i; break; } } if (mNextLaceIndex < mCurrentPage.mNumSegments) { off64_t dataOffset = mOffset + 27 + mCurrentPage.mNumSegments; for (size_t j = 0; j < mNextLaceIndex; ++j) { dataOffset += mCurrentPage.mLace[j]; } size_t fullSize = packetSize; if (buffer != NULL) { fullSize += buffer->range_length(); } MediaBuffer *tmp = new MediaBuffer(fullSize); if (buffer != NULL) { memcpy(tmp->data(), buffer->data(), buffer->range_length()); tmp->set_range(0, buffer->range_length()); buffer->release(); } else { // XXX Not only is this not technically the correct time for // this packet, we also stamp every packet in this page // with the same time. This needs fixing later. if (mVi.rate) { // Rate may not have been initialized yet if we're currently // reading the configuration packets... // Fortunately, the timestamp doesn't matter for those. timeUs = mCurrentPage.mGranulePosition * 1000000ll / mVi.rate; } tmp->set_range(0, 0); } buffer = tmp; ssize_t n = mSource->readAt( dataOffset, (uint8_t *)buffer->data() + buffer->range_length(), packetSize); if (n < (ssize_t)packetSize) { LOGV("failed to read %d bytes at 0x%016llx, got %ld bytes", packetSize, dataOffset, n); return ERROR_IO; } buffer->set_range(0, fullSize); mNextLaceIndex = i; if (gotFullPacket) { // We've just read the entire packet. if (timeUs >= 0) { buffer->meta_data()->setInt64(kKeyTime, timeUs); } if (mFirstPacketInPage) { buffer->meta_data()->setInt32( kKeyValidSamples, mCurrentPageSamples); mFirstPacketInPage = false; } *out = buffer; return OK; } // fall through, the buffer now contains the start of the packet. } CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments); mOffset += mCurrentPageSize; ssize_t n = readPage(mOffset, &mCurrentPage); if (n <= 0) { if (buffer) { buffer->release(); buffer = NULL; } LOGV("readPage returned %ld", n); return n < 0 ? n : (status_t)ERROR_END_OF_STREAM; } mCurrentPageSamples = mCurrentPage.mGranulePosition - mPrevGranulePosition; mFirstPacketInPage = true; mPrevGranulePosition = mCurrentPage.mGranulePosition; mCurrentPageSize = n; mNextLaceIndex = 0; if (buffer != NULL) { if ((mCurrentPage.mFlags & 1) == 0) { // This page does not continue the packet, i.e. the packet // is already complete. if (timeUs >= 0) { buffer->meta_data()->setInt64(kKeyTime, timeUs); } buffer->meta_data()->setInt32( kKeyValidSamples, mCurrentPageSamples); mFirstPacketInPage = false; *out = buffer; return OK; } } } }
/* * getTableInfo -- 表のデータ定義情報を取得する関数 * * 引数: * tableName: 情報を表示する表の名前 * * 返り値: * tableNameのデータ定義情報を返す * エラーの場合には、NULLを返す * * ***注意*** * この関数が返すデータ定義情報を収めたメモリ領域は、不要になったら * 必ずfreeTableInfoで解放すること。 */ TableInfo *getTableInfo(char *tableName) { File *file; TableInfo *tableinfo; char page[PAGE_SIZE]; char *p; int num; char name[MAX_FIELD_NAME]; DataType data; int i; /* tableFileName.[DEF_FILE_EXT]という文字列を作る*/ char tableFileName[MAX_FILENAME+10]; int len = strlen(tableName) + strlen(DEF_FILE_EXT) + 1; memset(tableFileName, '\0', strlen(tableFileName)); snprintf(tableFileName, len, "%s%s", tableName, DEF_FILE_EXT); /*tableinfoをmalloc*/ tableinfo = malloc(sizeof(TableInfo)); if(tableinfo == NULL){ printErrorMessage(ERR_MSG_MALLOC, __func__, __LINE__); return NULL; } /*tableinfoを初期化*/ memset(tableinfo, 0, sizeof(TableInfo)); /*tableNameという名前のファイルを開く*/ if((file=openFile(tableFileName)) == NULL){ printErrorMessage(ERR_MSG_OPEN, __func__, __LINE__); free(tableinfo); return NULL; } /*それぞれのデータを取り出し、新しく作ったTableInfoに代入する*/ if(readPage(file, 0, page) == NG){ printErrorMessage(ERR_MSG_READ, __func__, __LINE__); free(tableinfo); return NULL; } p = page; memcpy(&num, p, sizeof(int)); p += sizeof(int); tableinfo->numField = num; for (i = 0; i < num; i++){ /*i番目の名前の取得*/ memcpy(name, p, MAX_FIELD_NAME); p += MAX_FIELD_NAME; strcpy(tableinfo->fieldInfo[i].name, name); /*i番目のデータ型の取得*/ memcpy(&data, p, sizeof(int)); p += sizeof(int); tableinfo->fieldInfo[i].dataType = data; } /*ファイルをクローズする*/ if(closeFile(file) == NG){ printErrorMessage(ERR_MSG_CLOSE, __func__, __LINE__); free(tableinfo); return NULL; } /*TableInfoを返す*/ return tableinfo; }
void MyVorbisExtractor::buildTableOfContents() { off64_t offset = mFirstDataOffset; Page page; ssize_t pageSize; #ifndef MTK_AOSP_ENHANCEMENT while ((pageSize = readPage(offset, &page)) > 0) { #else struct timeval tb,te; gettimeofday(&tb,NULL); while (mTocStarted && ((pageSize = readPage(offset, &page)) > 0)) { if(page.mGranulePosition < 0xFFFFFFFFFFFF) { #endif mTableOfContents.push(); TOCEntry &entry = mTableOfContents.editItemAt(mTableOfContents.size() - 1); entry.mPageOffset = offset; entry.mTimeUs = page.mGranulePosition * 1000000ll / mVi.rate; #ifdef MTK_AOSP_ENHANCEMENT //sleep 100ms for consumes over 2s gettimeofday(&te,NULL); if((te.tv_sec - tb.tv_sec) > 2) { gettimeofday(&tb,NULL); usleep(100000); } } #endif offset += (size_t)pageSize; } // Limit the maximum amount of RAM we spend on the table of contents, // if necessary thin out the table evenly to trim it down to maximum // size. static const size_t kMaxTOCSize = 8192; static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry); size_t numerator = mTableOfContents.size(); if (numerator > kMaxNumTOCEntries) { size_t denom = numerator - kMaxNumTOCEntries; size_t accum = 0; for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) { accum += denom; if (accum >= numerator) { mTableOfContents.removeAt(i); accum -= numerator; } } } #ifdef MTK_AOSP_ENHANCEMENT mTocDone = true; #endif } status_t MyVorbisExtractor::verifyHeader( MediaBuffer *buffer, uint8_t type) { const uint8_t *data = (const uint8_t *)buffer->data() + buffer->range_offset(); size_t size = buffer->range_length(); if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) { return ERROR_MALFORMED; } ogg_buffer buf; buf.data = (uint8_t *)data; buf.size = size; buf.refcount = 1; buf.ptr.owner = NULL; ogg_reference ref; ref.buffer = &buf; ref.begin = 0; ref.length = size; ref.next = NULL; oggpack_buffer bits; oggpack_readinit(&bits, &ref); CHECK_EQ(oggpack_read(&bits, 8), type); for (size_t i = 0; i < 6; ++i) { oggpack_read(&bits, 8); // skip 'vorbis' } switch (type) { case 1: { #ifndef MTK_AOSP_ENHANCEMENT CHECK_EQ(0, _vorbis_unpack_info(&mVi, &bits)); #else _vorbis_unpack_info(&mVi, &bits);//skip the CHECK #endif mMeta->setData(kKeyVorbisInfo, 0, data, size); mMeta->setInt32(kKeySampleRate, mVi.rate); mMeta->setInt32(kKeyChannelCount, mVi.channels); #ifdef MTK_AOSP_ENHANCEMENT if(mVi.channels > 2) { #ifndef MTK_SWIP_VORBIS SXLOGE("Tremolo does not support multi channel"); return ERROR_UNSUPPORTED; #endif } #endif ALOGV("lower-bitrate = %ld", mVi.bitrate_lower); ALOGV("upper-bitrate = %ld", mVi.bitrate_upper); ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal); ALOGV("window-bitrate = %ld", mVi.bitrate_window); off64_t size; if (mSource->getSize(&size) == OK) { uint64_t bps = approxBitrate(); if (bps != 0) { mMeta->setInt64(kKeyDuration, size * 8000000ll / bps); } } break; } case 3: { if (0 != _vorbis_unpack_comment(&mVc, &bits)) { return ERROR_MALFORMED; } parseFileMetaData(); break; } case 5: { if (0 != _vorbis_unpack_books(&mVi, &bits)) { return ERROR_MALFORMED; } mMeta->setData(kKeyVorbisBooks, 0, data, size); break; } } return OK; } uint64_t MyVorbisExtractor::approxBitrate() { if (mVi.bitrate_nominal != 0) { return mVi.bitrate_nominal; } return (mVi.bitrate_lower + mVi.bitrate_upper) / 2; } void MyVorbisExtractor::parseFileMetaData() { mFileMeta = new MetaData; #ifdef MTK_AOSP_ENHANCEMENT if(mFileMeta.get() == NULL) return; #endif mFileMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG); for (int i = 0; i < mVc.comments; ++i) { const char *comment = mVc.user_comments[i]; size_t commentLength = mVc.comment_lengths[i]; parseVorbisComment(mFileMeta, comment, commentLength); //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]); } }
off64_t MyVorbisExtractor::findAccuratePageOffset(uint64_t samples,off64_t ofStart,off64_t ofEnd) { uint64_t sgranulePosition,egranulePosition,granulePositionGuess; off64_t offsetGuess; findGranulePositionofPage(ofStart, &sgranulePosition); findGranulePositionofPage(ofEnd, &egranulePosition); SXLOGD("ofStart:%lld,sgranulePosition:%lld,ofEnd:%lld,egranulePosition:%lld,samples:%lld",ofStart,sgranulePosition,ofEnd,egranulePosition,samples); if((sgranulePosition == egranulePosition)||(samples <= sgranulePosition)) return ofStart; if(samples >= egranulePosition) return ofEnd; offsetGuess = (ofEnd *(samples - sgranulePosition) + ofStart * (egranulePosition - samples))/(egranulePosition-sgranulePosition); if(findGranulePositionofPage(offsetGuess, &granulePositionGuess) != OK) { SXLOGD("offsetGuess is abnormal,return the start offset"); return ofStart; } else SXLOGD("offsetGuess:%lld,granulePositionGuess:%lld",offsetGuess,granulePositionGuess); if(samples >= granulePositionGuess) { off64_t pageOffset; status_t err = findNextPage_l(offsetGuess, &pageOffset); if (err != OK) { return offsetGuess; } else { Page page; ssize_t n = readPage(pageOffset, &page); if (n <= 0) { return offsetGuess; } offsetGuess = pageOffset; } if(findGranulePositionofPage(offsetGuess, &granulePositionGuess) != OK) { SXLOGD("offsetGuess is abnormal,return the start offset"); return ofStart; } if(samples <= granulePositionGuess) return offsetGuess; else return findAccuratePageOffset(samples,offsetGuess,ofEnd); } else { off64_t pageOffset; status_t err = findNextPage_l(ofStart, &pageOffset); if (err != OK) { return offsetGuess; } else { Page page; ssize_t n = readPage(pageOffset, &page); if (n <= 0) { return offsetGuess; } ofStart = pageOffset; } findGranulePositionofPage(ofStart, &sgranulePosition); if(samples <= sgranulePosition) return ofStart; else return findAccuratePageOffset(samples,ofStart,offsetGuess); } }
int main(void) { int ret; int fd; int tries = 0; int tagIdLen = MAX_TAG_ID_LENGTH; unsigned char tagId[MAX_TAG_ID_LENGTH]; bcm2835_init(); // We're assuming the caller has made sure there's a tag present int page = 4; // skip the first four pages as they hold general info on the tag int pageLen = MAX_TAG_ID_LENGTH; int contentIdx = 0; // where in the content buffer we're up to while ((contentIdx < kContentsBufferLen) && readPage(fd, page, &gContentsBuffer[contentIdx], &pageLen)) { contentIdx += pageLen; page++; // move onto the next page } #if DEBUG printf("Read in %d bytes\n", contentIdx); int i; for (i = 0; i < contentIdx; i++) { printf("%02x ", gContentsBuffer[i]); if (i % 16 == 15) { printf("\n"); } } printf("\n"); #endif // Parse the content to look for NDEF records int idx = 0; while (idx < contentIdx) { // Look for the initial TLV structure uint8_t t = gContentsBuffer[idx++]; if (t != 0) { // It's not a NULL TLV #if DEBUG printf("t: %02x\n", t); #endif int l = gContentsBuffer[idx++]; idx = MIN(idx, contentIdx); if (l == 0xff) { // 3-byte length format, so the next two bytes are the actual length l = gContentsBuffer[idx++] << 8 | gContentsBuffer[idx++]; idx = MIN(idx, contentIdx); } uint8_t tnf_byte; uint8_t typeLength =0; uint32_t payloadLength =0; uint8_t idLength =0; int messageEnd = idx + l; switch (t) { case 0x03: // We've found an NDEF message // Parse out each record in it #if DEBUG printf("NDEF message found\n", t); #endif while ((idx < messageEnd) && (idx < contentIdx)) { tnf_byte = gContentsBuffer[idx++]; idx = MIN(idx, contentIdx); typeLength = gContentsBuffer[idx++]; idx = MIN(idx, contentIdx); if (tnf_byte & NDEF_RECORD_SHORT_RECORD) { payloadLength = gContentsBuffer[idx++]; } else { payloadLength = (gContentsBuffer[idx++] << 24) | (gContentsBuffer[idx++] << 16) | (gContentsBuffer[idx++] << 8) | (gContentsBuffer[idx++]); } idx = MIN(idx, contentIdx); if (tnf_byte & NDEF_RECORD_ID_LENGTH_PRESENT) { idLength = gContentsBuffer[idx++]; idx = MIN(idx, contentIdx); } #if DEBUG printf("NDEF record: tnf_byte: 0x%02x, typeLength: %d, idLength: %d, payloadLength: %d, next byte: 0x%02x\n", tnf_byte, typeLength, idLength, payloadLength, gContentsBuffer[idx]); #endif // Let's see if it's a record we're interested in... if ( ((tnf_byte & NDEF_RECORD_TNF_MASK) == NDEF_TNF_NFC_WELL_KNOWN) && (typeLength == 1) && (gContentsBuffer[idx] == NDEF_RTD_TEXT) ) { // It's text! Let's output it... idx += typeLength; // skip over the type // skip the language int langLength = gContentsBuffer[idx++]; payloadLength--; // for the langLength byte payloadLength -= langLength; idx += langLength; while (payloadLength-- > 0) { idx = MIN(idx, contentIdx); printf("%c", gContentsBuffer[idx++]); } // ...and quit exit(0); } else { // Skip this message #if DEBUG printf("Skipping (tnf_byte: %02x)\n", tnf_byte); printf("idx: %d messageEnd: %d typeLength: %d idLength: %d payloadLength: %d contentIdx: %d\n", idx, messageEnd, typeLength, idLength, payloadLength, contentIdx); #endif idx += typeLength+idLength+payloadLength; idx = MIN(idx, contentIdx); } if (tnf_byte & NDEF_RECORD_MESSAGE_END) { break; } } break; case 0xfe: // Terminator TLV block, give up now exit(1); break; default: // Skip to the next TLV idx += l; break; }; } } }
void readChip(int totMem, unsigned char *buffer) { int paginas = totMem / 256, pag; for(pag=0; pag<paginas; pag++) readPage(pag, &buffer[pag * 256]); }
int main(int argc, const char **argv) { MemServerRequestProxy *hostMemServerRequest = new MemServerRequestProxy(IfcNames_HostMemServerRequest); MMURequestProxy *dmap = new MMURequestProxy(IfcNames_HostMMURequest); DmaManager *dma = new DmaManager(dmap); MemServerIndication *hostMemServerIndication = new MemServerIndication(hostMemServerRequest, IfcNames_HostMemServerIndication); MMUIndication *hostMMUIndication = new MMUIndication(dma, IfcNames_HostMMUIndication); fprintf(stderr, "Main::allocating memory...\n"); device = new FlashRequestProxy(IfcNames_FlashRequest); FlashIndication *deviceIndication = new FlashIndication(IfcNames_FlashIndication); srcAlloc = portalAlloc(srcAlloc_sz); dstAlloc = portalAlloc(dstAlloc_sz); srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcAlloc_sz); dstBuffer = (unsigned int *)portalMmap(dstAlloc, dstAlloc_sz); fprintf(stderr, "dstAlloc = %x\n", dstAlloc); fprintf(stderr, "srcAlloc = %x\n", srcAlloc); pthread_mutex_init(&flashReqMutex, NULL); pthread_cond_init(&flashFreeTagCond, NULL); printf( "Done initializing hw interfaces\n" ); fflush(stdout); portalExec_start(); printf( "Done portalExec_start\n" ); fflush(stdout); portalDCacheFlushInval(dstAlloc, dstAlloc_sz, dstBuffer); portalDCacheFlushInval(srcAlloc, srcAlloc_sz, srcBuffer); ref_dstAlloc = dma->reference(dstAlloc); ref_srcAlloc = dma->reference(srcAlloc); for (int t = 0; t < NUM_TAGS; t++) { readTagTable[t].busy = false; writeTagTable[t].busy = false; int byteOffset = t * PAGE_SIZE; device->addDmaWriteRefs(ref_dstAlloc, byteOffset, t); device->addDmaReadRefs(ref_srcAlloc, byteOffset, t); readBuffers[t] = dstBuffer + byteOffset/sizeof(unsigned int); writeBuffers[t] = srcBuffer + byteOffset/sizeof(unsigned int); } for (int blk=0; blk<BLOCKS_PER_CHIP; blk++) { for (int c=0; c<CHIPS_PER_BUS; c++) { for (int bus=0; bus< CHIPS_PER_BUS; bus++) { flashStatus[bus][c][blk] = UNINIT; } } } for (int t = 0; t < NUM_TAGS; t++) { for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) { readBuffers[t][i] = 0; writeBuffers[t][i] = 0; } } device->start(0); device->setDebugVals(0,0); //flag, delay device->debugDumpReq(0); sleep(1); device->debugDumpReq(0); sleep(1); //TODO: test writes and erases //test erases for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ eraseBlock(bus, chip, blk, waitIdleEraseTag()); } } } while (true) { usleep(100); if ( getNumErasesInFlight() == 0 ) break; } //read back erased pages for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ int page = 0; readPage(bus, chip, blk, page, waitIdleReadBuffer()); } } } while (true) { usleep(100); if ( getNumReadsInFlight() == 0 ) break; } //write pages //FIXME: in old xbsv, simulatneous DMA reads using multiple readers cause kernel panic //Issue each bus separately for now for (int bus = 0; bus < NUM_BUSES; bus++){ for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ int page = 0; //get free tag int freeTag = waitIdleWriteBuffer(); //fill write memory for (int w=0; w<PAGE_SIZE/sizeof(unsigned int); w++) { writeBuffers[freeTag][w] = hashAddrToData(bus, chip, blk, w); } //send request writePage(bus, chip, blk, page, freeTag); } while (true) { usleep(100); if ( getNumWritesInFlight() == 0 ) break; } } } //each bus timespec start, now; clock_gettime(CLOCK_REALTIME, & start); for (int repeat = 0; repeat < 1; repeat++){ for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ //int blk = rand() % 1024; //int chip = rand() % 8; //int bus = rand() % 8; int page = 0; readPage(bus, chip, blk, page, waitIdleReadBuffer()); } } } } int elapsed = 0; while (true) { usleep(100); if (elapsed == 0) { elapsed=10000; device->debugDumpReq(0); } else { elapsed--; } if ( getNumReadsInFlight() == 0 ) break; } device->debugDumpReq(0); clock_gettime(CLOCK_REALTIME, & now); fprintf(stderr, "LOG: finished reading from page! %f\n", timespec_diff_sec(start, now) ); for ( int t = 0; t < NUM_TAGS; t++ ) { for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) { fprintf(stderr, "%x %x %x\n", t, i, readBuffers[t][i] ); } } if (testPass==1) { fprintf(stderr, "LOG: TEST PASSED!\n"); } else { fprintf(stderr, "LOG: **ERROR: TEST FAILED!\n"); } }
void crawler::loadPage(std::string url) { std::string content; boost::match_results<std::string::const_iterator> res; boost::regex_search(url, res, baseUrlPattern); std::string baseUrl = res[1]; visitedLock.lock(); std::cout << lineOverride << pageQueue.size() << " " << connErrors << "e " << dict.size() << "w " << pageQueue.size() / (float) pageCounter << std::flush; #ifdef BASE_MAX int count = visited.count(baseUrl); if (count >= BASE_MAX) { #else int count = visited.count(url); if (count) { #endif visitedLock.unlock(); return; } visitedLock.unlock(); if (!readPage(url, content)) return; addContentToQueue(url, content); } void crawler::analyzePage(std::string url, std::string content) { if (!boost::regex_match(content, doctypePattern)) return; boost::match_results<std::string::const_iterator> res; boost::regex_search(url, res, urlPattern); std::string baseUrl = res[3]; std::string folderUrl = res[2]; std::string fileUrl = res[1]; visitedLock.lock(); #ifdef BASE_MAX int count = visited.count(baseUrl); if (count >= BASE_MAX) { #else int count = visited.count(url); if (count) { #endif visitedLock.unlock(); return; } else if (!count) { #ifdef USE_BASE std::cout << lineOverride << ++pageCounter << " " << baseUrl << " " << std::endl; #else std::cout << lineOverride << ++pageCounter << " " << url << " " << std::endl; #endif } #ifdef BASE_MAX visited.insert(baseUrl); #else visited.insert(url); #endif visitedLock.unlock(); boost::sregex_iterator hrefIt(content.begin(), content.end(), linkPattern); std::for_each(hrefIt, boost::sregex_iterator(), [this, baseUrl, fileUrl, folderUrl](const boost::match_results<std::string::const_iterator>& what) { std::string link = what[1]; if (boost::regex_match(link, javascriptPattern)) { return; } if (link.substr(0, 1) == ".") { link = "/" + link; } if (link.substr(0, 7) == "http://" || link.substr(0, 8) == "https://") { } else if (link.substr(0, 2) == "//") { link = "http:" + link; } else if (link.substr(0, 1) == "/") { link = baseUrl + link; } else if (link.substr(0, 1) == "?") { link = fileUrl + link; } else { link = folderUrl + link; } if (boost::regex_match(link, ignoreTypePattern)) { return; } boost::match_results<std::string::const_iterator> res; #ifdef REQUIRE_TLD boost::regex_search(link, res, tldPattern); if (res[1] != REQUIRE_TLD) { return; } #endif #ifdef REQUIRE_URL boost::regex_search(link, res, baseUrlPattern); if(res[1] != REQUIRE_URL) { return; } #endif boost::regex_search(link, res, baseUrlPattern); std::string baseLink = res[1]; visitedLock.lock(); #ifdef BASE_MAX if (visited.count(baseLink) < BASE_MAX) { #else if (!visited.count(link)) { #endif #ifdef USE_BASE addPageToQueue(baseLink); #else addPageToQueue(link); #endif } visitedLock.unlock(); }); content = boost::regex_replace(content, ignoreTagsPattern, " ", boost::match_default | boost::format_all); content = boost::regex_replace(content, tagPattern, " ", boost::match_default | boost::format_all); boost::sregex_token_iterator wordIt(content.begin(), content.end(), wordPattern, 0), wordItEnd; dictLock.lock(); while (wordIt != wordItEnd) { std::string word = *wordIt++; auto it = dict.find(word); if (it == dict.end()) { dict.insert(std::make_pair(word, 1)); } else { it->second++; } } dictLock.unlock(); } bool crawler::readPage(std::string &url, std::string &pageData) { try { curlpp::Easy myRequest; myRequest.setOpt<curlpp::options::WriteFunction>( [&pageData](char* buf, size_t size, size_t nmemb) { for (int c = 0; c < size * nmemb; c++) { pageData.push_back(buf[c]); } return size*nmemb; }); myRequest.setOpt<curlpp::options::FollowLocation>(1); myRequest.setOpt<curlpp::options::Url>(url); myRequest.setOpt<curlpp::options::Timeout>(TIMEOUT); myRequest.perform(); url = curlpp::infos::EffectiveUrl().get(myRequest); } catch (curlpp::RuntimeError & e) { connErrors++; return false; } catch (curlpp::LogicError & e) { connErrors++; return false; } return true; }
int FileSystem::readPage(fs_pageno pageNumber, void *buffer) { return readPage(pageNumber, 0, pageSize, buffer); }
//Leo una pagina y luego la muevo a la posicion deseada void copyPage(int from, int to) { char *page = readPage(from); writePage(to, page); }
//--------------------------------------------- //Local erase, read, write, read test //--------------------------------------------- void local_test(bool check, int read_repeat, int debug_lvl ) { LOG(0, "LOG: starting local_test...\n"); g_checkdata = check; g_debuglevel = debug_lvl; g_testpass = true; int node = myid; timespec start, now; double timeElapsed = 0; double bw = 0; //erase all blocks for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ eraseBlock(node, bus, chip, blk, waitIdleEraseTag()); } } } while (true) { if ( getNumErasesInFlight() == 0 ) break; } //read back erased pages for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ int page = 0; readPage(node, bus, chip, blk, page, waitIdleReadBuffer()); } } } while (true) { if ( getNumReadsInFlight() == 0 ) break; } int pagesWritten = 0; clock_gettime(CLOCK_REALTIME, & start); //write pages for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ int page = 0; int freeTag = waitIdleWriteBuffer(); if (g_checkdata) { //fill write memory only if we're doing readback checks for (int w=0; w<PAGE_SIZE/sizeof(unsigned int); w++) { writeBuffers[freeTag][w] = hashAddrToData(node, bus, chip, blk, w); } } //send request writePage(node, bus, chip, blk, page, freeTag); pagesWritten++; } } } while (true) { if ( getNumWritesInFlight() == 0 ) break; } clock_gettime(CLOCK_REALTIME, & now); timeElapsed = timespec_diff_sec(start, now); bw = (pagesWritten*8)/timeElapsed/1024; //MB/s //double latency = timeElapsed/pagesWritten; //double latency_us = latency*1000000; LOG(0, "LOG: finished writing to page. Time=%f, NumPages=%d, BW=%f MB/s\n", timeElapsed, pagesWritten, bw); int pagesRead = 0; clock_gettime(CLOCK_REALTIME, & start); for (int rep = 0; rep < read_repeat; rep++) { for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ int page = 0; readPage(node, bus, chip, blk, page, waitIdleReadBuffer()); pagesRead++; } } } } while (true) { if ( getNumReadsInFlight() == 0 ) break; } clock_gettime(CLOCK_REALTIME, & now); timeElapsed = timespec_diff_sec(start, now); bw = (pagesRead*8)/timeElapsed/1024; //MB/s LOG(0, "LOG: reading from page. Time=%f, NumPages=%d, BW=%f MB/s\n", timeElapsed, pagesRead, bw); device->debugDumpReq(0); sleep(1); for ( int t = 0; t < NUM_TAGS; t++ ) { for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) { LOG(1, "%x %x %x\n", t, i, readBuffers[t][i] ); } } if (g_checkdata) { if (g_testpass) { LOG(0, "LOG: local_test passed!\n"); } else { LOG(0, "LOG: **ERROR: local_test FAILED!\n"); } } else { LOG(0, "LOG: local_test complete. No checks done\n"); } }
int FileSystem::defrag() { printf("defrag called\n"); exit(1); int32_t nextFreePage = 1; int32_t *newPosition = (int32_t*)malloc(pageCount * sizeof(int32_t)); // page 0 must not be moved around newPosition[0] = 0; for (int i = 1; i < pageCount; i++) newPosition[i] = -1; // first, perform a DFS to assign new page positions int upperFileLimit = doubleIntsPerPage * fileMappingSize; for (int file = 0; file < upperFileLimit; file++) { int32_t page = getFirstPage(file); while (page > 0) { assert(newPosition[page] < 0); newPosition[page] = nextFreePage++; page = getPageStatus(page); } } // end for (int file = 0; file < upperFileLimit; file++) // then, assign new page numbers to the remaining (free) pages for (int i = 1; i < pageCount; i++) if (getPageStatus(i) == UNUSED_PAGE) newPosition[i] = nextFreePage++; // make sure that every page has been assigned a new location assert(nextFreePage == pageCount); // correct data in the page layout table int32_t *oldPageLayout = (int32_t*)malloc(pageLayoutSize * intsPerPage * sizeof(int32_t)); int32_t *newPageLayout = (int32_t*)malloc(pageLayoutSize * intsPerPage * sizeof(int32_t)); for (int i = 0; i < pageLayoutSize; i++) readPage(pageCount + i, &oldPageLayout[intsPerPage * i]); for (int page = 0; page < pageCount; page++) { if (oldPageLayout[page] <= 0) newPageLayout[newPosition[page]] = oldPageLayout[page]; else newPageLayout[newPosition[page]] = newPosition[oldPageLayout[page]]; } for (int i = 0; i < pageLayoutSize; i++) writePage(pageCount + i, &newPageLayout[intsPerPage * i]); free(newPageLayout); free(oldPageLayout); // correct page numbers in the file->page table for (int file = 0; file < upperFileLimit; file++) { int32_t page = getFirstPage(file); if (page >= 0) setFirstPage(file, newPosition[page]); } // end for (int file = 0; file < upperFileLimit; file++) byte *buffer1 = (byte*)malloc(pageSize); byte *buffer2 = (byte*)malloc(pageSize); // happy reading/writing while moving all pages to their new positions for (int page = 0; page < pageCount; page++) { int currentPage = page; while (newPosition[currentPage] != currentPage) { assert(newPosition[currentPage] >= page); int32_t newPos = newPosition[currentPage]; // swap data in pages "currentPage" and "newPos" if (readPage(currentPage, buffer1) == FILESYSTEM_ERROR) return FILESYSTEM_ERROR; if (readPage(newPos, buffer2) == FILESYSTEM_ERROR) return FILESYSTEM_ERROR; if (writePage(newPos, buffer1) == FILESYSTEM_ERROR) return FILESYSTEM_ERROR; if (writePage(currentPage, buffer2) == FILESYSTEM_ERROR) return FILESYSTEM_ERROR; // update permutation table newPosition[currentPage] = newPosition[newPos]; newPosition[newPos] = newPos; } } // end for (int page = 0; page < pageCount; page++) free(buffer2); free(buffer1); free(newPosition); return FILESYSTEM_SUCCESS; } // end of defrag()
int FileSystem::changeSize(fs_pageno newPageCount) { bool mustReleaseLock = getLock(); int result = FILESYSTEM_ERROR; // if "newPageCount" is too small, an error is returned if ((newPageCount < MIN_PAGE_COUNT) || (newPageCount < getUsedPageCount()) || (newPageCount > MAX_PAGE_COUNT)) goto endOfChangeSize; if (newPageCount < pageCount) { // First, defragment the filesystem in order to be able to reduce the size. if (defrag() == FILESYSTEM_ERROR) goto endOfChangeSize; // Then, decrease the size of the filesystem. int newPageLayoutSize = (newPageCount + (intsPerPage - 1)) / intsPerPage; byte *pageBuffer = (byte*)malloc(pageSize); // copy page layout data to new position for (int i = 0; i < newPageLayoutSize; i++) { readPage(pageCount + i, pageBuffer); writePage(newPageCount + i, pageBuffer); } // copy file->page mappings to new position for (int i = 0; i < fileMappingSize; i++) { readPage(pageCount + pageLayoutSize + i, pageBuffer); writePage(newPageCount + newPageLayoutSize + i, pageBuffer); } free(pageBuffer); pageCount = newPageCount; pageLayoutSize = newPageLayoutSize; // write changed preamble to disk int32_t pageCountOnDisk = (int32_t)pageCount; int32_t pageLayoutSizeOnDisk = (int32_t)pageLayoutSize; lseek(dataFile, 2 * INT_SIZE, SEEK_SET); forced_write(dataFile, &pageCountOnDisk, INT_SIZE); forced_write(dataFile, &pageLayoutSizeOnDisk, INT_SIZE); // change the size of the data file off_t fileSize = pageSize; fileSize *= (newPageCount + newPageLayoutSize + fileMappingSize); forced_ftruncate(dataFile, fileSize); } // end if (newPageCount < pageCount) if (newPageCount > pageCount) { // change the size of the data file int newPageLayoutSize = (newPageCount + (intsPerPage - 1)) / intsPerPage; off_t fileSize = pageSize; fileSize *= (newPageCount + newPageLayoutSize + fileMappingSize); if (ftruncate(dataFile, fileSize) < 0) { fprintf(stderr, "Filesystem size could not be changed.\n"); perror(NULL); goto endOfChangeSize; } if (getSize() != fileSize) { fprintf(stderr, "Filesystem size could not be changed.\n"); perror(NULL); goto endOfChangeSize; } int oldPageCount = pageCount; pageCount = newPageCount; int oldPageLayoutSize = pageLayoutSize; pageLayoutSize = newPageLayoutSize; // write changed preamble to disk int32_t pageCountOnDisk = (int32_t)pageCount; int32_t pageLayoutSizeOnDisk = (int32_t)pageLayoutSize; lseek(dataFile, 2 * INT_SIZE, SEEK_SET); forced_write(dataFile, &pageCountOnDisk, INT_SIZE); forced_write(dataFile, &pageLayoutSizeOnDisk, INT_SIZE); byte *pageBuffer = (byte*)malloc(pageSize); // copy file->page mappings to new position for (int i = fileMappingSize - 1; i >= 0; i--) { readPage(oldPageCount + oldPageLayoutSize + i, pageBuffer); writePage(newPageCount + newPageLayoutSize + i, pageBuffer); } // copy page layout data to new position for (int i = oldPageLayoutSize - 1; i >= 0; i--) { readPage(oldPageCount + i, pageBuffer); writePage(newPageCount + i, pageBuffer); } // initialize layout data for the new pages int32_t unusedValue = UNUSED_PAGE; for (int i = 0; i < intsPerPage; i++) memcpy(&pageBuffer[i * INT_SIZE], &unusedValue, INT_SIZE); for (int i = oldPageLayoutSize; i < newPageLayoutSize; i++) writePage(newPageCount + i, pageBuffer); free(pageBuffer); // update the freePages and freeFileNumbers arrays free(freePages); freePages = NULL; free(freeFileNumbers); freeFileNumbers = NULL; initializeFreeSpaceArrays(); } // end if (newPageCount > pageCount) enableCaching(); result = FILESYSTEM_SUCCESS; endOfChangeSize: if (mustReleaseLock) releaseLock(); return result; } // end of changeSize(fs_pageno)
fs_pageno FileSystem::claimFreePage(fs_fileno owner, fs_pageno closeTo) { bool mustReleaseLock = getLock(); int result = FILESYSTEM_ERROR; fs_pageno oldPageCount, newPageCount; int origCloseTo = closeTo; if ((closeTo < 0) || (closeTo >= pageCount)) { origCloseTo = 0; closeTo = 0; } else closeTo = closeTo / intsPerPage; // buffer for speeding up the individual status requests int32_t *data = (int32_t*)malloc((intsPerPage + 1) * sizeof(int32_t)); if (freePages[closeTo] > 0) { if (readPage(pageCount + closeTo, data) == FILESYSTEM_ERROR) { free(data); goto endOfClaimFreePage; } for (int j = origCloseTo % intsPerPage; j < intsPerPage; j++) if (data[j] == UNUSED_PAGE) { free(data); result = closeTo * intsPerPage + j; goto endOfClaimFreePage; } for (int j = origCloseTo % intsPerPage; j >= 0; j--) if (data[j] == UNUSED_PAGE) { free(data); result = closeTo * intsPerPage + j; goto endOfClaimFreePage; } } // end if (freePages[closeTo] > 0) // if nothing close to "closeTo" can be found, just search everywhere for (int j = closeTo + 1; j < pageLayoutSize; j++) { if (freePages[j] > 0) { if (readPage(pageCount + j, data) == FILESYSTEM_ERROR) { free(data); goto endOfClaimFreePage; } for (int k = 0; k < intsPerPage; k++) { if (data[k] == UNUSED_PAGE) { free(data); result = j * intsPerPage + k; goto endOfClaimFreePage; } } } } for (int j = closeTo - 1; j >= 0; j--) { if (freePages[j] > 0) { if (readPage(pageCount + j, data) == FILESYSTEM_ERROR) { free(data); goto endOfClaimFreePage; } for (int k = 0; k < intsPerPage; k++) { if (data[k] == UNUSED_PAGE) { free(data); result = j * intsPerPage + k; goto endOfClaimFreePage; } } } } free(data); // If we come here, then no free page has been found. If pageCount has reached // its maximum value, return an error code. assert(pageCount < MAX_PAGE_COUNT); // Increase the size of the filesystem. oldPageCount = pageCount; if (pageCount <= SMALL_FILESYSTEM_THRESHOLD) newPageCount = (fs_pageno)(1.41 * 1.41 * oldPageCount); else newPageCount = (fs_pageno)(1.41 * oldPageCount); // obey some constraints on the number of pages in the system while (newPageCount % (pageSize / INT_SIZE) != 0) newPageCount++; if (newPageCount > MAX_PAGE_COUNT) newPageCount = MAX_PAGE_COUNT; if (changeSize(newPageCount) < 0) goto endOfClaimFreePage; result = claimFreePage(owner, oldPageCount); endOfClaimFreePage: if (mustReleaseLock) releaseLock(); return result; } // end of claimFreePage(...)