STATUS semDestroy(SEM_ID semId, BOOL dealloc) { int level; level = intLock(); if(!IS_CLASS(semId, semClassId)) { return (ERROR); } objCoreTerminate(&semId->objCore); kernelState = TRUE; intUnlock(level); kernelSemDelete(semId); TASK_SAFE(); kernelExit(); if(dealloc) { objFree(semClassId, (char*)semId); } TASK_UNSAFE(); return (OK); }
static STATUS msgQDestroy(MSG_Q_ID msgQId, BOOL dealloc) { Q_JOB_NODE* pNode; FAST int timeout; FAST int nMsgs; /* TODO isr not allowed */ TASK_SAFE(); TASK_LOCK(); if(!IS_CLASS(msgQId, msgQClassId)) { TASK_UNLOCK(); TASK_UNSAFE(); return (ERROR); } objCoreTerminate(&msgQId->objCore); TASK_UNLOCK(); timeout = NO_WAIT; nMsgs = 0; while(nMsgs < msgQId->maxMsgs) { while(((pNode = qJobGet(msgQId, &msgQId->freeQ, timeout)) != NULL) && (pNode != (Q_JOB_NODE*)NONE)) { nMsgs++; } while(((pNode = qJobGet(msgQId, &msgQId->msgQ, timeout)) != NULL) && (pNode != (Q_JOB_NODE*)NONE)) { nMsgs++; } timeout = 1; } kernelState = TRUE; qJobTerminate(&msgQId->msgQ); qJobTerminate(&msgQId->freeQ); kernelExit(); if(dealloc) { objFree(msgQClassId, (char*)msgQId); } TASK_UNSAFE(); return (OK); }
STATUS wdDestroy( WDOG_ID wdId, BOOL dealloc ) { STATUS status; int level; /* Not callable from interrupts */ if (INT_RESTRICT() != OK) { status = ERROR; } else { /* Lock interrupts */ INT_LOCK(level); /* Verify object */ if (OBJ_VERIFY(wdId, wdClassId) != OK ) { INT_UNLOCK(level); status = ERROR; } else { /* Terminate object */ objCoreTerminate(&wdId->objCore); /* Enter kernel */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Cancel watchdog timer */ vmxWdCancel(wdId); wdId->status = WDOG_DEAD; taskSafe(); /* Exit kernel */ vmxExit(); /* Deallocate if requested */ if (dealloc == TRUE) { objFree(wdClassId, wdId); } taskUnsafe(); status = OK; } } return status; }
STATUS hashTblDestroy ( HASH_ID hashId, /* id of hash table to destroy */ BOOL dealloc /* deallocate associated memory */ ) { if (OBJ_VERIFY (hashId, hashClassId) != OK) return (ERROR); /* invalid hash id */ objCoreTerminate (&hashId->objCore); /* terminate core */ if (dealloc) return (objFree (hashClassId, (char *) hashId)); return (OK); }
STATUS semDestroy( SEM_ID semId, BOOL deallocate ) { STATUS status; int level; if (INT_RESTRICT() != OK) { errnoSet(S_intLib_NOT_ISR_CALLABLE); status = ERROR; } else { INT_LOCK(level); if (OBJ_VERIFY(semId, semClassId) != OK) { INT_UNLOCK(level); status = ERROR; } else { objCoreTerminate(&semId->objCore); /* Delete it */ kernelState = TRUE; INT_UNLOCK(level); vmxSemDelete(semId); taskSafe(); vmxExit(); if (deallocate == TRUE) { objFree(semClassId, semId); } taskUnsafe(); status = OK; } } return status; }
STATUS wdDestroy ( WDOG_ID wdId, /* ID of watchdog to terminate */ BOOL dealloc /* dealloc associated memory */ ) { int level; if (INT_RESTRICT () != OK) /* restrict isr use */ return (ERROR); level = intLock (); /* LOCK INTERRUPTS */ if (OBJ_VERIFY (wdId, wdClassId) != OK) /* validate watchdog ID */ { intUnlock (level); /* UNLOCK INTERRUPTS */ return (ERROR); } #ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_1 (OBJ, wdId, wdClassId, EVENT_WDDELETE, wdId); #endif objCoreTerminate (&wdId->objCore); /* invalidate watchdog */ kernelState = TRUE; /* KERNEL ENTER */ intUnlock (level); /* UNLOCK INTERRUPTS */ windWdCancel (wdId); /* cancel watchdog */ wdId->status = WDOG_DEAD; /* dead dog */ TASK_SAFE (); /* TASK SAFE */ windExit (); /* EXIT KERNEL */ if (dealloc) objFree (wdClassId, (char *) wdId); /* deallocate watchdog */ TASK_UNSAFE (); /* TASK UNSAFE */ return (OK); }
STATUS taskDestroy( int taskId, BOOL freeStack, unsigned timeout, BOOL forceDestroy ) { STATUS status; int i, level; TCB_ID tcbId; if (INT_RESTRICT() != OK) { errnoSet (S_intLib_NOT_ISR_CALLABLE); return ERROR; } /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) return ERROR; /* If task self destruct and excption lib installed */ if (tcbId == taskIdCurrent) { /* Wait for safe to destroy */ while (tcbId->safeCount > 0) taskUnsafe(); /* Kill it */ status = excJobAdd( (VOIDFUNCPTR) taskDestroy, (ARG) tcbId, (ARG) freeStack, (ARG) WAIT_NONE, (ARG) FALSE, (ARG) 0, (ARG) 0 ); /* Block here and suspend */ while(status == OK) taskSuspend(0); } /* End if task self destruct and exception lib installed */ taskDestroyLoop: /* Lock interrupts */ INT_LOCK(level); /* Check id */ if (TASK_ID_VERIFY(tcbId) != OK) { /* errno set by taskIdVerify() */ /* Unlock interrupts */ INT_UNLOCK(level); return ERROR; } /* Mask all signals */ if (tcbId->pSignalInfo != NULL) tcbId->pSignalInfo->sigt_blocked = 0xffffffff; /* Block here for safe and running locked tasks */ while ( (tcbId->safeCount > 0) || ( (tcbId->status == TASK_READY) && (tcbId->lockCount > 0) ) ) { /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Check if force deletion, or suicide */ if (forceDestroy || (tcbId == taskIdCurrent)) { /* Remove protections */ tcbId->safeCount = 0; tcbId->lockCount = 0; /* Check if flush of safety queue is needed */ if (Q_FIRST(&tcbId->safetyQ) != NULL) vmxPendQFlush(&tcbId->safetyQ); /* Exit trough kernel */ vmxExit(); } else { /* Not forced deletion or suicide */ /* Put task on safe queue */ if (vmxPendQPut(&tcbId->safetyQ, timeout) != OK) { /* Exit trough kernel */ vmxExit(); errnoSet (S_taskLib_INVALID_TIMEOUT); return ERROR; } /* Exit trough kernel */ status = vmxExit(); /* Check for restart */ if (status == SIG_RESTART) { timeout = (sigTimeoutRecalc)(timeout); goto taskDestroyLoop; } /* Check if unsuccessful */ if (status == ERROR) { /* timer should have set errno to S_objLib_TIMEOUT */ return ERROR; } } /* End else forced or suicide */ /* Lock interrupts */ INT_LOCK(level); /* Now verify class id again */ if (TASK_ID_VERIFY(tcbId) != OK) { /* errno set by taskIdVerify() */ /* Unlock interrupts */ INT_UNLOCK(level); return ERROR; } } /* End while blocked by safety */ /* Now only one cadidate is selected for deletion */ /* Make myself safe */ taskSafe(); /* Protet deletion cadidate */ tcbId->safeCount++; /* Check if not suicide */ if (tcbId != taskIdCurrent) { /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Suspend victim */ vmxSuspend(tcbId); /* Exit trough kernel */ vmxExit(); } else { /* Unlock interrupts */ INT_UNLOCK(level); } /* Run deletion hooks */ for (i = 0; i < MAX_TASK_DELETE_HOOKS; i++) if (taskDeleteHooks[i] != NULL) (*taskDeleteHooks[i])(tcbId); /* Lock task */ taskLock(); /* If dealloc and options dealloc stack */ if ( freeStack && (tcbId->options & TASK_OPTIONS_DEALLOC_STACK) ) { #if (_STACK_DIR == _STACK_GROWS_DOWN) objFree(taskClassId, tcbId->pStackEnd); #else /* _STACK_GROWS_UP */ objFree(taskClassId, tbcId - TASK_EXTRA_BYTES); #endif /* _STACK_DIR */ } /* Lock interrupts */ INT_LOCK(level); /* Invalidate id */ objCoreTerminate(&tcbId->objCore); /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Delete task */ status = vmxDelete(tcbId); /* Check if safe quque needs to be flushed */ if (Q_FIRST(&tcbId->safetyQ) != NULL) vmxPendQFlush(&tcbId->safetyQ); /* Exit trough kernel */ vmxExit(); /* Unprotect */ taskUnlock(); taskUnsafe(); return OK; }