void * PMAPI PM_allocLockedMem( uint size, ulong *physAddr, ibool contiguous, ibool below16M) { void* linear; /* Allocate a physically contiguous buffer */ #ifdef __QNXNTO__ if ((linear = mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_PHYS|MAP_ANON,NOFD,0)) == MAP_FAILED) { #else if ((linear = mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_ANON,NOFD,0)) == -1) { #endif perror("PM_allocLockedMem mmap"); return NULL; } *physAddr = PM_getPhysicalAddr(linear); return linear; } void PMAPI PM_freeLockedMem( void *p, uint size, ibool contiguous) { if (munmap(p,size) == -1) perror("PM_freeLockedMem munmap"); } /**************************************************************************** REMARKS: Allocates a new block of pages for the page block manager. ****************************************************************************/ static pageblock *PM_addNewPageBlock(void) { int i,size; pageblock *newBlock; char *p,*next; /* Allocate memory for the new page block, and add to head of list */ size = PAGES_PER_BLOCK * PM_PAGE_SIZE + (PM_PAGE_SIZE-1) + sizeof(pageblock); if ((newBlock = PM_malloc(size)) == NULL) return NULL; newBlock->prev = NULL; newBlock->next = pageBlocks; if (pageBlocks) pageBlocks->prev = newBlock; pageBlocks = newBlock; /* Initialise the page aligned free list for the page block */ newBlock->freeCount = PAGES_PER_BLOCK; newBlock->freeList = p = (char*)(((ulong)(newBlock + 1) + (PM_PAGE_SIZE-1)) & ~(PM_PAGE_SIZE-1)); newBlock->freeListStart = newBlock->freeList; newBlock->freeListEnd = p + (PAGES_PER_BLOCK-1) * PM_PAGE_SIZE; for (i = 0; i < PAGES_PER_BLOCK; i++,p = next) FREELIST_NEXT(p) = next = p + PM_PAGE_SIZE; FREELIST_NEXT(p - PM_PAGE_SIZE) = NULL; return newBlock; }
/**************************************************************************** REMARKS: Free a page aligned and page sized block of memory ****************************************************************************/ void PMAPI PM_freePage( void *p) { pageblock *block; /* First find the page block that this page belongs to */ for (block = pageBlocks; block != NULL; block = block->next) { if (p >= block->freeListStart && p <= block->freeListEnd) break; } CHECK(block != NULL); /* Now free the block by adding it to the free list */ FREELIST_NEXT(p) = block->freeList; block->freeList = p; if (++block->freeCount == PAGES_PER_BLOCK) { /* If all pages in the page block are now free, free the entire * page block itself. */ if (block == pageBlocks) { /* Delete from head */ pageBlocks = block->next; if (block->next) block->next->prev = NULL; } else { /* Delete from middle of list */ CHECK(block->prev != NULL); block->prev->next = block->next; if (block->next) block->next->prev = block->prev; } PM_free(block); } }
/**************************************************************************** RETURNS: Pointer to new segment REMARKS: Allocates space for a new segment in the segment pool from the free list. If there are no more segments, we attempt to re-size the segment pool which will bomb out if we run out of memory. {secret} ****************************************************************************/ segment_t *_MGL_newSegment(void) { segment_t *p; if (_MGL_segList.freeList == NULL) resizeSegmentList(); p = _MGL_segList.freeList; _MGL_segList.freeList = FREELIST_NEXT(p); return p; }
static struct segment * new_segment() { struct segment *seg; FREELIST_NEXT(heap_space.freelist, seg); if (seg == NULL) return NULL; seg->next = NULL; return seg; }
/**************************************************************************** REMARKS: Allocates a page aligned and page sized block of memory ****************************************************************************/ void * PMAPI PM_allocPage( ibool locked) { pageblock *block; void *p; PM_lockHandle lh; /* Scan the block list looking for any free blocks. Allocate a new * page block if no free blocks are found. */ for (block = pageBlocks; block != NULL; block = block->next) { if (block->freeCount) break; } if (block == NULL && (block = PM_addNewPageBlock()) == NULL) return NULL; block->freeCount--; p = block->freeList; block->freeList = FREELIST_NEXT(p); if (locked) PM_lockDataPages(p,PM_PAGE_SIZE,&lh); return p; }