Code Search for Developers
 
 
  

FBlockManager.C from Magnus at Krugle


Show FBlockManager.C syntax highlighted

/*******************

Written by Frank Rimlinger, August 1992
Revised by Frank Rimlinger, January 1993

*******************/
#include "crossTrainer.h"
#include "FGLink.h"
#include "FBlockManager.h"
#include "GLfunctions.h"
#ifdef Frank_MemoryDebugging
#include "debugMemory.h"
#endif
#define MASTERBLOCK 64
#define MINBLOCKS 10


FBlockManager::FBlockManager(FGLink* aGLink){ /*moves memory*/
// The BlockManager is allocated by FGLink::FGLink.

// DO NOT attempt to allocate master pointer blocks here.
// This will be disasterous if lots of different blockmanagers
// are allocated during the lifetime of the program.
// A word to the wise is sufficient.

	itsGLink=aGLink;
	long contig,listsize,grow;
	GLref addr;	
	FList *lock;
	if(itsGLink->MaxPacketSize<=0){
		xErr(9);
	}
	contig=MaxMem(&grow);
	SetListSize();
	SetBlockSize(ListSize);  // this is the blocksize for the list maintained
							 // by the BlockManager object, NOT the size of a
							 // block holding GLvar data
	if(ListSize<=0) Failure(memFullErr,0);						 
	BlockSize=contig/ListSize;  // this is the size of a block holding GLvar data
	TopSize=BlockSize;
	TotalAllocation=0;
	lock=new FList;
	this->lock=lock;
	lock->SetBlockSize(ListSize);
	NewBlock(addr);      
				//WARNING: Do not pass an FObject derived data member
				//by reference as memory may move.
	NextFreeAddress=addr;
	if(isNull(NextFreeAddress)){
		xErr(11);
	}

}

FBlockManager::~FBlockManager(void){
// The BlockManager is created and destroyed by itsGLink.
#ifdef Frank_MemoryDebugging
/* COMMENTED OUT
	extern Boolean toggleSkip;
	if(toggleSkip) memout <= "\n";
	toggleSkip=FALSE;
	for(long j=0;j<numItems;++j) memout <= "<";
END COMMENTED OUT */
#endif

	delete lock;lock=0;
	for(long i=1;i<=numItems;++i){
		Handle h=(Handle)NthItem(i);
		forgetHan(h);
	}
}

void FBlockManager::LockBlock(const GLref& ref){
	//locks the block containing ref
	
	long count=(long)lock->NthItem(ref.index);
// DEBUG
	if(count>20 || count<0){
		memout<="FBlockManager:: lockBlock:: bad lock depth: " <= count<="\n";
/* COMMENTED OUT
		ExitToShell();
END COMMENTED OUT*/
	}
// END DEBUG
	if(count==0){
		Handle handle=(Handle)NthItem(ref.index);
		if(handle==ZERO){
			memout<= "bad address is "<=ref <= "\n";
			xErr(22);
		}
		HLock((Handle)handle);
	}
	++count;
	lock->SetItem(&count,ref.index);
}

void FBlockManager::RestoreBlock(const GLref& ref){
	//unlocks the block containing ref
	long count=(long)lock->NthItem(ref.index);
// DEBUG
	if(count>20 || count<1){
		memout<="FBlockManager:: restoreBlock:: bad lock depth: " <= count<="\n";
/* COMMENTED OUT
		ExitToShell();
END COMMENTED OUT */
	}
// END DEUBG
	--count;
	lock->SetItem(&count,ref.index);
	if(count==0){
		Handle handle=(Handle)NthItem(ref.index);
		if(handle==ZERO){
			xErr(23);
		}
		HUnlock((Handle)handle);
	}
	else if(count<0){
		xErr(64);
	}
}





void FBlockManager::ReserveSpace(GLref& address,long PacketSize){ /*moves memory*/
	Boolean keepTrying=TRUE;
	
// tricky: notice that an attempt to top off a block may fail on the Mac
// if the block is locked, even if there is lots of free memory.
// So we must be prepared for topping off to fail, and if it does,
// we try allocating a new block.

// Since we are doing are own error recovery locally, we bypass
// GLresize and directly call SetHandleSize  (Mac only)

	if(PacketSize+NextFreeAddress.offset>=BlockSize){
		if(!ToppedOff){
			Handle han;
			long newSize;
			newSize=NextFreeAddress.offset+PacketSize;
			han=(Handle)LastItem();
#ifdef Frank_GenuineMac
			SetHandleSize(han,newSize); 
#ifdef Frank_MemoryDebugging
			repSetHandleSize(memout,han);
#endif

#else

// tricky: if the handle is not locked,the VALUE of the handle changes,
// (as opposed to the data it points too).  The implication
// is that the old handle must be removed from the 
// BlockManager list and the new handle entered therein

// CAUTION: Any other outstanding copies of the handle are now
// invalid, so be sure to use the locking mechanism properly.

			han=SetHandleSizePatch(han,newSize);
			if(han){
				SetItem((Ptr)&han,numItems);
			}
#endif

			if(!MemError()){

				keepTrying=FALSE;
				TotalAllocation=TotalAllocation+newSize-BlockSize;
				if(newSize>TopSize){
					TopSize=newSize;
				}
				ToppedOff=TRUE;
			}
		}
		if(keepTrying){	
			GLref addr;
			NewBlock(addr);
			NextFreeAddress=addr;      
			if(NextFreeAddress.offset!=0){
				xErr(13);
			}
			if(isNull(NextFreeAddress)==TRUE){
				xErr(2);
			}
		}
	}
	address=NextFreeAddress;
	NextFreeAddress.offset=NextFreeAddress.offset+PacketSize;
}




