/* * ======== WMD_MSG_DeleteQueue ======== * Delete a MSG queue allocated in WMD_MSG_CreateQueue. */ void WMD_MSG_DeleteQueue(struct MSG_QUEUE *hMsgQueue) { struct MSG_MGR *hMsgMgr = hMsgQueue->hMsgMgr; u32 refCount; DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE)); hMsgQueue->fDone = true; /* Unblock all threads blocked in MSG_Get() or MSG_Put(). */ refCount = hMsgQueue->refCount; while (refCount) { /* Unblock thread */ SYNC_SetEvent(hMsgQueue->hSyncDone); /* Wait for acknowledgement */ SYNC_WaitOnEvent(hMsgQueue->hSyncDoneAck, SYNC_INFINITE); refCount = hMsgQueue->refCount; } /* Remove message queue from hMsgMgr->queueList */ (void)SYNC_EnterCS(hMsgMgr->hSyncCS); LST_RemoveElem(hMsgMgr->queueList, (struct LST_ELEM *)hMsgQueue); /* Free the message queue object */ DeleteMsgQueue(hMsgQueue, hMsgQueue->uMaxMsgs); if (!hMsgMgr->msgFreeList) goto func_cont; if (LST_IsEmpty(hMsgMgr->msgFreeList)) SYNC_ResetEvent(hMsgMgr->hSyncEvent); func_cont: (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); }
/* * ======== RMM_free ======== */ bool RMM_free(struct RMM_TargetObj *target, u32 segid, u32 addr, u32 size, bool reserved) { struct RMM_OvlySect *sect; bool retVal = true; DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE)); DBC_Require(reserved || segid < target->numSegs); DBC_Require(reserved || (addr >= target->segTab[segid].base && (addr + size) <= (target->segTab[segid].base + target->segTab[segid].length))); GT_5trace(RMM_debugMask, GT_ENTER, "RMM_free(0x%lx, 0x%lx, 0x%lx, 0x%lx, " "0x%lx)\n", target, segid, addr, size, reserved); /* * Free or unreserve memory. */ if (!reserved) { retVal = freeBlock(target, segid, addr, size); if (retVal) target->segTab[segid].number--; } else { /* Unreserve memory */ sect = (struct RMM_OvlySect *)LST_First(target->ovlyList); while (sect != NULL) { if (addr == sect->addr) { DBC_Assert(size == sect->size); /* Remove from list */ LST_RemoveElem(target->ovlyList, (struct LST_ELEM *)sect); MEM_Free(sect); break; } sect = (struct RMM_OvlySect *)LST_Next(target->ovlyList, (struct LST_ELEM *)sect); } if (sect == NULL) retVal = false; } return retVal; }
/* * ======== NTFY_Register ======== * Purpose: * Add a notification element to the list. If the notification is already * registered, and uEventMask != 0, the notification will get posted for * events specified in the new event mask. If the notification is already * registered and uEventMask == 0, the notification will be unregistered. */ DSP_STATUS NTFY_Register(struct NTFY_OBJECT *hNtfy, struct DSP_NOTIFICATION *hNotification, u32 uEventMask, u32 uNotifyType) { struct NOTIFICATION *pNotify; struct SYNC_ATTRS syncAttrs; DSP_STATUS status = DSP_SOK; DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE)); if (hNotification == NULL) status = DSP_EHANDLE; /* Return DSP_ENOTIMPL if uNotifyType is not supported */ if (DSP_SUCCEEDED(status)) { if (!IsValidNotifyMask(uNotifyType)) status = DSP_ENOTIMPL; } if (DSP_FAILED(status)) return status; (void)SYNC_EnterCS(hNtfy->hSync); pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList); while (pNotify != NULL) { /* If there is more than one notification type, each * type may require its own handler code. */ if (hNotification->handle == pNotify->hSync) { /* found */ break; } pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList, (struct list_head *)pNotify); } if (pNotify == NULL) { /* Not registered */ if (uEventMask == 0) { status = DSP_EVALUE; } else { /* Allocate NOTIFICATION object, add to list */ pNotify = MEM_Calloc(sizeof(struct NOTIFICATION), MEM_PAGED); if (pNotify == NULL) status = DSP_EMEMORY; } if (DSP_SUCCEEDED(status)) { LST_InitElem((struct list_head *)pNotify); /* If there is more than one notification type, each * type may require its own handler code. */ status = SYNC_OpenEvent(&pNotify->hSync, &syncAttrs); hNotification->handle = pNotify->hSync; if (DSP_SUCCEEDED(status)) { pNotify->uEventMask = uEventMask; pNotify->uNotifyType = uNotifyType; LST_PutTail(hNtfy->notifyList, (struct list_head *)pNotify); } else { DeleteNotify(pNotify); } } } else { /* Found in list */ if (uEventMask == 0) { /* Remove from list and free */ LST_RemoveElem(hNtfy->notifyList, (struct list_head *)pNotify); DeleteNotify(pNotify); } else { /* Update notification mask (type shouldn't change) */ pNotify->uEventMask = uEventMask; } } (void)SYNC_LeaveCS(hNtfy->hSync); return status; }