예제 #1
0
EnduranceEeprom::EnduranceEeprom(SafeEeprom &eeprom, uint16_t startAddr, uint16_t endurFactor, size_t dataSize) :
  m_eeprom(eeprom),
  m_statusAddr(startAddr),
  m_endurFactor(endurFactor),
  m_dataSize(dataSize)
{
  if ( m_endurFactor > 1 ) {
    // Check if there is enough memory from the start address
    if ( (startAddr+storageSize()) > (1+E2END) ) {
      exit(-1);
    }
#ifdef SERIAL_DEBUG
    if ( ( dataSize % E2PAGESIZE ) != 0 ) {
      Serial.println("EnduranceEeprom Warning: dataSize is not a multiple of the page size -> non optimal endurance!");
    }
#endif
    m_dataAddr = m_statusAddr+m_endurFactor*sizeof(Status);
    bool found = findCurrent();
    if ( ! found ) {
      // This area of memory has never been used for this circular buffer
      m_status.index = 1;
      for ( uint16_t i=0; i<m_dataSize; i++) {
        m_eeprom.write_byte(m_dataAddr+i, 0xFF);
      }
      m_status.crc16 = memCrc16(m_dataAddr, m_dataSize);
      m_eeprom.write_block(m_statusAddr, (void *)&m_status, sizeof(Status));
    }
    else {
    }
  }
  else {
    m_dataAddr = m_statusAddr;
  }
}
예제 #2
0
파일: memory.cpp 프로젝트: AllenWeb/gypsum
Chunk::Chunk(VM* vm, u32 id)
    : vm_(vm),
      id_(id) {
  // We don't initialize the marking bitmap or the contents of the page, since the kernel will
  // zero-initialize pages before giving them to us.
  auto freePlace = reinterpret_cast<void*>(storageBase());
  auto free = new(freePlace, storageSize()) Free(nullptr);
  setFreeListHead(free);
}
예제 #3
0
    void RecordStoreV1Base::appendCustomStats( OperationContext* txn,
                                               BSONObjBuilder* result,
                                               double scale ) const {
        result->append( "lastExtentSize", _details->lastExtentSize(txn) / scale );
        result->append( "paddingFactor", _details->paddingFactor() );
        result->append( "userFlags", _details->userFlags() );

        if ( isCapped() ) {
            result->appendBool( "capped", true );
            result->appendNumber( "max", _details->maxCappedDocs() );
            result->appendNumber( "maxSize", static_cast<long long>( storageSize( txn, NULL, 0 ) ) );
        }
    }
