Home | Info | Community | Development | myReactOS | Contact Us
Definition at line 122 of file gdipool.c.
Referenced by BRUSH_bAllocBrushAttr(), DC_bAllocDcAttr(), and REGION_bAllocRgnAttr().
{ PGDI_POOL_SECTION pSection; ULONG ulIndex, cjOffset, ulPageBit; PLIST_ENTRY ple; PVOID pvAlloc, pvBaseAddress; SIZE_T cjSize; /* Disable APCs and acquire the pool lock */ KeEnterCriticalRegion(); ExAcquirePushLockExclusive(&pPool->pushlock); /* Check if we have a ready section */ if (!IsListEmpty(&pPool->leReadyList)) { /* Get a free section */ ple = pPool->leReadyList.Flink; pSection = CONTAINING_RECORD(ple, GDI_POOL_SECTION, leReadyLink); if (pSection->cAllocCount >= pPool->cSlotsPerSection) { DPRINT1("pSection->cAllocCount=%ld, pPool->cSlotsPerSection=%ld\n", pSection->cAllocCount, pPool->cSlotsPerSection); DBG_DUMP_EVENT_LIST(&pPool->slhLog); ASSERT(FALSE); } ASSERT(pSection->cAllocCount < pPool->cSlotsPerSection); } else { /* No, check if we have something on the empty list */ if (!IsListEmpty(&pPool->leEmptyList)) { /* Yes, remove it from the empty list */ ple = RemoveHeadList(&pPool->leEmptyList); pSection = CONTAINING_RECORD(ple, GDI_POOL_SECTION, leInUseLink); } else { /* No, allocate a new section */ pSection = GdiPoolAllocateSection(pPool); if (!pSection) { DPRINT1("Couldn't allocate a section\n"); pvAlloc = NULL; goto done; } /* Insert it into the ready list */ InsertHeadList(&pPool->leReadyList, &pSection->leReadyLink); } /* Insert it into the in-use list */ InsertHeadList(&pPool->leInUseList, &pSection->leInUseLink); } /* Find and set a single bit */ ulIndex = RtlFindClearBitsAndSet(&pSection->bitmap, 1, 0); ASSERT(ulIndex != MAXULONG); /* Calculate the allocation address */ cjOffset = ulIndex * pPool->cjAllocSize; pvAlloc = (PVOID)((ULONG_PTR)pSection->pvBaseAddress + cjOffset); /* Check if memory is comitted */ ulPageBit = 1 << (cjOffset / PAGE_SIZE); ulPageBit |= 1 << ((cjOffset + pPool->cjAllocSize - 1) / PAGE_SIZE); if ((pSection->ulCommitBitmap & ulPageBit) != ulPageBit) { /* Commit the pages */ pvBaseAddress = PAGE_ALIGN(pvAlloc); cjSize = ADDRESS_AND_SIZE_TO_SPAN_PAGES(pvAlloc, pPool->cjAllocSize) * PAGE_SIZE; ZwAllocateVirtualMemory(NtCurrentProcess(), &pvBaseAddress, 0, &cjSize, MEM_COMMIT, PAGE_READWRITE); pSection->ulCommitBitmap |= ulPageBit; } /* Increase alloc count */ pSection->cAllocCount++; DBG_LOGEVENT(&pPool->slhLog, EVENT_ALLOCATE, pvAlloc); /* Check if section is now busy */ if (pSection->cAllocCount == pPool->cSlotsPerSection) { /* Remove the section from the ready list */ RemoveEntryList(&pSection->leReadyLink); } done: /* Release the pool lock and enable APCs */ ExReleasePushLockExclusive(&pPool->pushlock); KeLeaveCriticalRegion(); DPRINT("GdiPoolallocate: %p\n", pvAlloc); return pvAlloc; }