示例#1
0
文件: sheap.cpp 项目: kolyden/mirror
Heap::Page *Heap::WorkPage(int k) // get a new empty workpage
{
	LLOG("AllocK - next work not available " << k << " empty: " << (void *)empty[k]);
	Page *page = empty[k]; // hot empty page of the same klass
	empty[k] = NULL;
	if(!page) { // try to reacquire pages freed remotely
		LLOG("AllocK - trying FreeRemote");
		FreeRemote();
		if(work[k]->freelist) { // partially free page found
			LLOG("AllocK - work available after FreeRemote " << k);
			return work[k];
		}
		page = empty[k]; // hot empty page
		empty[k] = NULL;
	}
	if(!page)
		for(int i = 0; i < NKLASS; i++) // Try hot local page of different klass
			if(empty[i]) {
				LLOG("AllocK - free page available for reformatting " << k);
				page = empty[i];
				empty[i] = NULL;
				page->Format(k);
				break;
			}
	if(!page) { // Attempt to find page in global storage of free pages
		Mutex::Lock __(mutex);
		aux.FreeRemoteRaw();
		if(aux.work[k]->next != aux.work[k]) { // Try page of the same klass first
			page = aux.work[k]->next;
			page->Unlink();
			page->heap = this;
			LLOG("AllocK - adopting aux page " << k << " page: " << (void *)page << ", free " << (void *)page->freelist);
		}
		if(!page && aux.empty[k]) { // Try hot empty page of the same klass
			page = aux.empty[k];
			aux.empty[k] = page->next;
			LLOG("AllocK - empty aux page available of the same format " << k << " page: " << (void *)page << ", free " << (void *)page->freelist);
		}
		if(!page)
			for(int i = 0; i < NKLASS; i++) // Finally try to to find hot page of different klass
				if(aux.empty[i]) {
					page = aux.empty[i];
					aux.empty[i] = page->next;
					page->Format(k);
					LLOG("AllocK - empty aux page available for reformatting " << k << " page: " << (void *)page << ", free " << (void *)page->freelist);
					break;
				}
		if(!page) { // Not free memory was found, ask system for the new page
			page = (Page *)AllocRaw4KB(Ksz(k));
			LLOG("AllocK - allocated new system page " << (void *)page << " " << k);
			page->Format(k);
		}
		page->heap = this;
	}
	page->Link(work[k]);
	ASSERT(page->klass == k);
	return page;
}
示例#2
0
inline void *MSmall::AllocK(int k)
{
	LOG("AllocK " << (int)k);
	Page *page = work[k]->next;
	for(;;) {
		ASSERT(page->klass == k);
		FreeLink *p = page->freelist;
		if(p) {
			page->freelist = p->next;
			++page->active;
			return p;
		}
		if(page->free > page->Begin()) { // Try swapping with freelist
			void *p = page->free;
			page->free -= page->sz;
			++page->active;
			return p;
		}
		if(page->next != page) {
			page->active = 255;
			page->Unlink();
			page->Link(full[k]);
			page = work[k]->next;
		}
		else {
			page = empty[k]->next;
			if(page->next == page) {
				if(emptypages) {
					emptypages--;
					for(int i = 0; i < 16; i++) { // try inverse direction
						page = empty[i]->next;
						if(page->next != page) {
							page->Unlink();
							break;
						}
					}
					ASSERT(page->next != page);
				}
				else // remote delete should be here!
					page = (Page *)AllocRaw4KB();
				page->Format(k);
				ASSERT(page->klass == k);
			}
			else {
				ASSERT(emptypages > 0);
				page->Unlink();
				emptypages--;
				ASSERT(page->klass == k);
			}
			page->Link(work[k]);
			ASSERT(page->klass == k);
		}
	}
}