예제 #4
0
TimePermRingBuffer::TimePermRingBuffer(uint16_t startAddr, uint16_t bufferSize,
                                       size_t dataSize, int timePeriod,
                                       uint16_t endurFactor) :
  EepromRingBuffer(startAddr, bufferSize, dataSize, endurFactor),
  m_period(timePeriod),
  m_lastTimeStamp(startAddr+storageSize(), endurFactor, sizeof(long))
{
  // long time;
  // m_lastTimeStamp.readData((void *)&time);
  // if ( 0xFFFFFFFFl == time ) {
  //   time = INT32_MIN;
  //   m_lastTimeStamp.writeData((void *)&time);
  // }
}
예제 #5
0
void RecordStoreV1Base::appendCustomStats(OperationContext* txn,
                                          BSONObjBuilder* result,
                                          double scale) const {
    result->append("lastExtentSize", _details->lastExtentSize(txn) / scale);
    result->append("paddingFactor", 1.0);  // hard coded
    result->append("paddingFactorNote",
                   "paddingFactor is unused and unmaintained in 3.0. It "
                   "remains hard coded to 1.0 for compatibility only.");
    result->append("userFlags", _details->userFlags());
    result->appendBool("capped", isCapped());
    if (isCapped()) {
        result->appendNumber("max", _details->maxCappedDocs());
        result->appendNumber("maxSize", static_cast<long long>(storageSize(txn, NULL, 0) / scale));
    }
}
예제 #6
0
void AppStorage::CheckSlot(size_t slot_index)
{
  auto &slot = slot_storage_[slot_index];
  auto &slot_info = slots_[slot_index];

  slot_info.id = slot.header.id;
  if (!slot.header.id || !slot.header.valid_length) {
    SERIAL_PRINTLN("Slot %u: id=%04x, valid_length=%u -- Empty", slot_index, slot.header.id, slot.header.valid_length);
    slot_info.state = SLOT_STATE::EMPTY;
    return;
  }

  slot_info.state = SLOT_STATE::CORRUPT;
  if (!slot.CheckCRC()) {
    SERIAL_PRINTLN("Slot %u: id=%04x, valid_length=%u -- CRC check failed", slot_index, slot.header.id, slot.header.valid_length);
    return;
  }

  SERIAL_PRINTLN("Slot %u: id=%04x, valid_length=%u", slot_index, slot.header.id, slot.header.valid_length);
  auto app = app_switcher.find(slot_info.id);
  if (!app) {
    SERIAL_PRINTLN("Slot %u: id=%04x -- App not found!", slot_index, slot.header.id);
    return;
  }
  SERIAL_PRINTLN("Slot %u: id=%04x found app '%s'", slot_index, slot.header.id, app->name);

  if (slot.header.version != app->storage_version) {
    SERIAL_PRINTLN("Slot %u: id=%04x -- version mismatch, expected %04x, got %04x", slot_index, slot.header.id, app->storage_version, slot.header.version);
  }

  // Some apps might have variable length settings, so there might not be a
  // safe way to check this.
  size_t expected_length = app->storageSize();
  if (slot.header.valid_length > expected_length) {
    SERIAL_PRINTLN("Slot %u: id=%04x -- storage length mismatch, expected %u, got %u", slot_index, slot.header.id, expected_length, slot.header.valid_length);
    return;
  }

  slot_info.state = SLOT_STATE::OK;
}
예제 #7
0
    DiskLoc NamespaceDetails::cappedAlloc(const char *ns, int len) {
        
        if ( len > theCapExtent()->length ) {
            // the extent check is a way to try and improve performance
            uassert( 16328 , str::stream() << "document is larger than capped size " 
                     << len << " > " << storageSize() , len <= storageSize() );
        }
        
        // signal done allocating new extents.
        if ( !cappedLastDelRecLastExtent().isValid() )
            getDur().writingDiskLoc( cappedLastDelRecLastExtent() ) = DiskLoc();

        verify( len < 400000000 );
        int passes = 0;
        int maxPasses = ( len / 30 ) + 2; // 30 is about the smallest entry that could go in the oplog
        if ( maxPasses < 5000 ) {
            // this is for bacwards safety since 5000 was the old value
            maxPasses = 5000;
        }
        DiskLoc loc;

        // delete records until we have room and the max # objects limit achieved.

        /* this fails on a rename -- that is ok but must keep commented out */
        //verify( theCapExtent()->ns == ns );

        theCapExtent()->assertOk();
        DiskLoc firstEmptyExtent;
        while ( 1 ) {
            if ( _stats.nrecords < maxCappedDocs() ) {
                loc = __capAlloc( len );
                if ( !loc.isNull() )
                    break;
            }

            // If on first iteration through extents, don't delete anything.
            if ( !_capFirstNewRecord.isValid() ) {
                advanceCapExtent( ns );

                if ( _capExtent != _firstExtent )
                    _capFirstNewRecord.writing().setInvalid();
                // else signal done with first iteration through extents.
                continue;
            }

            if ( !_capFirstNewRecord.isNull() &&
                    theCapExtent()->firstRecord == _capFirstNewRecord ) {
                // We've deleted all records that were allocated on the previous
                // iteration through this extent.
                advanceCapExtent( ns );
                continue;
            }

            if ( theCapExtent()->firstRecord.isNull() ) {
                if ( firstEmptyExtent.isNull() )
                    firstEmptyExtent = _capExtent;
                advanceCapExtent( ns );
                if ( firstEmptyExtent == _capExtent ) {
                    maybeComplain( ns, len );
                    return DiskLoc();
                }
                continue;
            }

            DiskLoc fr = theCapExtent()->firstRecord;
            theDataFileMgr.deleteRecord(this, ns, fr.rec(), fr, true); // ZZZZZZZZZZZZ
            compact();
            if( ++passes > maxPasses ) {
                StringBuilder sb;
                sb << "passes >= maxPasses in NamespaceDetails::cappedAlloc: ns: " << ns
                   << ", len: " << len
                   << ", maxPasses: " << maxPasses
                   << ", _maxDocsInCapped: " << _maxDocsInCapped
                   << ", nrecords: " << _stats.nrecords
                   << ", datasize: " << _stats.datasize;
                msgasserted(10345, sb.str());
            }
        }

        // Remember first record allocated on this iteration through capExtent.
        if ( _capFirstNewRecord.isValid() && _capFirstNewRecord.isNull() )
            getDur().writingDiskLoc(_capFirstNewRecord) = loc;

        return loc;
    }
예제 #8
0
size_t MemoryManager::objectCount()
{   
    return storageSize() - freeSlotsCount();
}