Ejemplo n.º 1
0
static
IMG_VOID RestructureLoopToExecPred(PINTERMEDIATE_STATE psState, PLOOP_INFO psLoopInfo, PUSC_LIST psLoopInfoLst)
{
	PCFG psLoopCfg;
	IMG_BOOL bGenerateInfiniteLoop;
	IMG_UINT32 uLoopPredReg;
	IMG_BOOL bInvertLoopPredReg;	
	RestructureLoop(psState, psLoopInfo, &psLoopCfg, &bGenerateInfiniteLoop, &uLoopPredReg, &bInvertLoopPredReg, psLoopInfoLst);
	RestructureNoneLoopCfgToExecPred(psState, psLoopCfg, IMG_FALSE);
	{
		PCODEBLOCK psCndEfLoopBlock = NULL;
		{
			psCndEfLoopBlock = AllocateBlock(psState, psLoopCfg);
			RedirectEdgesFromPredecessors(psState, psLoopCfg->psExit, psCndEfLoopBlock, IMG_FALSE);
			AppendExecPredInst(psState, psCndEfLoopBlock, ICNDEFLOOP, USC_PREDREG_NONE, IMG_TRUE, USC_PREDREG_NONE, 0);				
		}
		{
			PCODEBLOCK psCndExeLtBlock = AllocateBlock(psState, psLoopCfg);
			IMG_UINT32 uPDstLoop = GetNextPredicateRegister(psState);
			AppendExecPredInst(psState, psCndExeLtBlock, ICNDLT, uLoopPredReg, bGenerateInfiniteLoop ? bGenerateInfiniteLoop : bInvertLoopPredReg, uPDstLoop, 2);
			SetBlockUnconditional(psState, psCndEfLoopBlock, psCndExeLtBlock);
			SetBlockUnconditional(psState, psCndExeLtBlock, psLoopCfg->psExit);
		}			
	}	
	SetLoopFlow(psState, psLoopCfg);
	{
		PCODEBLOCK psCndStLoopBlock;
		PCODEBLOCK psOldEntry = psLoopCfg->psEntry;
		psCndStLoopBlock = AllocateBlock(psState, psLoopCfg);
		AppendExecPredInst(psState, psCndStLoopBlock, ICNDSTLOOP, USC_PREDREG_NONE, IMG_TRUE /* uCondPredInv */, USC_PREDREG_NONE, 2);
		psLoopCfg->psEntry = psCndStLoopBlock;
		SetBlockUnconditional(psState, psCndStLoopBlock, psOldEntry);
	}
}
Ejemplo n.º 2
0
descriptor_allocation_t DescriptorAllocator::Allocate(u32 num) {
	Check(num < BlockSize);

	auto bucket = find_log_2(num);
	auto m = pad_pow_2(num);

	u32 heapOffset = 0;
	if (Size(FreeRanges[bucket])) {
		heapOffset = Back(FreeRanges[bucket]).heap_offset;
		PopBack(FreeRanges[bucket]);
	}
	else {
		if (SuballocatedBlock[bucket] == NULL_BLOCK) {
			SuballocatedBlock[bucket] = AllocateBlock();
		}

		heapOffset = SuballocatedBlock[bucket] * BlockSize + Blocks[SuballocatedBlock[bucket]].next_allocation_offset;
		Blocks[SuballocatedBlock[bucket]].next_allocation_offset += m;

		if (Blocks[SuballocatedBlock[bucket]].next_allocation_offset == BlockSize) {
			SuballocatedBlock[bucket] = NULL_BLOCK;
		}
	}

	descriptor_allocation_t allocation = {};
	allocation.allocator = this;
	allocation.heap_offset = heapOffset;
	allocation.size = num;

	return allocation;
}
void FD3D12BuddyAllocator::Allocate(uint32 SizeInBytes, uint32 Alignment, FD3D12ResourceLocation& ResourceLocation)
{
	FScopeLock Lock(&CS);

	if (Initialized == false)
	{
		Initialize();
		Initialized = true;
	}

	uint32 SizeToAllocate = SizeInBytes;

	// If the alignment doesn't match the block size
	if (Alignment != 0 && MinBlockSize % Alignment != 0)
	{
		SizeToAllocate = SizeInBytes + Alignment;
	}

	// Work out what size block is needed and allocate one
	const uint32 UnitSize = SizeToUnitSize(SizeToAllocate);
	const uint32 Order = UnitSizeToOrder(UnitSize);
	const uint32 Offset = AllocateBlock(Order); // This is the offset in MinBlockSize units

	const uint32 AllocSize = uint32(OrderToUnitSize(Order) * MinBlockSize);
	const uint32 AllocationBlockOffset = uint32(Offset * MinBlockSize);
	uint32 Padding = 0;

	if (Alignment != 0 && AllocationBlockOffset % Alignment != 0)
	{
		uint32 AlignedBlockOffset = AlignArbitrary(AllocationBlockOffset, Alignment);
		Padding = AlignedBlockOffset - AllocationBlockOffset;

		check((Padding + SizeInBytes) <= AllocSize)
	}
uint32 FD3D12BuddyAllocator::AllocateBlock(uint32 order)
{
	uint32 offset;

	if (order > MaxOrder)
	{
		check(false); // Can't allocate a block that large  
	}

	if (FreeBlocks[order].Num() == 0)
	{
		// No free nodes in the requested pool.  Try to find a higher-order block and split it.  
		uint32 left = AllocateBlock(order + 1);

		uint32 size = OrderToUnitSize(order);

		uint32 right = left + size;

		FreeBlocks[order].Add(right); // Add the right block to the free pool  

		offset = left; // Return the left block  
	}

	else
	{
		TSet<uint32>::TConstIterator it(FreeBlocks[order]);
		offset = *it;

		// Remove the block from the free list
		FreeBlocks[order].Remove(*it);
	}

	return offset;
}
Ejemplo n.º 5
0
const RC openFile(char *fileName,PF_FileHandle *fileHandle)
{
	int fd;
	PF_FileHandle *pfilehandle=fileHandle;
	RC tmp;
	if((fd=_open(fileName,O_RDWR|_O_BINARY))<0)
		return PF_FILEERR;
	pfilehandle->bopen=true;
	pfilehandle->fileName=fileName;
	pfilehandle->fileDesc=fd;
	if((tmp=AllocateBlock(&pfilehandle->pHdrFrame))!=SUCCESS){
		_close(fd);
		return tmp;
	}
	pfilehandle->pHdrFrame->bDirty=false;
	pfilehandle->pHdrFrame->pinCount=1;
	pfilehandle->pHdrFrame->accTime=clock();
	pfilehandle->pHdrFrame->fileDesc=fd;
	pfilehandle->pHdrFrame->fileName=fileName;
	if(_lseek(fd,0,SEEK_SET)==-1){
		DisposeBlock(pfilehandle->pHdrFrame);
		_close(fd);
		return PF_FILEERR;
	}
	if(_read(fd,&(pfilehandle->pHdrFrame->page),sizeof(Page))!=sizeof(Page)){
		DisposeBlock(pfilehandle->pHdrFrame);
		_close(fd);
		return PF_FILEERR;
	}
	pfilehandle->pHdrPage=&(pfilehandle->pHdrFrame->page);
	pfilehandle->pBitmap=pfilehandle->pHdrPage->pData+PF_FILESUBHDR_SIZE;
	pfilehandle->pFileSubHeader=(PF_FileSubHeader *)pfilehandle->pHdrPage->pData;
	fileHandle=pfilehandle;
	return SUCCESS;
}
FIndirectLightingCacheAllocation* FIndirectLightingCache::CreateAllocation(int32 BlockSize, const FBoxSphereBounds& Bounds, bool bPointSample, bool bUnbuiltPreview)
{	
	check(BlockSize > 1 || bPointSample);

	FIndirectLightingCacheAllocation* NewAllocation = new FIndirectLightingCacheAllocation();
	FIndirectLightingCacheBlock NewBlock;

	//@todo - don't allocate point samples from the layout, they don't go through the volume texture
	if (AllocateBlock(BlockSize, NewBlock.MinTexel))
	{
		NewBlock.TexelSize = BlockSize;
		CalculateBlockPositionAndSize(Bounds, BlockSize, NewBlock.Min, NewBlock.Size);

		FVector Scale;
		FVector Add;
		FVector MinUV;
		FVector MaxUV;
		CalculateBlockScaleAndAdd(NewBlock.MinTexel, NewBlock.TexelSize, NewBlock.Min, NewBlock.Size, Scale, Add, MinUV, MaxUV);

		VolumeBlocks.Add(NewBlock.MinTexel, NewBlock);
		NewAllocation->SetParameters(NewBlock.MinTexel, NewBlock.TexelSize, Scale, Add, MinUV, MaxUV, bPointSample, bUnbuiltPreview);
	}

	return NewAllocation;
}
Ejemplo n.º 7
0
globle void *RequestChunk(
  void *theEnv,
  size_t requestSize)
  {
   struct chunkInfo *chunkPtr;
   struct blockInfo *blockPtr;

   /*==================================================*/
   /* Allocate initial memory pool block if it has not */
   /* already been allocated.                          */
   /*==================================================*/

   if (MemoryData(theEnv)->BlockMemoryInitialized == FALSE)
      {
       if (InitializeBlockMemory(theEnv,requestSize) == 0) return(NULL);
      }

   /*====================================================*/
   /* Make sure that the amount of memory requested will */
   /* fall on a boundary of strictest alignment          */
   /*====================================================*/

   requestSize = (((requestSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE;

   /*=====================================================*/
   /* Search through the list of free memory for a block  */
   /* of the appropriate size.  If a block is found, then */
   /* allocate and return a pointer to it.                */
   /*=====================================================*/

   blockPtr = MemoryData(theEnv)->TopMemoryBlock;

   while (blockPtr != NULL)
     {
      chunkPtr = blockPtr->nextFree;

      while (chunkPtr != NULL)
        {
         if ((chunkPtr->size == requestSize) ||
             (chunkPtr->size > (requestSize + MemoryData(theEnv)->ChunkInfoSize)))
           {
            AllocateChunk(theEnv,blockPtr,chunkPtr,requestSize);

            return((void *) (((char *) chunkPtr) + MemoryData(theEnv)->ChunkInfoSize));
           }
         chunkPtr = chunkPtr->nextFree;
        }

      if (blockPtr->nextBlock == NULL)
        {
         if (AllocateBlock(theEnv,blockPtr,requestSize) == 0)  /* get another block */
           { return(NULL); }
        }
      blockPtr = blockPtr->nextBlock;
     }

   SystemError(theEnv,(char*)"MEMORY",2);
   EnvExitRouter(theEnv,EXIT_FAILURE);
   return(NULL); /* Unreachable, but prevents warning. */
  }
uint64 FileBundleWriter::AllocateAppend(size_t write_len) {
  FileBundleWriterSegment *segment;     // segment to write into
  off_t seg_position;                   // position in segment file
  uint64 bundle_position;
  AllocateBlock(write_len, &segment, &seg_position, &bundle_position);

  return bundle_position;
}
Ejemplo n.º 9
0
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    // Gets an object from the pool.
    void* GetObject()	{
        // Acquire the lock. Will be automatically released by the destructor.
        SpinLock lock(&lock_);
        
        if((Count() == 0) || (static_cast<BlockHeader*>(First())->FreeObjects == 0)) {
            // No free block is available, a new one needs to be allocated.
            AllocateBlock();
        }

        return GetObjectFromBlock(static_cast<BlockHeader*>(First()));
    }
Ejemplo n.º 10
0
int mkdir(char * filePath, char * fileName)
{
	unsigned int destinationDirBlockNumber,newDirBlockNumber;
	directoryBlock destinationDirectory,newDirectory;
	int z, y, isfile;
	if (strCmp(filePath, "/") == 1)
		destinationDirBlockNumber = ROOTBLOCK;
	else
		destinationDirBlockNumber = findFileBlockInPath(filePath);
	if (destinationDirBlockNumber == -1)
	{
		printstring("Directory does not exists");
		return -1;
	}
	
	filePath = getData(filePath);
	fileName = getData(fileName);	
	readsector(destinationDirBlockNumber, &destinationDirectory);
	isfile = IsNewFile(destinationDirectory, fileName);
	if (isfile == -1)
	{
		printstring("Directory already exist\n");
		return -1;
	}
	newDirBlockNumber = AllocateBlock();
	y  = 0;
	while(y < DIRECTORYENTRYCOUNT)
	{
		newDirectory.entries[y].fileType = IS_FILE;
		newDirectory.entries[y].fileBlockStart = 0;
		newDirectory.entries[y].fileBlockSize = 0;
		y++;
	}
	writesector(newDirBlockNumber, &newDirectory);
	z = 0;
	while (z < DIRECTORYENTRYCOUNT)
	{
		if (destinationDirectory.entries[z].fileBlockStart == 0)
		{
			strcpy(fileName, destinationDirectory.entries[z].fileName);
			destinationDirectory.entries[z].fileType = IS_DIRECTORY;
			destinationDirectory.entries[z].fileBlockStart = newDirBlockNumber;
			destinationDirectory.entries[z].fileBlockSize = 1;
			break;
		}
		z++;
	}
	writesector(destinationDirBlockNumber, &destinationDirectory);
	printstring("Directory ");
	printstring(fileName);
	printstring(" Created!\n");
	return newDirBlockNumber;
}
Ejemplo n.º 11
0
//allocators for a node
CLTANode* CLTALoadOnlyAlloc::AllocateNode()
{
	//lets first off get the memory for a node
	CLTANode* pNewNode = (CLTANode*)AllocateBlock(sizeof(CLTANode));

	//check the alloc
	if(pNewNode)
	{
		pNewNode->NodeConstructor();
	}

	return pNewNode;
}
uint64 FileBundleWriter::WriteAppend(const void *buffer, size_t write_len) {
  if (SegmentsEmpty()) {               // if bundle closed
    throw khSimpleException
    ("FileBundleWriter::WriteAppend: bundle already closed");
  }

  FileBundleWriterSegment *segment;     // segment to write into
  off_t seg_position;                   // position in segment file
  uint64 bundle_position;
  AllocateBlock(write_len, &segment, &seg_position, &bundle_position);
  WriteToSegment(segment, seg_position, buffer, write_len);
  return bundle_position;
}
Ejemplo n.º 13
0
void mkf(char * path, char* fileName, char acess[], char *data)
{
	int y,isfile;
	directoryBlock destinationDirectory;
	fileBlock file;
	unsigned int newDirBlockNumber, destinationDirBlockNumber;
	
	if (strCmp(getData(path), "/") != 1)
	{
		destinationDirBlockNumber = findFileBlockInPath(getData(path));
	}
	else
	{
		destinationDirBlockNumber = ROOTBLOCK;
	}
	if (destinationDirBlockNumber == -1)
	{
		printstring("Path cannot be found, creating file failed");
		return;
	}
	readsector(destinationDirBlockNumber, (char*)&destinationDirectory);
	isfile = IsNewFile(destinationDirectory, getData(fileName));
	if (isfile == -1)
	{
		printstring("File already exist\n");
		return;
	}
	file.size = 0;
	file.type = IS_FILE;
	file.data[0] = '\0';
	strcpy(getData(fileName), file.fileName);
	strcpy(getData(acess), file.acessRights);
	strcpy(getData(data), file.data);
	newDirBlockNumber = AllocateBlock();
	wf(&file, getData(data), newDirBlockNumber);
	y = 0;
	while( y < DIRECTORYENTRYCOUNT)
	{
		if (destinationDirectory.entries[y].fileBlockStart == 0)
		{
			strcpy(destinationDirectory.entries[y].fileName, file.fileName);
			destinationDirectory.entries[y].fileType = IS_FILE;
			destinationDirectory.entries[y].fileBlockStart = newDirBlockNumber;
			destinationDirectory.entries[y].fileBlockSize = file.size;
			break;
		}
		y++;
	}
	writesector(destinationDirBlockNumber, (char*)&destinationDirectory);
	return;
}
Ejemplo n.º 14
0
static
IMG_VOID RestructureNoneLoopCfgToExecPred(PINTERMEDIATE_STATE psState, PCFG psCfg, IMG_BOOL bMostOuterLevel)
{
	PCTRL_DEP_GRAPH psCtrlDepGraph;
	PCODEBLOCK psNewEntryBlock;
	PCODEBLOCK psNewExitBlock;
	PCODEBLOCK psCfgActualExitBlock;
	if(psCfg->uNumBlocks > 1)
	{
		psNewEntryBlock = AllocateBlock(psState, psCfg);
		psNewExitBlock = AllocateBlock(psState, psCfg);
		psCfg->psExit->eType = CBTYPE_UNCOND;
		if (bMostOuterLevel == IMG_FALSE)
		{
			psCfgActualExitBlock = NULL;		
		}
		else
		{
			psCfgActualExitBlock = psCfg->psExit;
		}
		SetBlockUnconditional(psState, psCfg->psExit, psNewExitBlock);
		SetBlockConditional(psState, psNewEntryBlock, GetNextPredicateRegister(psState), psCfg->psEntry, psNewExitBlock, IMG_FALSE);
		psCfg->psEntry = psNewEntryBlock;
		psNewExitBlock->eType = CBTYPE_EXIT;	
		psCfg->psExit = psNewExitBlock;
		CalcDoms(psState, psCfg);
		psCfg->bBlockStructureChanged = IMG_FALSE;
		//TESTONLY_PRINT_INTERMEDIATE("After changing program structure", "beforeCtrlDep", IMG_FALSE);
		psCtrlDepGraph = CalcCtrlDep(psState, psCfg->psEntry);
		LayoutExecPredCfgFromCtrlDepGraph(psState, psCtrlDepGraph, psCfg, psCfgActualExitBlock);	
		FreeCtrlDepGraph(psState, &psCtrlDepGraph);
		if (bMostOuterLevel == IMG_TRUE)
		{
			//TESTONLY_PRINT_INTERMEDIATE("After changing program structure", "returns", IMG_FALSE);
			OptimizeFunctionEnd(psState, psCfg->psExit);
		}
	}
}
Ejemplo n.º 15
0
const RC AllocatePage(PF_FileHandle *fileHandle,PF_PageHandle *pageHandle)
{
	PF_PageHandle *pPageHandle=pageHandle;
	RC tmp;
	int i,byte,bit;
	fileHandle->pHdrFrame->bDirty=true;
	if((fileHandle->pFileSubHeader->nAllocatedPages)<=(fileHandle->pFileSubHeader->pageCount)){
		for(i=0;i<=fileHandle->pFileSubHeader->pageCount;i++){
			byte=i/8;
			bit=i%8;
			if(((fileHandle->pBitmap[byte])&(1<<bit))==0){
				(fileHandle->pFileSubHeader->nAllocatedPages)++;
				fileHandle->pBitmap[byte]|=(1<<bit);
				break;
			}
		}
		if(i<=fileHandle->pFileSubHeader->pageCount)
			return GetThisPage(fileHandle,i,pageHandle);
		
	}
	fileHandle->pFileSubHeader->nAllocatedPages++;
	fileHandle->pFileSubHeader->pageCount++;
	byte=fileHandle->pFileSubHeader->pageCount/8;
	bit=fileHandle->pFileSubHeader->pageCount%8;
	fileHandle->pBitmap[byte]|=(1<<bit);
	if((tmp=AllocateBlock(&(pPageHandle->pFrame)))!=SUCCESS){
		return tmp;
	}
	pPageHandle->pFrame->bDirty=false;
	pPageHandle->pFrame->fileDesc=fileHandle->fileDesc;
	pPageHandle->pFrame->fileName=fileHandle->fileName;
	pPageHandle->pFrame->pinCount=1;
	pPageHandle->pFrame->accTime=clock();
	memset(&(pPageHandle->pFrame->page),0,sizeof(Page));
	pPageHandle->pFrame->page.pageNum=fileHandle->pFileSubHeader->pageCount;
	if(_lseek(fileHandle->fileDesc,0,SEEK_END)==-1){
		bf_manager.allocated[pPageHandle->pFrame-bf_manager.frame]=false;
		return PF_FILEERR;
	}
	if(_write(fileHandle->fileDesc,&(pPageHandle->pFrame->page),sizeof(Page))!=sizeof(Page)){
		bf_manager.allocated[pPageHandle->pFrame-bf_manager.frame]=false;
		return PF_FILEERR;
	}
	
	return SUCCESS;
}
Ejemplo n.º 16
0
static 
PCODEBLOCK DuplicateCodeBlock(PINTERMEDIATE_STATE psState, PCODEBLOCK psCodeBlock, PCFG psCfg)
{	
	PINST psCurrInst;
	PCODEBLOCK psDuplicateCodeBlock = AllocateBlock(psState, psCfg);
	if (psCodeBlock->uFlags & USC_CODEBLOCK_CFG)
	{
		psDuplicateCodeBlock->u.sUncond.psCfg = DuplicateCfg(psState, psCfg);
		psDuplicateCodeBlock->uFlags |= USC_CODEBLOCK_CFG;
	}
	for (psCurrInst = psCodeBlock->psBody; psCurrInst != NULL; psCurrInst = psCurrInst->psNext)
	{
		PINST psDuplicateInst = CopyInst(psState, psCurrInst);
		AppendInst(psState, psDuplicateCodeBlock, psDuplicateInst);
	}
	CopyRegLiveSet(psState, &psCodeBlock->sRegistersLiveOut, &psDuplicateCodeBlock->sRegistersLiveOut);
	return psDuplicateCodeBlock;
}
Ejemplo n.º 17
0
const RC GetThisPage(PF_FileHandle *fileHandle,PageNum pageNum,PF_PageHandle *pageHandle)
{
	int i,nread,offset;
	RC tmp;
	PF_PageHandle *pPageHandle=pageHandle;
	if(pageNum>fileHandle->pFileSubHeader->pageCount)
		return PF_INVALIDPAGENUM;
	if((fileHandle->pBitmap[pageNum/8]&(1<<(pageNum%8)))==0)
		return PF_INVALIDPAGENUM;
	pPageHandle->bOpen=true;
	for(i=0;i<PF_BUFFER_SIZE;i++){
		if(bf_manager.allocated[i]==false)
			continue;
		if(strcmp(bf_manager.frame[i].fileName,fileHandle->fileName)!=0)
			continue;
		if(bf_manager.frame[i].page.pageNum==pageNum){
			pPageHandle->pFrame=bf_manager.frame+i;
			pPageHandle->pFrame->pinCount++;
			pPageHandle->pFrame->accTime=clock();
			return SUCCESS;
		}
	}
	if((tmp=AllocateBlock(&(pPageHandle->pFrame)))!=SUCCESS){
		return tmp;
	}
	pPageHandle->pFrame->bDirty=false;
	pPageHandle->pFrame->fileDesc=fileHandle->fileDesc;
	pPageHandle->pFrame->fileName=fileHandle->fileName;
	pPageHandle->pFrame->pinCount=1;
	pPageHandle->pFrame->accTime=clock();
	offset=pageNum*sizeof(Page);
	if(_lseek(fileHandle->fileDesc,offset,SEEK_SET)==offset-1){
		bf_manager.allocated[pPageHandle->pFrame-bf_manager.frame]=false;
		return PF_FILEERR;
	}
	if((nread=read(fileHandle->fileDesc,&(pPageHandle->pFrame->page),sizeof(Page)))!=sizeof(Page)){
		bf_manager.allocated[pPageHandle->pFrame-bf_manager.frame]=false;
		return PF_FILEERR;
	}
	return SUCCESS;
}
Ejemplo n.º 18
0
BOOL

StoreLine(
    char *line,
    int lineLen,
    int *offset,
    BYTE *prevLength,
    LPBLOCKDEF * pCurBlock
    )
{
    LPLINEREC pl;

    if ((*offset + (LHD + lineLen)) > BLOCK_SIZE) {

        //We arrived at the end of the block. Allocates a new one.

        if (!AllocateBlock(*pCurBlock, NULL, pCurBlock))
              return FALSE;

        ((*pCurBlock)->PrevBlock)->NextBlock = *pCurBlock;
        *offset = 0;
        if ((*pCurBlock)->PrevBlock == NULL)
              *prevLength = 0;
    }
    (*pCurBlock)->LastLineOffset = *offset;
    pl = (LPLINEREC)((*pCurBlock)->Data + *offset);
    AssertAligned(pl);

    pl->PrevLength = *prevLength;
    pl->Length = (BYTE)(LHD + lineLen);
    pl->Status = 0;
    memmove((LPSTR)(pl->Text), (LPSTR)line, lineLen);

    *prevLength = (BYTE)(LHD + lineLen);
    *offset += LHD + lineLen;
#ifdef ALIGN
    *offset = (*offset + 3) & ~3;
#endif
    return TRUE;
}                                       /* StoreLine() */
Ejemplo n.º 19
0
static void* OperatorNew( size_t s )
{
    if ( !using_alloc_set )
    {
        simulate_possible_failure();
        alloc_count++;
    }

    char *p = AllocateBlock(s);

    if ( gTestController.TrackingEnabled()
            && gTestController.LeakDetectionEnabled()
            && !using_alloc_set )
    {
        using_alloc_set = true;
        EH_ASSERT( alloc_set().find( p ) == alloc_set().end() );
        alloc_set().insert( p );
        using_alloc_set = false;
    }

    return p;
}
FIndirectLightingCacheAllocation* FIndirectLightingCache::CreateAllocation(int32 BlockSize, const FBoxSphereBounds& Bounds, bool bOpaqueRelevance)
{
	FIndirectLightingCacheAllocation* NewAllocation = new FIndirectLightingCacheAllocation();
	FIndirectLightingCacheBlock NewBlock;

	if (AllocateBlock(BlockSize, NewBlock.MinTexel))
	{
		NewBlock.TexelSize = BlockSize;
		CalculateBlockPositionAndSize(Bounds, BlockSize, NewBlock.Min, NewBlock.Size);

		FVector Scale;
		FVector Add;
		FVector MinUV;
		FVector MaxUV;
		CalculateBlockScaleAndAdd(NewBlock.MinTexel, NewBlock.TexelSize, NewBlock.Min, NewBlock.Size, Scale, Add, MinUV, MaxUV);

		VolumeBlocks.Add(NewBlock.MinTexel, NewBlock);
		NewAllocation->SetParameters(NewBlock.MinTexel, NewBlock.TexelSize, Scale, Add, MinUV, MaxUV, bOpaqueRelevance);
	}

	return NewAllocation;
}
 StormFixedBlockHandle StormFixedBlockAllocator::AllocateBlock(StormFixedBlockHandle chain_head, StormFixedBlockType::Index type)
 {
   StormFixedBlockHandle new_block = AllocateBlock(type);
   SetNextBlock(chain_head, new_block);
   return new_block;
 }
Ejemplo n.º 22
0
void CachedInterpreter::Jit(u32 address)
{
	if (m_code.size() >= CODE_SIZE / sizeof(Instruction) - 0x1000 || IsFull() || SConfig::GetInstance().bJITNoBlockCache)
	{
		ClearCache();
	}

	u32 nextPC = analyzer.Analyze(PC, &code_block, &code_buffer, code_buffer.GetSize());
	if (code_block.m_memory_exception)
	{
		// Address of instruction could not be translated
		NPC = nextPC;
		PowerPC::ppcState.Exceptions |= EXCEPTION_ISI;
		PowerPC::CheckExceptions();
		WARN_LOG(POWERPC, "ISI exception at 0x%08x", nextPC);
		return;
	}

	int block_num = AllocateBlock(PC);
	JitBlock *b = GetBlock(block_num);

	js.blockStart = PC;
	js.firstFPInstructionFound = false;
	js.fifoBytesThisBlock = 0;
	js.downcountAmount = 0;
	js.curBlock = b;

	PPCAnalyst::CodeOp *ops = code_buffer.codebuffer;

	b->checkedEntry = GetCodePtr();
	b->normalEntry = GetCodePtr();
	b->runCount = 0;

	for (u32 i = 0; i < code_block.m_num_instructions; i++)
	{
		js.downcountAmount += ops[i].opinfo->numCycles;

		u32 function = HLE::GetFunctionIndex(ops[i].address);
		if (function != 0)
		{
			int type = HLE::GetFunctionTypeByIndex(function);
			if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE)
			{
				int flags = HLE::GetFunctionFlagsByIndex(function);
				if (HLE::IsEnabled(flags))
				{
					m_code.emplace_back(WritePC, ops[i].address);
					m_code.emplace_back(Interpreter::HLEFunction, ops[i].inst);
					if (type == HLE::HLE_HOOK_REPLACE)
					{
						m_code.emplace_back(EndBlock, js.downcountAmount);
						m_code.emplace_back();
						break;
					}
				}
			}
		}

		if (!ops[i].skip)
		{
			if ((ops[i].opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
			{
				m_code.emplace_back(CheckFPU, ops[i].address);
				js.firstFPInstructionFound = true;
			}

			if (ops[i].opinfo->flags & FL_ENDBLOCK)
				m_code.emplace_back(WritePC, ops[i].address);
			m_code.emplace_back(GetInterpreterOp(ops[i].inst), ops[i].inst);
			if (ops[i].opinfo->flags & FL_ENDBLOCK)
				m_code.emplace_back(EndBlock, js.downcountAmount);
		}
	}
	if (code_block.m_broken)
	{
		m_code.emplace_back(WritePC, nextPC);
		m_code.emplace_back(EndBlock, js.downcountAmount);
	}
	m_code.emplace_back();

	b->codeSize = (u32)(GetCodePtr() - b->checkedEntry);
	b->originalSize = code_block.m_num_instructions;

	FinalizeBlock(block_num, jo.enableBlocklink, b->checkedEntry);
}
Ejemplo n.º 23
0
	virtual void Run()
	{
		SetName("ZLibCompressor");

#if defined (DURANGO)
		SetThreadAffinityMask(GetCurrentThread(), BIT(3));
#endif

		while(!m_bCancelled || !m_files.empty())
		{
			m_event.Wait();

			uint8* pZLibCompressedBuffer = AllocateBlock();

			while(!m_files.empty())
			{
				CFile* pFile = m_files.pop();
				assert(pFile);
				PREFAST_ASSUME(pFile);

				while(!pFile->Closed() || !pFile->m_blocks.empty())
				{
					if( pFile->m_blocks.empty() )
					{ 
						CrySleep(1); // yield to give other threads a chance to do some work        
					}

					while(!pFile->m_blocks.empty())
					{
						SZLibBlock* block = pFile->m_blocks.pop();
						assert(block);
						PREFAST_ASSUME(block);

						if(pFile->m_pCompressor->m_bUseZLibCompression)
						{
							size_t compressedLength = XMLCPB_ZLIB_BUFFER_SIZE;
							bool compressionOk = gEnv->pSystem->CompressDataBlock( block->m_pZLibBuffer, block->m_ZLibBufferSizeUsed, pZLibCompressedBuffer, compressedLength );

							SZLibBlockHeader zlibHeader;
							zlibHeader.m_compressedSize = compressionOk ? compressedLength : SZLibBlockHeader::NO_ZLIB_USED;
							zlibHeader.m_uncompressedSize = block->m_ZLibBufferSizeUsed;
							pFile->m_bytesWrittenIntoFileUncompressed += block->m_ZLibBufferSizeUsed;

							pFile->Write( &zlibHeader, sizeof(SZLibBlockHeader) );
							if (compressionOk)
								pFile->Write( pZLibCompressedBuffer, compressedLength );
							else
								pFile->Write( block->m_pZLibBuffer, block->m_ZLibBufferSizeUsed );
						}
						else
						{
							pFile->Write(block->m_pZLibBuffer, block->m_ZLibBufferSizeUsed);
						}

						delete block;
					}
				}

				pFile->Finish();
				delete pFile;
			}

			FreeBlock(pZLibCompressedBuffer);
		}
	}
Ejemplo n.º 24
0
Archivo: Disco.c Proyecto: Liz30/SisOs
void AllocateBlocks(int n){
  int i=0;
  for (i; i<n; i+=1)
    AllocateBlock();
  getch();
}
Ejemplo n.º 25
0
// ResizeBlock
Block *
BlockAllocator::Area::ResizeBlock(Block *block, size_t newUsableSize,
								  bool dontDefragment)
{
//PRINT(("Area::ResizeBlock(%p, %lu)\n", block, newUsableSize));
// newUsableSize must be >0 !
	if (newUsableSize == 0)
		return NULL;
	Block *resultBlock = NULL;
	if (block) {
		size_t size = block->GetSize();
		size_t newSize = max(newUsableSize + sizeof(BlockHeader),
							 kMinBlockSize);
		newSize = block_align_ceil(newSize);
		if (newSize == size) {
			// size doesn't change: nothing to do
			resultBlock = block;
		} else if (newSize < size) {
			// shrink the block
			size_t sizeDiff = size - newSize;
			Block *nextBlock = block->GetNextBlock();
			if (nextBlock && nextBlock->IsFree()) {
				// join the space with the adjoining free block
				TFreeBlock *freeBlock = nextBlock->ToFreeBlock();
				_MoveResizeFreeBlock(freeBlock, -sizeDiff,
									 freeBlock->GetSize() + sizeDiff);
				// resize the block and we're done
				block->SetSize(newSize, true);
				fFreeBytes += sizeDiff;
			} else if (sizeDiff >= sizeof(TFreeBlock)) {
				// the freed space is large enough for a free block
				TFreeBlock *newFree = _MakeFreeBlock(block, newSize, block,
					sizeDiff, nextBlock, NULL, NULL);
				_InsertFreeBlock(newFree);
				block->SetSize(newSize, true);
				if (fFreeBlockCount == 1)
					fFreeBytes += newFree->GetUsableSize();
				else
					fFreeBytes += newFree->GetSize();
				if (!dontDefragment && _DefragmentingRecommended())
					_Defragment();
			}	// else: insufficient space for a free block: no changes
			resultBlock = block;
		} else {
//PRINT(("  grow...\n"));
			// grow the block
			size_t sizeDiff = newSize - size;
			Block *nextBlock = block->GetNextBlock();
			if (nextBlock && nextBlock->IsFree()
				&& nextBlock->GetSize() >= sizeDiff) {
//PRINT(("  adjoining free block\n"));
				// there is a adjoining free block and it is large enough
				TFreeBlock *freeBlock = nextBlock->ToFreeBlock();
				size_t freeSize = freeBlock->GetSize();
				if (freeSize - sizeDiff >= sizeof(TFreeBlock)) {
					// the remaining space is still large enough for a free
					// block
					_MoveResizeFreeBlock(freeBlock, sizeDiff,
										 freeSize - sizeDiff);
					block->SetSize(newSize, true);
					fFreeBytes -= sizeDiff;
				} else {
					// the remaining free space wouldn't be large enough for
					// a free block: consume the free block completely
					Block *freeNext = freeBlock->GetNextBlock();
					_RemoveFreeBlock(freeBlock);
					block->SetSize(size + freeSize, freeNext);
					_FixBlockList(block, block->GetPreviousBlock(), freeNext);
					if (fFreeBlockCount == 0)
						fFreeBytes = 0;
					else
						fFreeBytes -= freeSize;
				}
				resultBlock = block;
			} else {
//PRINT(("  no adjoining free block\n"));
				// no (large enough) adjoining free block: allocate
				// a new block and copy the data to it
				BlockReference *reference = block->GetReference();
				resultBlock = AllocateBlock(newUsableSize, dontDefragment);
				block = reference->GetBlock();
				if (resultBlock) {
					resultBlock->SetReference(reference);
					memcpy(resultBlock->GetData(), block->GetData(),
						   block->GetUsableSize());
					FreeBlock(block, dontDefragment);
					resultBlock = reference->GetBlock();
				}
			}
		}
	}
	D(SanityCheck());
//PRINT(("Area::ResizeBlock() done: %p\n", resultBlock));
	return resultBlock;
}
Ejemplo n.º 26
0
BOOL FAR  MergeFile(LPSTR FileName, int view)
{
    HCURSOR hSaveCursor;
    char line[MAX_USER_LINE + 1];
    int offset; //Current offset of storage in block
    int lineLen; // length of line
    BYTE prevLength; //Previous line size
    LPVIEWREC v = &Views[view];
    WORD res;
    LPDOCREC d =&Docs[v->Doc];
    LPLINEREC pCurLine, pLastLine;
    LPBLOCKDEF pCurBlock, pNewBlock;
    long y;

    Assert( v->Doc >= 0);


    if ((hFileDoc = _lopen(FileName, OF_READ)) == HFILE_ERROR)
          return ErrorBox(ERR_File_Open, (LPSTR)FileName);

    if ((pszBufferDoc = DocAlloc(DISK_BLOCK_SIZE)) == NULL) {
        ErrorBox(SYS_Allocate_Memory);
        goto error1;
    }

    dwBytesReadDoc = DISK_BLOCK_SIZE;
    dwOffsetDoc = DISK_BLOCK_SIZE;
    lineLen = 0;

    //Delete selected text if any
    if (v->BlockStatus) {

        long XR, YR;

        GetBlockCoord (view, &(v->X), &(v->Y), &XR, &YR);
        DeleteStream(view, v->X, v->Y, XR, YR, FALSE);
    }

    //Set the Hour glass cursor
          hSaveCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));

    //Insert first line

    res = LoadLine(line, &lineLen, d->NbLines);
    if (res == END_OF_FILE || res == END_OF_LINE) {

        //Add a CR+LF
        if (res == END_OF_LINE) {
            line[lineLen] = CR;
            line[lineLen + 1] = LF;
            lineLen += 2;
        }
        if (!InsertBlock(v->Doc, v->X, v->Y, (WORD) lineLen, line))
            goto error2;
    }
    else {

        if (res == ERR_File_Read || res == ERR_Not_A_Text_File)
              ErrorBox(res, (LPSTR)FileName);
        goto error2;
    }

    if (res != END_OF_FILE) {

        //Get current line status (we just inserted it)

        y = v->Y;
        if (!FirstLine(v->Doc, &pCurLine, &y, &pCurBlock))
              return FALSE;

        //Get next line (just after the line we just inserted)

        if (!NextLine(v->Doc, &pCurLine, &y, &pCurBlock))
              return FALSE;

        //Set offset to StoreLine start
              offset =  (LPSTR)pCurLine - (LPSTR)pCurBlock->Data;
        prevLength = pCurLine->PrevLength;

        //Split block in 2 blocks by first allocating a new block and then
        //copying right side of block in new block

        if (!AllocateBlock(pCurBlock, pCurBlock->NextBlock, &pNewBlock))
              return FALSE;

        pLastLine = (LPLINEREC)(pCurBlock->Data + pCurBlock->LastLineOffset);
        memmove(pNewBlock->Data, (LPSTR)pCurLine,
              (LPSTR)pLastLine - (LPSTR)pCurLine + pLastLine->Length);

        //Set new old block len and new new block len
              pCurBlock->LastLineOffset = (LPSTR)pCurLine - (LPSTR)pCurBlock->Data - pCurLine->PrevLength;
        pNewBlock->LastLineOffset = (LPSTR)pLastLine - (LPSTR)pCurLine;

        //Backward links next block with new one
        if (pCurBlock->NextBlock == NULL)
              d->LastBlock = pNewBlock;
        else
              (pCurBlock->NextBlock)->PrevBlock = pNewBlock;

        //Forward link current block with new block

        pCurBlock->NextBlock = pNewBlock;

        CloseLine(v->Doc, &pCurLine, y, &pCurBlock);

        //Read and store all lines in new blocks

        res = LoadLine(line, &lineLen, d->NbLines);
        while (res == END_OF_LINE) {

            //Truncate a file too large

            if (d->NbLines >= MAX_LINE_NUMBER - 1) {
                ErrorBox(ERR_Truncate_Doc);
                res = END_OF_FILE;
                break;
            }

            if (!StoreLine(line, lineLen, &offset, &prevLength, &pCurBlock)) {
                res = END_ABORT;
                break;
            }

            res = LoadLine(line, &lineLen, ++d->NbLines);
        }

        //Take decisions
        switch (res) {

          case END_OF_FILE:

            //Store last line
            if (StoreLine(line, lineLen, &offset, &prevLength, &pCurBlock)) {

                d->NbLines++;

                //Forward link of last allocated block with new block

                pCurBlock->NextBlock = pNewBlock;

                //Backward link of new block with last allocated block

                pNewBlock->PrevBlock = pCurBlock;
                ((LPLINEREC)(pNewBlock->Data))->PrevLength = (BYTE)(lineLen + LHD);

                //Free memory

                if (!DocFree(pszBufferDoc))
                      InternalErrorBox(SYS_Free_Memory);

                //Restore cursor

                SetCursor(hSaveCursor);

                //Check syntax if C

                if (d->language == C_LANGUAGE) {
                    d->lineTop = 0;
                    d->lineBottom = d->NbLines;
                    CheckSyntax(v->Doc);
                }
                SetVerticalScrollBar(view, TRUE);

                PosXY(view, v->X, v->Y, FALSE);
                InvalidateRect(v->hwndClient, (LPRECT)NULL, FALSE);

                CloseHandle (hFileDoc);
                return TRUE;
            }
            else
                goto abort;

          case ERR_File_Read:
          case ERR_Not_A_Text_File:
            ErrorBox(res, (LPSTR)FileName);
            //Fall through

          case END_ABORT:
            {

              abort:
                SetCursor(hSaveCursor);
                break;
            }

          default:
            Assert(FALSE);
            break;
        }

    } else
          InvalidateRect(v->hwndClient, (LPRECT)NULL, FALSE);

  error2: {
        SetCursor (hSaveCursor);
        if (!DocFree(pszBufferDoc))
              InternalErrorBox(SYS_Free_Memory);
    }

  error1: {
        CloseHandle (hFileDoc);
    }

    return FALSE;
}                                       /* MergeFile() */
Ejemplo n.º 27
0
BOOL

LoadFile(
    int doc
    )
{
    LPDOCREC d =&Docs[doc];
    char line[MAX_USER_LINE + 1];
    int offset; //Current offset of storage in block
    int lineLen;
    BYTE prevLength; //Previous line size
    HCURSOR hSaveCursor;
    WORD res;
    WORD nbLines = 0;

    //
    // Documents are now always read only. Because WinDbg is no longer and IDE, it
    // is strictly a debugger now.
    //

    hFileDoc = CreateFile(d->szFileName, GENERIC_READ, FILE_SHARE_READ, 
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (INVALID_HANDLE_VALUE == hFileDoc) {
        ErrorBox( ERR_File_Open, (LPSTR)d->szFileName );
        return FALSE;
    }

    d->readOnly = TRUE;

    //Store file date

    if (!GetFileTimeByName( d->szFileName, NULL, NULL, &d->time ) ) {
        GetSystemTimeAsFileTime(&d->time);
    }

    if ((pszBufferDoc = DocAlloc(DISK_BLOCK_SIZE)) == NULL) {
        ErrorBox(SYS_Allocate_Memory);
        goto error1;
    }

    //Alloc first block

    if (!AllocateBlock(NULL, NULL, &d->FirstBlock)) {
        return FALSE;
    }

    //If we are in reload mode, and a message box shows up, a repaint
    //of the document being loaded is done, so force number of lines
    //to a value != 0

    d->NbLines = MAX_LINE_NUMBER;

    d->LastBlock = d->FirstBlock;
    dwBytesReadDoc = DISK_BLOCK_SIZE;
    dwOffsetDoc = DISK_BLOCK_SIZE;
    offset = 0;
    prevLength = 0;

    //Set the Hour glass cursor

    hSaveCursor = SetCursor (LoadCursor(NULL, IDC_WAIT));

    //Read file line after line

    res = LoadLine(line, &lineLen, nbLines);
    while (res == END_OF_LINE) {

        //Truncate a file too large

        if (nbLines >= MAX_LINE_NUMBER - 1) {
            ErrorBox(ERR_Truncate_Doc);
            res = END_OF_FILE;
            break;
        }

        if (!StoreLine(line, lineLen, &offset, &prevLength, &d->LastBlock)) {
            res = END_ABORT;
            break;
        }

        res = LoadLine(line, &lineLen, ++nbLines);
    }

    //Take decisions

    switch (res) {

      case END_OF_FILE:

        //Store last line

        if (StoreLine(line, lineLen, &offset, &prevLength, &d->LastBlock)) {

            nbLines++;

            //Free memory

            if (!DocFree(pszBufferDoc))
                  InternalErrorBox(SYS_Free_Memory);

            //Restore cursor

            SetCursor(hSaveCursor);

            CloseHandle(hFileDoc);
            d->NbLines = nbLines;
            return TRUE;
        } else
              goto abort;

      case ERR_File_Read:
      case ERR_Not_A_Text_File:
        ErrorBox(res, (LPSTR)d->szFileName);
        //Fall through

      case END_ABORT:
        {
            LPBLOCKDEF pB;

          abort:
            while (TRUE) {

                pB = (d->LastBlock)->PrevBlock;
                if (!DocFree((LPSTR)d->LastBlock))
                      InternalErrorBox(SYS_Free_Memory);
                d->LastBlock = pB;
                if (pB == NULL)
                      break;
            }
            SetCursor(hSaveCursor);
            break;
        }

      default:
        Assert(FALSE);
        break;
    }

    //Restore cursor

    SetCursor(hSaveCursor);

    if (!DocFree(pszBufferDoc))
          InternalErrorBox(SYS_Free_Memory);

  error1: {
        CloseHandle(hFileDoc);
    }

    return FALSE;
}                                       /* LoadFile() */
Ejemplo n.º 28
0
void csMeshGenerator::UpdateForPosition (const csVector3& pos)
{
  csVector3 delta = pos - last_pos;

  last_pos = pos;
  SetupSampleBox ();

  for (size_t i = 0 ; i < geometries.GetSize () ; i++) 
  { 
    geometries[i]->UpdatePosition (pos); 
  } 

  int cellx = GetCellX (pos.x);
  int cellz = GetCellZ (pos.z);

  // Total maximum distance for all geometries.
  float md = GetTotalMaxDist ();
  float sqmd = md * md;
  // Same in cell counts:
  int cell_x_md = 1+int (md * samplefact_x);
  int cell_z_md = 1+int (md * samplefact_z);

  // @@@ This can be done more efficiently.
  csVector2 pos2d (pos.x, pos.z);
  int x, z;

  int minz = cellz - cell_z_md;
  if (minz < 0) minz = 0;
  int maxz = cellz + cell_z_md+1;
  if (maxz > cell_dim) maxz = cell_dim;

  int minx = cellx - cell_x_md;
  if (minx < 0) minx = 0;
  int maxx = cellx + cell_x_md+1;
  if (maxx > cell_dim) maxx = cell_dim;

  // Calculate the intersection of minx, ... with prev_minx, ...
  // This intersection represent all cells that are not used this frame
  // but may potentially have gotten meshes the previous frame. We need
  // to free those meshes.
  csRect cur_cells (minx, minz, maxx, maxz);
  if (!prev_cells.IsEmpty ())
  {
    for (z = prev_cells.ymin ; z < prev_cells.ymax ; z++)
      for (x = prev_cells.xmin ; x < prev_cells.xmax ; x++)
        if (!cur_cells.Contains (x, z))
        {
          int cidx = z*cell_dim + x;
          csMGCell& cell = cells[cidx];
          FreeMeshesInBlock (cidx, cell);
        }
  }
  prev_cells = cur_cells;

  int total_needed = 0;

  // Now allocate the cells that are close enough.
  for (z = minz ; z < maxz ; z++)
  {
    int cidx = z*cell_dim + minx;
    for (x = minx ; x < maxx ; x++)
    {
      csMGCell& cell = cells[cidx];
      float sqdist = cell.box.SquaredPosDist (pos2d);

      if (sqdist < sqmd)
      {
        total_needed++;
        if (total_needed >= max_blocks)
        {
          engine->Error (
            "The mesh generator needs more blocks than %d!", max_blocks);
          return;	// @@@ What to do here???
        }
        AllocateBlock (cidx, cell);
        AllocateMeshes (cidx, cell, pos, delta);
      }
      else
      {
        // Block is out of range. We keep the block in the cache
        // but free all meshes that are in it.
        FreeMeshesInBlock (cidx, cell);
      }
      cidx++;
    }
  }

  // Housekeeping
  size_t i;
  for (i = 0 ; i < geometries.GetSize () ; i++)
  {
    geometries[i]->FinishUpdate ();
  }
}
Ejemplo n.º 29
0
size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data, FileLoader::Flags flags) {
	lock_guard guard(lock_);

	if (!f_) {
		// Just to keep things working.
		return backend->ReadAt(pos, bytes, data, flags);
	}

	s64 cacheStartPos = pos / blockSize_;
	s64 cacheEndPos = (pos + bytes - 1) / blockSize_;
	size_t readSize = 0;
	size_t offset = (size_t)(pos - (cacheStartPos * (u64)blockSize_));
	u8 *p = (u8 *)data;

	size_t blocksToRead = 0;
	for (s64 i = cacheStartPos; i <= cacheEndPos; ++i) {
		auto &info = index_[i];
		if (info.block != INVALID_BLOCK) {
			break;
		}
		++blocksToRead;
		if (blocksToRead >= MAX_BLOCKS_PER_READ) {
			break;
		}
	}

	if (!MakeCacheSpaceFor(blocksToRead) || blocksToRead == 0) {
		return 0;
	}

	if (blocksToRead == 1) {
		auto &info = index_[cacheStartPos];

		u8 *buf = new u8[blockSize_];
		size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blockSize_, buf, flags);

		// Check if it was written while we were busy.  Might happen if we thread.
		if (info.block == INVALID_BLOCK && readBytes != 0) {
			info.block = AllocateBlock((u32)cacheStartPos);
			WriteBlockData(info, buf);
			WriteIndexData((u32)cacheStartPos, info);
		}

		size_t toRead = std::min(bytes - readSize, (size_t)blockSize_ - offset);
		memcpy(p + readSize, buf + offset, toRead);
		readSize += toRead;

		delete [] buf;
	} else {
		u8 *wholeRead = new u8[blocksToRead * blockSize_];
		size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blocksToRead * blockSize_, wholeRead, flags);

		for (size_t i = 0; i < blocksToRead; ++i) {
			auto &info = index_[cacheStartPos + i];
			// Check if it was written while we were busy.  Might happen if we thread.
			if (info.block == INVALID_BLOCK && readBytes != 0) {
				info.block = AllocateBlock((u32)cacheStartPos + (u32)i);
				WriteBlockData(info, wholeRead + (i * blockSize_));
				// TODO: Doing each index together would probably be better.
				WriteIndexData((u32)cacheStartPos + (u32)i, info);
			}

			size_t toRead = std::min(bytes - readSize, (size_t)blockSize_ - offset);
			memcpy(p + readSize, wholeRead + (i * blockSize_) + offset, toRead);
			readSize += toRead;
		}
		delete[] wholeRead;
	}

	cacheSize_ += blocksToRead;
	++generation_;

	if (generation_ == std::numeric_limits<u16>::max()) {
		RebalanceGenerations();
	}

	return readSize;
}
Ejemplo n.º 30
0
descriptor_allocation_t DescriptorAllocator::AllocateTemporary(u32 num) {
	if (!Size(TemporaryBlocks)) {
		ScopeLock lock(&TemporaryBlocksCS);
		if (!Size(TemporaryBlocks)) {
			PushBack(TemporaryBlocks, AllocateBlock());
			CurrentTemporaryBlockIndex = 0;
		}
	}

	descriptor_allocation_t allocation = {};
	allocation.allocator = this;
	allocation.size = num;

	u16 currentTmpBlockIndex;
	u16 blockToTry;
	u32 blockNextAllocation;
	//{
	//	ScopeLock lock(&TemporaryBlocksCS);
	//	currentTmpBlockIndex = CurrentTemporaryBlockIndex.load();
	//	blockToTry = TemporaryBlocks[currentTmpBlockIndex];
	//	blockNextAllocation = Blocks[blockToTry].next_allocation_offset.load();
	//}

	currentTmpBlockIndex = CurrentTemporaryBlockIndex.load();
	blockToTry = TemporaryBlocks[currentTmpBlockIndex];
	blockNextAllocation = Blocks[blockToTry].next_allocation_offset.load();

	while (true) {
		if (blockNextAllocation + num <= BlockSize) {
			auto expected = blockNextAllocation;
			if (Blocks[blockToTry].next_allocation_offset.compare_exchange_strong(expected, blockNextAllocation + num)) {
				allocation.heap_offset = blockToTry * BlockSize + blockNextAllocation;
				break;
			}
			blockNextAllocation = expected;
		}
		else {
			Check(currentTmpBlockIndex <= Size(TemporaryBlocks));
			if (currentTmpBlockIndex + 1 == Size(TemporaryBlocks)) {
				while (CurrentTemporaryBlockIndex + 1 == Size(TemporaryBlocks)) {
					if (TemporaryBlocksCS.TryLock()) {
						PushBack(TemporaryBlocks, AllocateBlock());
						TemporaryBlocksCS.Unlock();
					}
					else {
						_mm_pause();
					}
				}
			}

			auto expected = currentTmpBlockIndex;
			if (CurrentTemporaryBlockIndex.compare_exchange_strong(expected, currentTmpBlockIndex + 1)) {
				currentTmpBlockIndex = currentTmpBlockIndex + 1;
			}
			else {
				currentTmpBlockIndex = expected;
			}
			Check(currentTmpBlockIndex < Size(TemporaryBlocks));

			blockToTry = TemporaryBlocks[currentTmpBlockIndex];
			blockNextAllocation = Blocks[blockToTry].next_allocation_offset.load();
		}
	}

	return allocation;
}