STATUS memPartFree(PART_ID partId, char* pBlock) { FAST BLOCK_HDR *pHdr; FAST unsigned nWords; FAST BLOCK_HDR *pNextHdr; if(!IS_CLASS(partId, memPartClassId)) { return (ERROR); } if(NULL == pBlock) { return (OK); } pHdr = BLOCK_TO_HDR(pBlock); /* TODO take semaphore hear */ semTake(partId->semPartId, WAIT_FOREVER); if((partId->options & MEM_BLOCK_CHECK) && !memPartBlockIsValid(partId, pHdr, FALSE)) { /* TODO give semaphore hear */ semGive(partId->semPartId); return (ERROR); } nWords = pHdr->nWords; if(PREV_HDR(pHdr)->free) {/* the prev hdr is free and than coalesce with it */ pHdr->free = FALSE; pHdr = PREV_HDR(pHdr); pHdr->nWords += nWords; } else { pHdr->free = TRUE; dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr)); } /* check to coalesce with the next */ pNextHdr = NEXT_HDR(pHdr); if(pNextHdr->free) { pHdr->nWords += pNextHdr->nWords; dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr)); } /* cannot use pNextHdr->prevHdr=pHdr hear */ NEXT_HDR(pHdr)->prevHdr = pHdr; partId->curBlocksAlloc--; partId->curWordsAlloc -= nWords; /* TODO give sem hear */ semGive(partId->semPartId); return (OK); }
STATUS pciIntDisconnect ( VOIDFUNCPTR *vector, /* interrupt vector to attach to */ VOIDFUNCPTR routine /* routine to be called */ ) { int irq = IVEC_TO_INUM ((int)vector) - INT_NUM_IRQ0; PCI_INT_RTN *pRtn; int oldLevel; for (pRtn = (PCI_INT_RTN *)DLL_FIRST (&pciIntList[irq]); pRtn != NULL; pRtn = (PCI_INT_RTN *)DLL_NEXT (&pRtn->node)) { if (pRtn->routine == routine) { oldLevel = intLock (); /* LOCK INTERRUPT */ dllRemove (&pciIntList[irq], &pRtn->node); intUnlock (oldLevel); /* UNLOCK INTERRUPT */ free ((char *)pRtn); return (OK); } } return (ERROR); }
LOCAL STATUS qFifoRemove( Q_FIFO_HEAD *pQFifoHead, Q_FIFO_NODE *pQFifoNode ) { dllRemove(&pQFifoHead->qFifo.head, &pQFifoNode->qFifo.node); return OK; }
STATUS qPriListRemove ( Q_PRI_HEAD *pQPriHead, Q_PRI_NODE *pQPriNode ) { dllRemove (pQPriHead, &pQPriNode->node); return (OK); }
int dllRemoveFirst (void * list) { struct dll * _list; _list = (struct dll *) list; if ((_list->prev != NULL) && (_list->next != NULL)) { return (dllRemove (_list, _list->next)); } return (0); }
STATUS qFifoRemove ( Q_FIFO_HEAD *pQFifoHead, Q_FIFO_NODE *pQFifoNode ) { dllRemove (pQFifoHead, pQFifoNode); return (OK); }
STATUS qPriDeltaRemove ( Q_PRI_HEAD *pQPriHead, Q_PRI_NODE *pQPriNode ) { Q_PRI_NODE *pNextNode = (Q_PRI_NODE *) DLL_NEXT (&pQPriNode->node); if (pNextNode != NULL) pNextNode->key += pQPriNode->key; /* add key to next node */ dllRemove (pQPriHead, &pQPriNode->node); return (OK); }
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId , FAST BLOCK_HDR* pHdr , FAST unsigned nWords , unsigned minWords , unsigned align) { FAST BLOCK_HDR *pNewHdr; FAST BLOCK_HDR *pNextHdr; FAST char *endOfBlock; FAST char *pNewBlock; int blockSize; endOfBlock = (char*)pHdr + (pHdr->nWords*2); pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2)); pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1))); pNewHdr = BLOCK_TO_HDR(pNewBlock); blockSize = ((char*)pNewHdr - (char*)pHdr)/2; if(blockSize < minWords) { if(pNewHdr == pHdr) { dllRemove(&partId->freeList, HDR_TO_NODE(pHdr)); } else { return NULL; } } else { /* recaculate pHdr */ pNewHdr->prevHdr = pHdr; pHdr->nWords = blockSize; } if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)) { pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2; pNewHdr->free = TRUE; NEXT_HDR(pNewHdr)->prevHdr = pNewHdr; } else {/* space left is enough to be a fragment on the free list then */ pNewHdr->nWords = nWords; pNewHdr->free = TRUE; pNextHdr = NEXT_HDR(pNewHdr); /* words °üÀ¨BlockHdr */ pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2; pNextHdr->prevHdr = pNewHdr; pNextHdr->free = TRUE; dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr)); NEXT_HDR(pNextHdr)->prevHdr = pNewHdr; } return (pNewHdr); }
LOCAL BLOCK_HDR *memAlignedBlockSplit ( PART_ID partId, FAST BLOCK_HDR *pHdr, FAST unsigned nWords, /* number of words in second block */ unsigned minWords, /* min num of words allowed in a block */ unsigned alignment /* boundary to align to */ ) { FAST BLOCK_HDR *pNewHdr; FAST BLOCK_HDR *pNextHdr; FAST char *endOfBlock; FAST char *pNewBlock; int blockSize; /* calculate end of pHdr block */ endOfBlock = (char *) pHdr + (pHdr->nWords * 2); /* caluclate unaligned beginning of new block */ pNewBlock = (char *) ((unsigned) endOfBlock - ((nWords - sizeof (BLOCK_HDR) / 2) * 2)); /* align the beginning of the block */ pNewBlock = (char *)((unsigned) pNewBlock & ~(alignment - 1)); pNewHdr = BLOCK_TO_HDR (pNewBlock); /* adjust original block's word count */ blockSize = ((char *) pNewHdr - (char *) pHdr) / 2; if (blockSize < minWords) { /* check to see if the new block is the same as the original block - * if so, delete if from the free list. If not, reject the newly * split block because it's too small to hang on the free list. */ if (pNewHdr == pHdr) dllRemove (&partId->freeList, HDR_TO_NODE (pHdr)); else return (NULL); } else { pNewHdr->pPrevHdr = pHdr; pHdr->nWords = blockSize; } /* check to see if space left over after we aligned the new buffer * is big enough to be a fragment on the free list. */ if (((UINT) endOfBlock - (UINT) pNewHdr - (nWords * 2)) < (minWords * 2)) { /* nope - give all the memory to the newly allocated block */ pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof (BLOCK_HDR)) / 2; pNewHdr->free = TRUE; /* fix next block to point to newly allocated block */ NEXT_HDR (pNewHdr)->pPrevHdr = pNewHdr; } else { /* the extra bytes are big enough to be a fragment on the free list - * first, fix up the newly allocated block. */ pNewHdr->nWords = nWords; pNewHdr->free = TRUE; /* split off the memory after pNewHdr and add it to the free list */ pNextHdr = NEXT_HDR (pNewHdr); pNextHdr->nWords = ((UINT) endOfBlock - (UINT) pNextHdr) / 2; pNextHdr->pPrevHdr = pNewHdr; pNextHdr->free = TRUE; dllAdd (&partId->freeList, HDR_TO_NODE (pNextHdr)); /* fix next block to point to the new fragment on the free list */ NEXT_HDR (pNextHdr)->pPrevHdr = pNextHdr; } return (pNewHdr); }
STATUS memPartFree ( PART_ID partId, /* memory partition to add block to */ char *pBlock /* pointer to block of memory to free */ ) { FAST BLOCK_HDR *pHdr; FAST unsigned nWords; FAST BLOCK_HDR *pNextHdr; if (ID_IS_SHARED (partId)) /* partition is shared? */ { if (smMemPartFreeRtn == NULL) { errno = S_smObjLib_NOT_INITIALIZED; return (ERROR); } return ((*smMemPartFreeRtn) (SM_OBJ_ID_TO_ADRS (partId), pBlock)); } /* partition is local */ if (OBJ_VERIFY (partId, memPartClassId) != OK) return (ERROR); if (pBlock == NULL) return (OK); /* ANSI C compatibility */ pHdr = BLOCK_TO_HDR (pBlock); /* get exclusive access to the partition */ semTake (&partId->sem, WAIT_FOREVER); /* optional check for validity of block */ if ((partId->options & MEM_BLOCK_CHECK) && !memPartBlockIsValid (partId, pHdr, FALSE)) { semGive (&partId->sem); /* release mutual exclusion */ if (memPartBlockErrorRtn != NULL) (* memPartBlockErrorRtn) (partId, pBlock, "memPartFree"); if (partId->options & MEM_BLOCK_ERROR_SUSPEND_FLAG) { if ((taskIdCurrent->options & VX_UNBREAKABLE) == 0) taskSuspend (0); } errnoSet (S_memLib_BLOCK_ERROR); return (ERROR); } #ifdef WV_INSTRUMENTATION EVT_OBJ_3 (OBJ, partId, memPartClassId, EVENT_MEMFREE, partId, pBlock, 2 * (pHdr->nWords)); #endif nWords = pHdr->nWords; /* check if we can coalesce with previous block; * if so, then we just extend the previous block, * otherwise we have to add this as a new free block */ if (PREV_HDR (pHdr)->free) { pHdr->free = FALSE; /* this isn't a free block */ pHdr = PREV_HDR (pHdr); /* coalesce with prev block */ pHdr->nWords += nWords; } else { pHdr->free = TRUE; /* add new free block */ dllInsert (&partId->freeList, (DL_NODE *) NULL, HDR_TO_NODE (pHdr)); } /* check if we can coalesce with next block; * if so, then we can extend our block delete next block from free list */ pNextHdr = NEXT_HDR (pHdr); if (pNextHdr->free) { pHdr->nWords += pNextHdr->nWords; /* coalesce with next */ dllRemove (&partId->freeList, HDR_TO_NODE (pNextHdr)); } /* fix up prev info of whatever block is now next */ NEXT_HDR (pHdr)->pPrevHdr = pHdr; /* adjust allocation stats */ partId->curBlocksAllocated--; partId->curWordsAllocated -= nWords; semGive (&partId->sem); return (OK); }