Esempio n. 1
0
	uint64_t AllocatePage(uint64_t size, bool Below4Gb)
	{
		if(!DidInit)
			return AllocateFromReserved(size);

		auto mut = AutoMutex(mtx);
		OpsSinceLastCoalesce++;
		size_t trycount = 0;
		auto len = PageList->size();

		begin:

		if(PageList->size() == 0)
		{
			HALT("Out of physical pages");
		}

		Pair* p = PageList->front();
		if(Below4Gb && p->BaseAddr >= 0xFFFFFFFF)
		{
			trycount++;
			PageList->erase(PageList->begin());
			PageList->push_back(p);
			goto begin;
		}
		else if(p->LengthInPages > size)
		{
			p->LengthInPages -= size;
			uint64_t raddr = p->BaseAddr;

			p->BaseAddr += (size * 0x1000);
			return raddr;
		}
		else if(p->LengthInPages == size)
		{
			auto raddr = p->BaseAddr;
			PageList->erase(PageList->begin());

			delete p;
			return raddr;
		}
		else
		{
			if(trycount < len)
			{
				auto fr = PageList->front();
				PageList->erase(PageList->begin());
				PageList->push_back(fr);

				trycount++;
				goto begin;	// dirty
			}
			else
			{
				Log(1, "tried allocating %d pages, failed", size);
				HALT("Out of physical pages");
				return 0;
			}
		}
	}
Esempio n. 2
0
	void MoveCursor(uint16_t x, uint16_t y)
	{
		if(x <= CharsPerLine && y <= CharsPerColumn)
		{
			AutoMutex lk = AutoMutex(Mutexes::ConsoleOutput);
			VT_CursorX = x;
			VT_CursorY = y;
		}
	}
Esempio n. 3
0
	void CoalesceFPLs()
	{
		if(!DidInit)
			return;

		// check if we even need to coalesce
		if(OpsSinceLastCoalesce < CoalesceThreshold)
			return;

		Log("Coalesced FPLs");
		auto mut = AutoMutex(mtx);
		OpsSinceLastCoalesce = 0;

		// O(n^2) time.
		// essentially, loop in a loop.
		// for each entry in the list, loop through all the other entries to see if there's anything suitable.
		// if so, merge.
		// to make sure we don't screw with the list while in the middle of it, go back to the beginning and loop again.
		// this is a background process anyway so.
		for(size_t i = 0; i < PageList->size(); i++)
		{
			bool delp = false;
			// Pair* p = PageList->pop_front();
			auto p = PageList->front();
			PageList->erase(PageList->begin());

			uint64_t base = p->BaseAddr;
			uint64_t end = p->BaseAddr + (p->LengthInPages * 0x1000);

			for(size_t k = 0; k < PageList->size(); k++)
			{
				// Pair* other = PageList->pop_front();
				auto other = PageList->front();
				PageList->erase(PageList->begin());

				if(other->BaseAddr == end)
				{
					p->LengthInPages += other->LengthInPages;
					delete other;
					break;
				}
				else if(other->BaseAddr + (other->LengthInPages * 0x1000) == base)
				{
					other->LengthInPages += p->LengthInPages;
					delp = true;
					break;
				}
			}

			if(delp)
			{
				delete p;
			}
			else
				PageList->push_back(p);
		}
	}
Esempio n. 4
0
	void FreePage(uint64_t page, uint64_t size)
	{
		auto mut = AutoMutex(mtx);
		OpsSinceLastCoalesce++;

		uint64_t end = page + (size * 0x1000);

		bool ret = false;
		for(size_t i = 0; i < PageList->size(); i++)
		{
			Pair* pair = PageList->front();
			PageList->erase_unordered(PageList->begin());

			// 3 basic conditions
			// 1. we find a match below a pair's baseaddr
			// 2. we find a match above a pair's baseaddr
			// 3. we don't find a match

			if(end == pair->BaseAddr)
			{
				pair->BaseAddr = page;
				pair->LengthInPages += size;
				ret = true;
			}
			else if(pair->BaseAddr + (pair->LengthInPages * 0x1000) == page)
			{
				pair->LengthInPages += size;
				ret = true;
			}

			PageList->push_back(pair);

			if(ret)
				return;
		}

		// if we reach here, we haven't found a match.
		Pair* np = new Pair();
		np->BaseAddr = page;
		np->LengthInPages = size;

		PageList->push_back(np);
	}
Esempio n. 5
0
	void PrintChar(uint8_t c)
	{
		if(c == 0)
			return;

		if(SERIALMIRROR){ HardwareAbstraction::Devices::SerialPort::WriteChar(c); }

		if(!IsInitialised())
		{
			Kernel::HardwareAbstraction::VideoOutput::Console80x25::PrintChar(c);
			return;
		}

		AutoMutex lk = AutoMutex(Mutexes::ConsoleOutput);

		if(c == '\r')
		{
			VT_CursorX = 0;
			return;
		}
		if(c == '\b')
		{
			if(VT_CursorX > 0)
			{
				VT_CursorX--;
				DrawChar(' ', (VT_CursorX * CharWidth) + OffsetLeft, (VT_CursorY * 16), VT_Colour);
			}
			else if(VT_CursorY > 0)
			{
				VT_CursorX = CharsPerLine - 1;
				VT_CursorY--;

				DrawChar(' ', (VT_CursorX * CharWidth) + OffsetLeft, (VT_CursorY * 16), VT_Colour);
			}

			return;
		}

		if(VT_CursorY == CharsPerColumn && VT_CursorX == CharsPerLine)
		{
			// Reached end of line and no more space below
			VT_CursorX = 0;
			ScrollDown(1);



			if(c == '\n' || c == '\t')
			{
				ScrollDown(1);
				VT_CursorX = 0;

				return;
			}
			DrawChar(c, (VT_CursorX * CharWidth) + OffsetLeft, (VT_CursorY * 16), VT_Colour);
			VT_CursorX++;

		}
		else if((VT_CursorX * 8) >= ((GetResX()) - 10))
		{
			// Reached end of line
			VT_CursorX = 0;
			VT_CursorY++;

			DrawChar(c, (VT_CursorX * CharWidth) + OffsetLeft, (VT_CursorY * 16), VT_Colour);
			VT_CursorX = 1;
		}
		else
		{
			if(c == '\n')
			{
				if(VT_CursorY < CharsPerColumn)
				{
					VT_CursorX = 0;
					VT_CursorY++;
				}
				else
				{
					VT_CursorX = 0;
					ScrollDown(1);
				}

				return;
			}
			else if(c == '\t')
			{
				if(((VT_CursorX + 4) & ~(4 - 1)) < CharsPerLine)
				{
					VT_CursorX = (VT_CursorX + 4) & ~(4 - 1);
				}
				else
				{
					VT_CursorX = 0;
					if(VT_CursorY < CharsPerColumn)
						VT_CursorY++;

					else
						ScrollDown(1);
				}

				return;
			}

			// Normal printing
			DrawChar(c, (VT_CursorX * CharWidth) + OffsetLeft, (VT_CursorY * 16), VT_Colour);
			VT_CursorX++;
		}

		return;
	}