static ClRcT clAmsListHeadDelete(ClAmsListHeadT *pList) { while(!CL_LIST_HEAD_EMPTY(&pList->list)) { ClListHeadT *pFirst = pList->list.pNext; ClAmsEntityTriggerT *pEntityTrigger = CL_LIST_ENTRY(pFirst, ClAmsEntityTriggerT, list); clListDel(pFirst); clHeapFree(pEntityTrigger); } pList->numElements = 0; return CL_OK; }
/* * To be called during a reset or a free of the loads. */ void clAmsTestEntityUnmark(void) { ClListHeadT *pHead = &gClAmsTestEntitiesMarkerList; if(gClAmsTestEntitiesMarker == CL_FALSE) return; gClAmsTestEntitiesMarker = CL_FALSE; while(!CL_LIST_HEAD_EMPTY(pHead)) { ClListHeadT *pTemp = pHead->pNext; ClAmsTestEntitiesMarkerT *pMarker = CL_LIST_ENTRY(pTemp,ClAmsTestEntitiesMarkerT,list); clAmsTestEntityDeleteMarker(pMarker); clListDel(pTemp); free(pMarker); } }
/* * The recovery thread for entity threshold. */ static ClPtrT clAmsEntityTriggerRecoveryThread(ClPtrT pArg) { #define MAX_RECOVERY_MASK (0x3) static ClInt32T numRecovery = 0; ClTimerTimeOutT timeout = { 0, 0 }; ClTimerTimeOutT delay = { 0, 500 }; static ClAmsListHeadT recoveryList = { 0, CL_LIST_HEAD_INITIALIZER(recoveryList.list) }; clOsalMutexLock(&gClAmsEntityTriggerRecoveryCtrl.list.mutex); while(gClAmsEntityTriggerRecoveryCtrl.running == CL_TRUE) { ClListHeadT *pNext = NULL; while(!gClAmsEntityTriggerRecoveryCtrl.list.numElements) { numRecovery = 0; clOsalCondWait(&gClAmsEntityTriggerRecoveryCtrl.list.cond, &gClAmsEntityTriggerRecoveryCtrl.list.mutex, timeout); if(gClAmsEntityTriggerRecoveryCtrl.running == CL_FALSE) goto out_drain; } /* * We are here when the recovery list isn't empty. * We shove the existing recovery batch into the temp list * and reset the main list to release the lock and go lockless. */ recoveryList.numElements = gClAmsEntityTriggerRecoveryCtrl.list.numElements; gClAmsEntityTriggerRecoveryCtrl.list.numElements = 0; pNext = gClAmsEntityTriggerRecoveryCtrl.list.list.pNext; clListDelInit(&gClAmsEntityTriggerRecoveryCtrl.list.list); clListAddTail(pNext, &recoveryList.list); clOsalMutexUnlock(&gClAmsEntityTriggerRecoveryCtrl.list.mutex); while(gClAmsEntityTriggerRecoveryCtrl.running == CL_TRUE && recoveryList.numElements > 0 && !CL_LIST_HEAD_EMPTY(&recoveryList.list)) { ClListHeadT *pFirst = recoveryList.list.pNext; ClAmsEntityTriggerT *pEntityTrigger = CL_LIST_ENTRY(pFirst, ClAmsEntityTriggerT, list); /* * Take a break incase you have done some recoveries */ if(numRecovery && !(numRecovery & MAX_RECOVERY_MASK)) { clOsalTaskDelay(delay); } ++numRecovery; numRecovery &= 0xffff; /* * Unlink the entry from the recovery list. */ clListDel(pFirst); clAmsEntityTriggerRecovery(pEntityTrigger); clHeapFree(pEntityTrigger); --recoveryList.numElements; } clOsalMutexLock(&gClAmsEntityTriggerRecoveryCtrl.list.mutex); if(gClAmsEntityTriggerRecoveryCtrl.running == CL_FALSE) { goto out_drain; } } /* * Drain the entries holding the lock. */ out_drain: clAmsListHeadDelete(&recoveryList); clAmsListHeadDelete(&gClAmsEntityTriggerRecoveryCtrl.list); clOsalMutexUnlock(&gClAmsEntityTriggerRecoveryCtrl.list.mutex); return NULL; }