int main(int argc, char const *argv[]) { // creating a new list dll_t *list = dll_create(); dll_registerCompareFn(list, compareFn); dll_registerFreeFn(list, freeFn); dll_registerPrintFn(list, printFn); // ask for the number of persons to enter puts("How many persons do you like to enter?"); char input[sizeof(stdin)]; fgets(input, sizeof(stdin), stdin); int x; sscanf(input, "%d", &x); // ask for person data for x times int i; for(i = 0; i < x; i++) { dll_pushTail(list, askPersonData() ); } // print data dll_print(list); puts(""); // reverse the list puts("reverse"); dll_reverse(list); // use dll iterator functions in a for loop to print the reversed list for(dll_head(list); dll_hasNext(list); dll_next(list)) { printFn(list->curr->data); } puts("sort"); dll_sort(list); // use dll iterator functions in a while loop to print the sorted list dll_head(list); while(dll_hasNext(list)) { printFn(list->curr->data); dll_next(list); } printf("List size: %ld\n", dll_size(list)); // empty the whole list dll_clear(list); return 0; }
static UINT32 wdbBpDelete ( TGT_ADDR_T * pId ) { dll_t * pDll; dll_t * pNextDll; BRKPT * pBp; pBp = *(BRKPT **) pId; /* * Breakpoint ID of -1 means remove all breakpoints. * We can only remove breakpoints set by the host tools. Breakpoints * set from target shell can't be removed */ wdbTaskLock (); /* disable task switching */ if ((int ) pBp == -1) { for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = pNextDll) { pNextDll = dll_next(pDll); if (BP_BASE(pDll)->bp_flags & BP_HOST) wdbDbgBpRemove (BP_BASE(pDll)); } wdbTaskUnlock (); /* re-enable task switching */ return (WDB_OK); } /* else just remove one breakpoint */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { if (BP_BASE(pDll) == pBp) { wdbDbgBpRemove (pBp); wdbTaskUnlock (); /* re-enable task switching */ return (WDB_OK); } } wdbTaskUnlock (); /* re-enable task switching */ return (WDB_ERR_INVALID_EVENTPOINT); }
void wdbResumeSystem (void) { dll_t * pThisNode; WDB_REG_SET_OBJ * pRegSet; wdbState &= (~WDB_STATE_EXTERN_RUNNING); /* mark extern agent done */ /* * Set driver in interrupt mode only if task mode is supported by the * agent. Otherwise, it is not usefull. */ if (wdbRunsTasking ()) { (*pWdbExternCommIf->modeSet) /* reset communication stack */ (pWdbExternCommIf->commId, WDB_COMM_MODE_INT); } wdbOneShot = FALSE; /* ... */ wdbExternExitHook(); /* call extern exit hook */ /* restore inferior context */ for (pThisNode = dll_head (&wdbRegSetList); pThisNode != dll_end (&wdbRegSetList); pThisNode = dll_next (pThisNode)) { pRegSet = (WDB_REG_SET_OBJ *)pThisNode; (*pRegSet->load)(); } WDB_CTX_LOAD (&wdbExternSystemRegs); /*NOTREACHED*/ }
STATUS wdbExternRegsGet ( WDB_REG_SET_TYPE type, char ** ppRegs ) { dll_t * pThisNode; WDB_REG_SET_OBJ * pRegSet; if (type == WDB_REG_SET_IU) { *ppRegs = (char *)&wdbExternSystemRegs; return (OK); } for (pThisNode = dll_head (&wdbRegSetList); pThisNode != dll_end (&wdbRegSetList); pThisNode = dll_next (pThisNode)) { pRegSet = (WDB_REG_SET_OBJ *)pThisNode; if (pRegSet->regSetType == type) { (*pRegSet->get) (ppRegs); return (OK); } } return (ERROR); }
static void timer_insert (timer_handle_t _handle) { interrupt_level_t interrupt_level; bucket_t *p_bucket; usize_t count = 0, round, level; timer_handle_t iterator; interrupt_level = global_interrupt_disable (); _handle->bucket_index_ = (g_cursor + _handle->ticks_) % CONFIG_MAX_BUCKET; dll_remove (&g_inactive_timer, &_handle->node_); p_bucket = &g_buckets [_handle->bucket_index_]; round = _handle->ticks_ / CONFIG_MAX_BUCKET; level = ++ p_bucket->level_; p_bucket->reentrance_ ++; redo: iterator = (timer_handle_t) dll_head (&p_bucket->dll_); _handle->round_ = round; for (;;) { if (0 == iterator) { dll_push_tail (&p_bucket->dll_, &_handle->node_); break; } if (_handle->round_ <= iterator->round_) { iterator->round_ -= _handle->round_; dll_insert_before (&p_bucket->dll_, &iterator->node_, &_handle->node_); break; } _handle->round_ -= iterator->round_; iterator = (timer_handle_t) dll_next (&p_bucket->dll_, &iterator->node_); count ++; if (count < CONFIG_INTERRUPT_FLASH_FREQUENCY) { continue; } count = 0; global_interrupt_enable (interrupt_level); // at this moment we give a chance to the higher pirority interrupt // (or task) for being served (or running) interrupt_level = global_interrupt_disable (); if (p_bucket->level_ != level) { level = ++ p_bucket->level_; p_bucket->redo_ ++; goto redo; } } if (g_bucket_firing == p_bucket) { if(0 == g_timer_next || _handle->round_ <= g_timer_next->round_) { g_timer_next = _handle; } } p_bucket->hit_ ++; if (0 == -- p_bucket->reentrance_) { p_bucket->level_ = 0; } _handle->state_ = TIMER_STARTED; global_interrupt_enable (interrupt_level); }
void wdbExcGetEvent ( void * arg, WDB_EVT_DATA * pEvtData ) { wdbExcInfoNode_t * pNode; wdbExcInfoNode_t * pTmpNode; WDB_EXC_INFO * pExcInfo; int lockKey; /* get a node from the exception queue */ lockKey = intLock(); pNode = (wdbExcInfoNode_t *) dll_head (&wdbExcEvtList); dll_remove (&pNode->node); intUnlock (lockKey); /* give the node info to the host */ pExcInfo = (WDB_EXC_INFO *)&pEvtData->eventInfo; pEvtData->evtType = WDB_EVT_EXC; pExcInfo->numInts = 4; pExcInfo->context = pNode->context; pExcInfo->vec = pNode->excVector; pExcInfo->pEsf = (TGT_ADDR_T) pNode->pESF; /* mark the node invalid and put back in queue (after valid nodes) */ pNode->valid = FALSE; lockKey = intLock(); for (pTmpNode = (wdbExcInfoNode_t *) dll_head (&wdbExcEvtList); pTmpNode != (wdbExcInfoNode_t *) dll_end (&wdbExcEvtList); pTmpNode = (wdbExcInfoNode_t *) dll_next (&pTmpNode->node)) { if (pTmpNode->valid == FALSE) break; } pTmpNode = (wdbExcInfoNode_t *) dll_prev (&pTmpNode->node); dll_insert (&pNode->node, &pTmpNode->node); intUnlock (lockKey); }
void wdbBpInstall (void) { dll_t * pDll; #if DBG_HARDWARE_BP DBG_REGS dbgRegs; #endif /* DBG_HARDWARE_BP */ /* don't install system BP's if we are not in system mode */ if (wdbIsNowTasking()) return; #if DBG_HARDWARE_BP memset (&dbgRegs, 0, sizeof (DBG_REGS)); wdbDbgRegsClear (); /* clean debug registers */ #endif /* DBG_HARDWARE_BP */ /* if stepping, just set trace mode */ if (wdbSysBpMode != 0) { #if DBG_NO_SINGLE_STEP wdbSysNpc = wdbDbgGetNpc (&wdbExternSystemRegs); wdbSysNpcInstr = *wdbSysNpc; usrBreakpointSet (wdbSysNpc, DBG_BREAK_INST); #endif /* DBG_NO_SINGLE_STEP */ wdbBpData = wdbDbgTraceModeSet ((REG_SET *) &wdbExternSystemRegs); } else /* if not stepping, insert breakpoints */ { for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { if (BP_BASE(pDll)->bp_task == -1) { if ((BP_BASE(pDll)->bp_flags & BRK_HARDWARE) == 0) usrBreakpointSet (BP_BASE(pDll)->bp_addr, DBG_BREAK_INST); #if DBG_HARDWARE_BP else wdbDbgHwBpSet (&dbgRegs, BP_BASE(pDll)->bp_flags & BRK_HARDMASK, (UINT32) BP_BASE(pDll)->bp_addr); #endif /* DBG_HARDWARE_BP */ BP_BASE(pDll)->bp_flags |= BP_INSTALLED; } } #if DBG_HARDWARE_BP wdbDbgRegsSet (&dbgRegs); /* set debug registers. */ #endif /* DBG_HARDWARE_BP */ } }
void timer_fire () { interrupt_level_t level; timer_handle_t handle; level = global_interrupt_disable (); g_bucket_firing = &g_buckets [g_cursor]; if (0 == dll_size (&g_bucket_firing->dll_)) { // no timer is expired goto out; } handle = (timer_handle_t) dll_head (&g_bucket_firing->dll_); while (0 != handle) { g_statistics.traversed_ ++; g_timer_next = (timer_handle_t) dll_next (&g_bucket_firing->dll_, &handle->node_); if (handle->round_ > 0) { // in this case the timer is still not expired handle->round_ --; break; } else { // hooray, the timer is expired dll_remove (&g_bucket_firing->dll_, &handle->node_); dll_push_tail (&g_inactive_timer, &handle->node_); handle->state_ = TIMER_STOPPED; if (g_bucket_firing->reentrance_ > 0) { g_bucket_firing->level_ ++; } global_interrupt_enable (level); if (TIMER_TYPE_INTERRUPT == handle->type_) { handle->callback_(handle, handle->arg_); } else if (TIMER_TYPE_TASK == handle->type_) { timer_message_send (handle); } level = global_interrupt_disable (); } handle = g_timer_next; } out: g_cursor ++; if (g_cursor > BUCKET_LAST_INDEX) { g_cursor = 0; } g_timer_next = 0; g_bucket_firing = 0; global_interrupt_enable (level);; }
void wdbExcDeqEvent ( void *arg ) { int lockKey; wdbExcInfoNode_t * pNode; lockKey = intLock(); pNode = (wdbExcInfoNode_t *) dll_head (&wdbExcEvtList); if (pNode->valid) { intUnlock (lockKey); wdbEventPost (&wdbExcEvtNode); return; } intUnlock (lockKey); }
void wdbSuspendSystem ( WDB_IU_REGS * pRegs, /* runtime context to save */ void (*callBack)(), /* callback after system is stopped */ int arg /* callback argument */ ) { dll_t * pThisNode; WDB_REG_SET_OBJ * pRegSet; intLock(); wdbSuspendCallbackRtn = callBack; /* install the callback */ wdbSuspendCallbackArg = arg; /* and the callback argument */ wdbState |= WDB_STATE_EXTERN_RUNNING; /* mark extern agent running */ wdbExternEnterHook(); /* call extern enter hook */ (*pWdbExternCommIf->modeSet) /* reset communication stack */ (pWdbExternCommIf->commId, WDB_COMM_MODE_POLL); bcopy ((caddr_t)pRegs, /* save inferior context */ (caddr_t)&wdbExternSystemRegs, sizeof (WDB_IU_REGS)); for (pThisNode = dll_head (&wdbRegSetList); pThisNode != dll_end (&wdbRegSetList); pThisNode = dll_next (pThisNode)) { pRegSet = (WDB_REG_SET_OBJ *)pThisNode; (*pRegSet->save)(); } #if CPU_FAMILY==MC680X0 wdbExternAgentRegs.regSet.sr &= 0xefff; wdbExternAgentRegs.regSet.sr |= (wdbExternSystemRegs.regSet.sr & 0x1000); #endif WDB_CTX_LOAD (&wdbExternAgentRegs); /* run external agent */ /*NOTREACHED*/ }
STATUS wdbVioChannelRegister ( WDB_VIO_NODE * pVioNode ) { WDB_VIO_NODE * pThisNode; int lockKey; for (pThisNode = (WDB_VIO_NODE *)dll_head (&wdbVioDevList); pThisNode != (WDB_VIO_NODE *)dll_end (&wdbVioDevList); pThisNode = (WDB_VIO_NODE *)dll_next (&pThisNode->node) ) { if (pThisNode->channel == pVioNode->channel) return (ERROR); } lockKey = intLock(); dll_insert (&pVioNode->node, &wdbVioDevList); intUnlock (lockKey); return (OK); }
static UINT32 wdbVioWrite ( WDB_MEM_XFER * pMemXfer, UINT32 * pBytesWritten ) { WDB_VIO_NODE * pThisNode; for (pThisNode = (WDB_VIO_NODE *)dll_head (&wdbVioDevList); pThisNode != (WDB_VIO_NODE *)dll_end (&wdbVioDevList); pThisNode = (WDB_VIO_NODE *)dll_next (&pThisNode->node) ) { if (pThisNode->channel == (UINT32)pMemXfer->destination) { *pBytesWritten = (*pThisNode->inputRtn)(pThisNode, pMemXfer->source, pMemXfer->numBytes); return (OK); } } return (WDB_ERR_INVALID_VIO_CHANNEL); }
static UINT32 wdbHwBpAdd ( WDB_EVTPT_ADD_DESC * pBreakPoint, /* breakpoint to add */ UINT32 * pId /* breakpoint ID */ ) { BRKPT * pBp; dll_t * pDll; int status; DBG_REGS dbgRegs; /* debug registers */ int contextId; /* context ID */ UINT32 addr; /* breakpoint address */ UINT32 count = 0; /* breakpoint count */ int type = DEFAULT_HW_BP; /* hardware type */ switch (pBreakPoint->numArgs) { default: case 3: type = pBreakPoint->args[2]; /* FALL THROUGH */ case 2: count = pBreakPoint->args[1]; /* FALL THROUGH */ case 1: addr = pBreakPoint->args[0]; break; case 0: return (WDB_ERR_INVALID_PARAMS); } /* check validity of hardware breakpoint address */ if (wdbDbgHwAddrCheck (addr, type, (FUNCPTR) pWdbRtIf->memProbe) != OK) return (WDB_ERR_MEM_ACCES); /* check the agent mode */ switch (pBreakPoint->context.contextType) { case WDB_CTX_SYSTEM: if (!wdbIsNowExternal()) return (WDB_ERR_AGENT_MODE); break; default: if (!wdbIsNowTasking()) return (WDB_ERR_AGENT_MODE); } /* set the context ID */ switch (pBreakPoint->context.contextType) { case WDB_CTX_SYSTEM: contextId = BP_SYS; break; case WDB_CTX_ANY_TASK: contextId = BP_ANY_TASK; break; case WDB_CTX_TASK: default: contextId = pBreakPoint->context.contextId; } /* clean dbgRegs structure */ memset (&dbgRegs, 0, sizeof (DBG_REGS)); /* fill dbgRegs structure with all hardware breakpoints */ wdbTaskLock (); /* disable task switching */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { pBp = BP_BASE(pDll); /* check if found breakpoint is applicable to new breakpoint context */ if (((contextId == BP_SYS) && (pBp->bp_task == BP_SYS)) || ((contextId == BP_ANY_TASK) && (pBp->bp_task != BP_SYS)) || ((contextId != BP_SYS) && (pBp->bp_task == BP_ANY_TASK))) { if (pBp->bp_flags & BRK_HARDWARE) { if ((status = wdbDbgHwBpSet (&dbgRegs, pBp->bp_flags & BRK_HARDMASK, (UINT32) pBp->bp_addr)) != OK) { wdbTaskUnlock (); /* re-enable task switching */ return (status); } } } } wdbTaskUnlock (); /* re-enable task switching */ if ((status = wdbDbgHwBpSet (&dbgRegs, type, addr)) != OK) return (status); if (dll_empty (&bpFreeList)) return (WDB_ERR_EVENTPOINT_TABLE_FULL); wdbTaskLock (); /* disable task switching */ pBp = BP_BASE(dll_tail (&bpFreeList)); dll_remove (&pBp->bp_chain); wdbTaskUnlock (); /* re-enable task switching */ pBp->bp_flags = BP_HOST | type | BRK_HARDWARE; pBp->bp_addr = (INSTR *)addr; pBp->bp_action = pBreakPoint->action.actionType; pBp->bp_count = count; pBp->bp_callRtn = (void (*)())pBreakPoint->action.callRtn; pBp->bp_callArg = pBreakPoint->action.callArg; pBp->bp_task = contextId; /* * XXX - MS hack because host tools pass wrong info. * XXX - DBT This has been corrected in tornado 2.0 host tools but we * must keep this hack for backward compatibility. */ if ((pBp->bp_action == 0) || (pBp->bp_action == WDB_ACTION_STOP)) pBp->bp_action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY; wdbTaskLock (); /* disable task switching */ dll_insert(&pBp->bp_chain, &bpList); wdbTaskUnlock (); /* re-enable task switching */ if (pBreakPoint->context.contextType != WDB_CTX_SYSTEM) if (_wdbTaskBpAdd != NULL) _wdbTaskBpAdd (pBreakPoint); *pId = (UINT32)pBp; return (WDB_OK); }