MediaBlock* MediaBlockMap::LastBlock() const { if (CountBlocks() == 0) return NULL; return BlockAt(CountBlocks()-1); }
// TODO various optimizations possible int64 MediaBlockMap::CountFrames() const { int64 ret = 0; for (int32 i = 0; i < CountBlocks(); i++) { MediaBlock* block = BlockAt(i); ret += block->CountFrames(); } return ret; }
int64 MediaBlockMap::PreviewFrames() const { int64 frames = 0; for (int32 i = 0; i < CountBlocks(); i++) { MediaBlock* block = BlockAt(i); frames += block->PreviewFrames(); } return frames; }
int64 MediaBlockMap::BlockPlacement(int32 index) const { if (index >= CountBlocks()) return -1; int64 ret = 0; for (int32 i = 0; i < index; i++) { MediaBlock* block = BlockAt(i); ret += block->CountFrames(); } return ret; }
int32 MediaBlockMap::BlockForFrame(int64 frame, int64* startFrame) const { int64 count = 0; for (int32 i = 0; i < CountBlocks(); i++) { MediaBlock* block = BlockAt(i); int64 nextCount = count+block->CountFrames(); if (frame >= count && frame < nextCount) { *startFrame = count; return i; } count = nextCount; } return -1; }
// Mount status_t Volume::Mount(fs_volume *fsVolume, const char *path) { Unmount(); status_t error = (path ? B_OK : B_BAD_VALUE); fFSVolume = fsVolume; // load the settings if (error == B_OK) { fSettings = new(nothrow) Settings; if (fSettings) error = fSettings->SetTo(path); else error = B_NO_MEMORY; } // copy the device name if (error == B_OK) { fDeviceName = new(nothrow) char[strlen(path) + 1]; if (fDeviceName) strcpy(fDeviceName, path); else error = B_NO_MEMORY; } // open disk if (error == B_OK) { fDevice = open(path, O_RDONLY); if (fDevice < 0) SET_ERROR(error, errno); } // read and analyze super block if (error == B_OK) error = _ReadSuperBlock(); if (error == B_OK) UpdateName(fsVolume->partition); // create and init block cache if (error == B_OK) { fBlockCache = new(nothrow) BlockCache; if (fBlockCache) error = fBlockCache->Init(fDevice, CountBlocks(), GetBlockSize()); else error = B_NO_MEMORY; } // create the tree if (error == B_OK) { fTree = new(nothrow) Tree; if (!fTree) error = B_NO_MEMORY; } // get the root node and init the tree if (error == B_OK) { Block *rootBlock = NULL; error = fBlockCache->GetBlock(fSuperBlock->GetRootBlock(), &rootBlock); REPORT_ERROR(error); if (error == B_OK) { rootBlock->SetKind(Block::KIND_FORMATTED); error = fTree->Init(this, rootBlock->ToNode(), fSuperBlock->GetTreeHeight()); REPORT_ERROR(error); rootBlock->Put(); } } // get the root VNode (i.e. the root dir) if (error == B_OK) { fRootVNode = new(nothrow) VNode; if (fRootVNode) { error = FindVNode(REISERFS_ROOT_PARENT_OBJECTID, REISERFS_ROOT_OBJECTID, fRootVNode); REPORT_ERROR(error); if (error == B_OK) { error = publish_vnode(fFSVolume, fRootVNode->GetID(), fRootVNode, &gReiserFSVnodeOps, S_IFDIR, 0); } REPORT_ERROR(error); } else error = B_NO_MEMORY; } // init the hash function if (error == B_OK) _InitHashFunction(); // init the negative entry list if (error == B_OK) _InitNegativeEntries(); // cleanup on error if (error != B_OK) Unmount(); RETURN_ERROR(error); }
// CountFreeBlocks off_t Volume::CountFreeBlocks() const { // TODO:... return CountBlocks() - fBlockAllocator->GetUsedBytes() / kDefaultBlockSize; }
void FlowSave( hw_reg_set *preg ) /*******************************/ { int score; int i, j; int best; int num_blocks; int num_regs; int curr_reg; hw_reg_set *curr_push; reg_flow_info *reg_info; block *save; block *restore; instruction *ins; type_class_def reg_type; HW_CAsgn( flowedRegs, HW_EMPTY ); if( _IsntModel( FLOW_REG_SAVES ) ) return; if( !HaveDominatorInfo ) return; // we can't do this if we have push's which are 'live' at the end of a block // - this flag is set when we see a push being generated for a call in a different // block #if _TARGET & _TARG_INTEL if( CurrProc->targ.never_sp_frame ) return; #endif num_regs = CountRegs( *preg ); if( num_regs == 0 ) return; reg_info = CGAlloc( num_regs * sizeof( reg_flow_info ) ); num_blocks = CountBlocks(); InitBlockArray(); curr_push = PushRegs; for( curr_reg = 0; curr_reg < num_regs; curr_reg++ ) { while( !HW_Ovlap( *curr_push, *preg ) ) curr_push++; HW_Asgn( reg_info[curr_reg].reg, *curr_push ); reg_info[curr_reg].save = NULL; reg_info[curr_reg].restore = NULL; #if _TARGET & _TARG_INTEL if( HW_COvlap( *curr_push, HW_BP ) ) continue; // don't mess with BP - it's magical #endif GetRegUsage( ®_info[curr_reg] ); best = 0; for( i = 0; i < num_blocks; i++ ) { for( j = 0; j < num_blocks; j++ ) { if( PairOk( blockArray[i], blockArray[j], ®_info[0], curr_reg ) ) { // we use the number of blocks dominated by the save block plus // the number of blocks post-dominated by the restore block as a // rough metric for determining how much we like a given (valid) // pair of blocks - the more blocks dominated, the further 'in' // we have pushed the save, which should be good score = CountDomBits( &blockArray[i]->dom.dominator ); score += CountDomBits( &blockArray[j]->dom.post_dominator ); if( score > best ) { best = score; reg_info[curr_reg].save = blockArray[i]; reg_info[curr_reg].restore = blockArray[j]; } } } } // so now we know where we are going to save and restore the register // emit the instructions to do so, and remove reg from the set to push // in the normal prolog sequence save = reg_info[curr_reg].save; restore = reg_info[curr_reg].restore; if( ( save != NULL && save != HeadBlock ) && ( restore != NULL && !_IsBlkAttr( restore, BLK_RETURN ) ) ) { reg_type = WD; #if _TARGET & _TARG_INTEL if( IsSegReg( reg_info[curr_reg].reg ) ) { reg_type = U2; } #endif ins = MakeUnary( OP_PUSH, AllocRegName( reg_info[curr_reg].reg ), NULL, reg_type ); ResetGenEntry( ins ); PrefixIns( save->ins.hd.next, ins ); ins = MakeUnary( OP_POP, NULL, AllocRegName( reg_info[curr_reg].reg ), reg_type ); ins->num_operands = 0; ResetGenEntry( ins ); SuffixIns( restore->ins.hd.prev, ins ); HW_TurnOff( *preg, reg_info[curr_reg].reg ); HW_TurnOn( flowedRegs, reg_info[curr_reg].reg ); FixStackDepth( save, restore ); } curr_push++; } CGFree( reg_info ); }