コード例 #1
0
ファイル: TempSpace.cpp プロジェクト: AsylumCorp/dsploit
size_t TempSpace::allocateBatch(size_t count, size_t minSize, size_t maxSize, Segments& segments)
{
	// adjust passed chunk size to amount of free memory we have and number
	// of runs still not allocated.
	offset_t freeMem = 0;

	for (bool found = freeSegments.getFirst(); found; found = freeSegments.getNext())
		freeMem += freeSegments.current().size;

	freeMem = MIN(freeMem / count, maxSize);
	freeMem = MAX(freeMem, minSize);
	freeMem = MIN(freeMem, minBlockSize);
	freeMem &= ~(FB_ALIGNMENT - 1);

	bool is_positioned = freeSegments.getFirst();
	while (segments.getCount() < count && is_positioned)
	{
		Segment* freeSpace = &freeSegments.current();
		offset_t freeSeek = freeSpace->position;
		const offset_t freeEnd = freeSpace->position + freeSpace->size;

		UCHAR* const mem = findMemory(freeSeek, freeEnd, freeMem);

		if (mem)
		{
			fb_assert(freeSeek + freeMem <= freeEnd);
#ifdef DEV_BUILD
			offset_t seek1 = freeSeek;
			UCHAR* const p = findMemory(seek1, freeEnd, freeMem);
			fb_assert(p == mem);
			fb_assert(seek1 == freeSeek);
#endif
			if (freeSeek != freeSpace->position)
			{
				const offset_t skip_size = freeSeek - freeSpace->position;
				const Segment skip_space(freeSpace->position, skip_size);

				freeSpace->position += skip_size;
				freeSpace->size -= skip_size;
				fb_assert(freeSpace->size != 0);

				if (!freeSegments.add(skip_space))
					fb_assert(false);

				if (!freeSegments.locate(skip_space.position + skip_size))
					fb_assert(false);

				freeSpace = &freeSegments.current();
			}

			SegmentInMemory seg;
			seg.memory = mem;
			seg.position = freeSeek;
			seg.size = freeMem;
			segments.add(seg);

			freeSpace->position += freeMem;
			freeSpace->size -= freeMem;

			if (!freeSpace->size)
			{
				is_positioned = freeSegments.fastRemove();
			}
		}
		else
		{
			is_positioned = freeSegments.getNext();
		}
	}

	return segments.getCount();
}