示例#1
0
static void *internal_Allocate(int size, int flags, char *file, int line){
#else
static void *internal_Allocate(int size, int flags){
#endif

//	assert(size!=48);

//int log=1;
//int tmp = size-1;
//while((tmp>>=1)!=0) log++;
//printf("AllocateSize %d,%d\n",size,log);
	if(!initialized){
		heap_sem = new Semaphore();
		heap_sem->Acquire();

		#ifdef MEMORY_STATS
		thread_sem = new Semaphore();
		thread_sem->Acquire();
unsigned long dwThreadId;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ticker, 0, 0, &dwThreadId);
//		_beginthread(&ticker,4096,0);
		thread_sem->Acquire();
//		Sleep(100000);
		#endif

		HANDLE file = CreateFileMapping((HANDLE)-1,0,PAGE_READWRITE,0,HEAP_SIZE+sizeof(Heap),0);
printf("Total shared heap space allocated = %d bytes\n",heap_bytes+=HEAP_SIZE);
		Heap *h = (Heap*)MapViewOfFile(file,FILE_MAP_WRITE,0,0,0);
		assert(h);
		first_heap = h;
		h->Next = 0;
		h->File = file;
		memset(h->Mask,0,HEAP_SIZE/BLOCK_SIZE/8);
		memset(h->Type,0,HEAP_SIZE/BLOCK_SIZE/8);
		memset(h->Size,-1,HEAP_SIZE/BLOCK_SIZE*sizeof(int));
		h->Blocks = (void*)(int(h)+sizeof(Heap));
		initialized = true;		// Assume we get no errors
		#ifdef _DEBUG
		void *block = internal_Allocate(BLOCK_SIZE-sizeof(MemHeader),flags,0,0);
		#else
		void *block = internal_Allocate(BLOCK_SIZE-sizeof(MemHeader),flags);
		#endif
		assert(block);
		if(!block){
			heap_sem->Release();
			printf("Failed!\n");
			return 0;
		}
		int _size = 32*sizeof(Fragment*);			// fixme: not 32 bits
		int log=1;
		int tmp = _size-1;
		while((tmp>>=1)!=0) log++;

		h = GetHeap(block);
		int blockn = h->GetBlock(block);
		h->Size[blockn] = size;
		h->Type[blockn/8]|=1<<(blockn&7);

		Fragments = (Fragment**)block;
		memset(Fragments,0,32*sizeof(Fragment*));	// fixme: not 32 bits

		Fragments[log] = (Fragment*)(int(block)+(2<<log));
		Fragments[log]->Next = 0;
		Fragments[log]->Prev = 0;

		for(int n=3; n<(BLOCK_SIZE-sizeof(MemHeader))>>log; n++){
			Fragment *frag = (Fragment*)(int(block)+(n<<log));
			Fragments[log]->Next = frag;
			frag->Next = 0;
			frag->Prev = Fragments[log];
			Fragments[log] = frag;
		}
		heap_sem->Release();
		#ifdef MEMORY_STATS
		total_used_history = (DynamicArray*)internal_Allocate(sizeof(DynamicArray),flags,0,0);
		total_size_history = (DynamicArray*)internal_Allocate(sizeof(DynamicArray),flags,0,0);
		total_frag_history = (DynamicArray*)internal_Allocate(sizeof(DynamicArray),flags,0,0);
		total_frags_history = (DynamicArray*)internal_Allocate(sizeof(DynamicArray),flags,0,0);
		total_blocks_history = (DynamicArray*)internal_Allocate(sizeof(DynamicArray),flags,0,0);
		total_used_history->DynamicArray::DynamicArray(DARRAY_SHARED_MEMORY);
		total_size_history->DynamicArray::DynamicArray(DARRAY_SHARED_MEMORY);
		total_frag_history->DynamicArray::DynamicArray(DARRAY_SHARED_MEMORY);
		total_frags_history->DynamicArray::DynamicArray(DARRAY_SHARED_MEMORY);
		total_blocks_history->DynamicArray::DynamicArray(DARRAY_SHARED_MEMORY);
		#endif
	}
	heap_sem->Acquire();
	int orgsize = size;
	size+=sizeof(MemHeader);
	if(size<sizeof(Fragment)) size = sizeof(Fragment);

	if(size<=BLOCK_SIZE/2){


		int log=1;
		int tmp = size-1;
		while((tmp>>=1)!=0) log++;

//printf("Frag %d!\n",log);
		if(!Fragments[log]){
//printf("Frag %d empty!\n",log);
			#ifdef _DEBUG
			void *block = internal_Allocate(BLOCK_SIZE-sizeof(MemHeader),flags,0,0);
			#else
			void *block = internal_Allocate(BLOCK_SIZE-sizeof(MemHeader),flags);
			#endif
			assert(block);
			if(!block){
				heap_sem->Release();
				assert(false);
				return 0;
			}
			Heap *h = GetHeap(block);
			int blockn = h->GetBlock(block);
			h->Size[blockn] = log;
//printf("h->Size[3] = %d\n",h->Size[3]);
			h->Type[blockn/8]|=1<<(blockn&7);

			Fragments[log] = (Fragment*)block;
			Fragments[log]->Next = 0;
			Fragments[log]->Prev = 0;

			for(int n=2; n<(BLOCK_SIZE-sizeof(MemHeader))>>log; n++){
				Fragment *frag = (Fragment*)(int(block)+(n<<log));
				Fragments[log]->Next = frag;
				frag->Next = 0;
				frag->Prev = Fragments[log];
				Fragments[log] = frag;
			}
		}

//		int frags = get_frag_count();

		MemHeader *header = (MemHeader*)Fragments[log];
//printf("Alloc: %d\n",log);
	if(Fragments[log]->Prev) Fragments[log]->Prev->Next = Fragments[log]->Next;
	if(Fragments[log]->Next) Fragments[log]->Next->Prev = Fragments[log]->Prev;
		Fragments[log] = Fragments[log]->Prev;
//DumpStuff();
//GetHeap(data);
		//#ifdef MEMORY_STATISTICS
//		heap_used+=orgsize;
		//#endif

//		frags = frags-get_frag_count();
		//printf("Alloc: %d\n",frags);
//		assert(frags==1);

		#ifdef _DEBUG
		AddToFile(header,file,line,orgsize); //1<<log);
		#endif
//printf("Alloc at %x\n",data);
//printf("Alloc(%d) %x\n",orgsize,header);
		header->size = orgsize;
//printf("a\n");
		#ifdef MEMORY_STATS
		if(file&&line){
			header->line = line;
			if(file){
				header->file = (char*)internal_Allocate(strlen(file)+1,flags,0,0);
				sprintf(header->file,"%s",file);
			}else header->file = 0;

//printf("b\n");
			MemHeader *ent = list;
			while(ent){
				if(ent->line==header->line){
					if(ent->file&&header->file){
						if(!strcmp(ent->file,header->file)){
							header->listent = ent;
							ent->size+=orgsize;
							break;
						}
					}else if(!ent->file&&!!header->file){
						header->listent = ent;
						ent->size+=orgsize;
						break;
					}
				}
				ent = ent->Next;
			}
//printf("c\n");
			if(!ent){
				MemHeader *ent = (MemHeader*)internal_Allocate(sizeof(MemHeader),flags,0,0);
				ent->size = orgsize;
				ent->file = file;
				ent->line = line;
				ent->history = (DynamicArray*)internal_Allocate(sizeof(DynamicArray),flags,0,0);
				ent->history->DynamicArray::DynamicArray(DARRAY_SHARED_MEMORY);
				header->listent = ent;
				ent->Next = list;
				list = ent;
			}
		}else header->listent = 0;
		#endif

//printf("d\n");
		heap_used+=orgsize;
//printf("Allocated %d bytes!\n",orgsize);
		heap_sem->Release();
//printf("e\n");
		return (void*)(int(header)+sizeof(MemHeader));
	}else{