void FBlockManager::SetListSize(void){  /*moves memory*/ 
	/*tricky: ListSize is short, but computation requires long*/
	long listsize,grow;
	listsize=MaxMem(&grow)/itsGLink->MaxPacketSize;
	if(listsize>FGLink::MaxBlocks){
		listsize=FGLink::MaxBlocks;
	}
	ListSize=(short)listsize;
}
void FBlockManager::LargerPacketSize(long PacketSize){  /*moves memory*/ 
	long newBlocks,contig,newBlockSize,grow;
	contig=MaxMem(&grow);
	SetListSize();
	if(ListSize<=0)Failure(memFullErr,0);
	newBlockSize=contig/ListSize;
	if(newBlockSize>BlockSize){
		/*reset BlockSize and grow the current block*/
		Handle han;
		BlockSize=newBlockSize;
		if(TopSize<BlockSize){
			TopSize=BlockSize;
		}
		han=(Handle)LastItem();
#ifdef Frank_GenuineMac
		GLresize(han,BlockSize,"FBlockManager::LargerPacketSize");
#else
		han=SetHandleSizePatch(han,BlockSize);
		SetItem((Ptr)&han,numItems);
#endif
	}
#ifdef Frank_MemoryDebugging
	extern FGLink *pTreeLink;
	extern FGLink *pLibLink;
	extern long pTreeTotal,libTreeTotal;
	long addedMemory=newBlockSize-BlockSize;
	if(itsGLink==pTreeLink) pTreeTotal+= addedMemory;
	if(itsGLink==pLibLink) libTreeTotal+= addedMemory;
#endif
}


void FBlockManager::NewBlock(GLref& address){ /*moves memory*/
	Handle han;
	long grow,zero=0;
	han=GLhandle(BlockSize,"FBlockManager::NewBlock");
	Append((FObject*)han);
	lock->Append((FObject*)zero); // new block starts out unlocked
	address.index=numItems;
	address.offset=0L;
	TotalAllocation=TotalAllocation+BlockSize;
	ToppedOff=FALSE;
#ifdef Frank_MemoryDebugging

/* COMMENTED OUT
	extern Boolean toggleSkip;
	if(!toggleSkip){
		toggleSkip=TRUE;
		memout <= "\n";
	}
	memout <= ">";
END COMMENTED OUT */

	extern FGLink *pTreeLink;
	extern FGLink *pLibLink;
	extern long pTreeTotal,libTreeTotal;
	if(itsGLink==pTreeLink) pTreeTotal+= BlockSize;
	if(itsGLink==pLibLink) libTreeTotal+= BlockSize;
#endif
}


Boolean FBlockManager::DoForEach2(BooleanFunc theFunc,void *param){
	long i;
	for (i = 0; i < numItems; i++) {
		if((*theFunc)((void*)(*items)[i], (void*)param)==FALSE){
			return(FALSE);
		}
	}
	return(TRUE);
}



ostream& FBlockManager::repBlockSize(ostream& s){
	return s <= BlockSize;
}




See more files for this project here

Magnus

Magnus is a special purpose mathematical package for Infinite Group Theory computations

Project homepage: http://sourceforge.net/projects/magnus
Programming language(s): C,C++
License: other

  FBlockManager.C
  FBlockManager.h
  FGLink.C
  FGLink.h
  FGLnode.C
  FGLnode.h
  FGLrecycleStack.C
  FGLrecycleStack.h
  FGLstack.C
  FGLstack.h
  FGLstepper.C
  FGLstepper.h
  FGLwalkNode.C
  FGLwalkNode.h
  FcleanUpNode.C
  FcleanUpNode.h
  FcloneNode.C
  FcloneNode.h
  FdebugNode.C
  FdebugNode.h
  FfoldNode.C
  FfoldNode.h
  FfoldStepper.C
  FfoldStepper.h
  FgrowNode.C
  FgrowNode.h
  FrandomRef.C
  FrandomRef.h
  FreducedFoldNode.C
  FreducedFoldNode.h
  FreducedVertexFolder.C
  FreducedVertexFolder.h
  FvertexFolder.C
  FvertexFolder.h
  GLfunctions.C
  GLfunctions.h
  GLref.h
  _FnameNode.cp_
  _FnameNode.h_
  _FrankNode.cp_
  _FrankNode.h_
  _FstrToGLvarNode.cp_
  _FstrToGLvarNode.h_
  debugGLink.C
  debugGLink.h