Exemple #1
0
error_t timer_free (timer_handle_t _handle)
{
    interrupt_level_t level;

    level = global_interrupt_disable ();
    if (is_invalid_handle (_handle)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_FREE_INVHANDLE);
    }
    if (TIMER_STARTED == _handle->state_) {
        timer_handle_t next;
        bucket_t *p_bucket = &g_buckets [_handle->bucket_index_];

        if (g_timer_next == _handle) {
            g_timer_next = (timer_handle_t) dll_next (&g_bucket_firing->dll_,
                           &_handle->node_);
        }
        next = (timer_handle_t)dll_next (&p_bucket->dll_, &_handle->node_);
        if (0 != next) {
            next->round_ += _handle->round_;
        }
        dll_remove (&p_bucket->dll_, &_handle->node_);
        if (p_bucket->reentrance_ > 0) {
            g_bucket_firing->level_ ++;
        }
    }
    else {
        dll_remove (&g_inactive_timer, &_handle->node_);
    }
    _handle->magic_number_ = 0;
    dll_push_tail (&g_free_timer, &_handle->node_);
    global_interrupt_enable (level);

    return 0;
}
Exemple #2
0
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 dll_removeAll(HeadNode* hn)
{
    while( hn->size > 0 )
    {
	dll_remove(hn, 0);
    }
}
Exemple #4
0
static int rem_deleted_entries(int queue_id)
{
	TIMR_ENT *auxp, *prevp, *queue_head;
	int n;

	DISABLE_AST
	queue_head = timer_queues[queue_id].queue_head;
	n = timer_queues[queue_id].remove_entries;
	if(queue_head)
	{
		auxp = queue_head;
		prevp = auxp;
		while( (auxp = (TIMR_ENT *)dll_get_next((DLL *)queue_head, (DLL *)auxp)) )
		{
			if(auxp->time == -1)
			{
				dll_remove(auxp);
				free(auxp);
				auxp = prevp;
				n--;
				if(!n)
					break;
			}
			else
				prevp = auxp;
		}
	}
	ENABLE_AST;
	return(1);
}
Exemple #5
0
int main4(int argc, char **argv) {
	jlg_init();
	JLG_DEBUG_ON();
	JLG_LOG("starting");
	
	double_linked_list_t list;
	
	dll_create(&list);
	dll_push(&list, "coucou");
	dll_node_t *coucou_nodep = list.nodep;
	dll_push(&list, "hello");
	dll_push(&list, "salut");

	dll_node_t *nodep = list.nodep;
	while (nodep) {
		JLG_DEBUG("value = %s", (char *) nodep->valuep);
		nodep = nodep->nextp;
	}
	
	dll_remove(&list, coucou_nodep);
	
	void *buffer = NULL;
	while (dll_pop(&list, &buffer) != EODLL) {
		JLG_DEBUG("item = %s", (char *) buffer);
	}

//cleanup:
	return JLG_RETURN_CODE;
}
Exemple #6
0
int hash_remove(hash_t *hashp, char *key) {
	hash_key_t md = hash_compute_md(hashp, key);
	if (hashp->array[md] == NULL) {
		return HASH_ERR_NOT_FOUND;
	}
	ll_node_t *nodep = hashp->array[md]->first;
	ll_node_t *previous_nodep = NULL;
	while (nodep) {
		hash_pair_t *pairp = (hash_pair_t *) nodep->valuep;
		if (EQUALS(key, pairp->key)) {
			hashp->cfg->free_func(pairp->value);
			free(pairp->key);
			// remove this node from the linked list
			if (previous_nodep) {
				previous_nodep->nextp = nodep->nextp;
			} else {
				hashp->array[md]->first = nodep->nextp;
			}
			// remove this node from the double linked list as well
			dll_remove(hashp->dlistp, pairp->nodep);
			JLG_FREE(&(pairp->nodep));
			JLG_FREE(&pairp);
			
			return 0;
		}
		previous_nodep = nodep;
		nodep = nodep->nextp;
	}
	return HASH_ERR_NOT_FOUND;
}
Exemple #7
0
void main(void){
	int arr[]={1,2,3,4,5,6,7,8,9};
	int len=sizeof(arr)/sizeof(arr[0]);
	Node *list=create_list(arr,len);
	char *str;
	str=to_str(list,len);
	printf("%s\n",str);
	int rst=dll_remove(list,list->fwd->fwd);
	str=to_str(list,len);
	printf("%s\n",str);	
}
Exemple #8
0
void wdbVioChannelUnregister
    (
    WDB_VIO_NODE *	pVioNode
    )
    {
    int lockKey;

    lockKey = intLock();
    dll_remove (&pVioNode->node);
    intUnlock (lockKey);
    }
dll_node_t *dllht_pop_entry (const dllht_t *_p_dllht, void *_key, usize_t _key_length)
{
    usize_t index = _p_dllht->key_calc_func_ (_key, _key_length);

    dll_node_t *p_node = dll_traverse (&_p_dllht->buckets_[index].dll_, 
        _p_dllht->compare_func_, _key);

    if (0 != p_node)
        dll_remove (&_p_dllht->buckets_[index].dll_, p_node);
    
    return p_node;
}
Exemple #10
0
int main(void) {
	A* a = malloc(sizeof(A)), *b = malloc(sizeof(A)), *c = NULL;
	List* l = list_init();
	Stack* s = stack_init();
	Queue* q = queue_init();
	DoubleLinkedList* d = dll_init();
	printf("a: %d\nB: %d\nc: %d\n", (int)a, (int)b, (int)c);
	a->a1 = 1;
	a->a2 = 'c';
	b->a1 = 2;
	b->a2 = 'a';

	printf("\n=== LIST TEST ===\n");
	list_add(l, a, 0);
	list_append(l, b);
	list_remove(l, 0);
	list_print(l);	
	c = list_get(l, 0);
	printf("c: %d\n", (int)c);
	list_delete(l);

	printf("\n=== STACK TEST ===\n");
	stack_push(s, b);
	stack_push(s, a);
	stack_pop(s);
	stack_print(s);
	c = stack_peek(s);
	printf("c: %d\n", (int)c);
	stack_delete(s);

	printf("\n=== QUEUE TEST ===\n");
	queue_push(q, a);
	queue_push(q, b);
	queue_pop(q);
	queue_print(q);
	c = queue_peek(q);
	printf("c: %d\n", (int)c);
	queue_delete(q);

	printf("\n=== DOUBLE LINKED LIST TEST ===\n");
	dll_add(d, b, 0);
	dll_prepend(d, a);
	dll_remove(d, 1);
	dll_print(d);
	c = dll_get(d, 0);
	printf("c: %d\n", (int)c);
	dll_delete(d);

	free(a);
	free(b);
	return 0;
}
Exemple #11
0
error_t timer_stop (timer_handle_t _handle, msecond_t *_p_remained)
{
    interrupt_level_t level;
    timer_handle_t next;
    bucket_t *p_bucket;

    level = global_interrupt_disable ();
    if (is_invalid_handle (_handle)) {
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_STOP_INVHANDLE);
    }
    if (_handle->state_ != TIMER_STARTED) {
        g_statistics.abnormal_ ++;
        global_interrupt_enable (level);
        return ERROR_T (ERROR_TIMER_STOP_INVSTATE);
    }

    if (g_timer_next == _handle) {
        g_timer_next = (timer_handle_t) dll_next (&g_bucket_firing->dll_,
                       &_handle->node_);
    }
    p_bucket = &g_buckets [_handle->bucket_index_];
    if (_p_remained != null) {
        timer_remained_t remained = {_handle, 0};

        (void) dll_traverse (&p_bucket->dll_, timer_calculate_remained, &remained);
        *_p_remained = remained.remained_round_ * CONFIG_MAX_BUCKET;
        if (g_cursor > _handle->bucket_index_) {
            *_p_remained = (*_p_remained) * CONFIG_MAX_BUCKET -
                           (g_cursor - _handle->bucket_index_);
        }
        else {
            *_p_remained = (*_p_remained - 1) * CONFIG_MAX_BUCKET +
                           (g_cursor - _handle->bucket_index_) + 1;
        }
        *_p_remained *= CONFIG_TICK_DURATION_IN_MSEC;
    }
    _handle->state_ = TIMER_STOPPED;
    next = (timer_handle_t)dll_next (&p_bucket->dll_, &_handle->node_);
    if (0 != next) {
        next->round_ += _handle->round_;
    }
    dll_remove (&p_bucket->dll_, &_handle->node_);
    dll_push_tail (&g_inactive_timer, &_handle->node_);
    if (p_bucket->reentrance_ > 0) {
        p_bucket->level_ ++;
    }
    global_interrupt_enable (level);

    return 0;
}
Exemple #12
0
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);;
}
Exemple #13
0
static void wdbExcHook
    (
    WDB_CTX	context,
    u_int	vec,
    char *	pESF,
    WDB_IU_REGS	* pRegs
    )
    {
    wdbExcInfoNode_t *	pExcInfoNode;
    int			lockKey;

    /* get a node off the queue */

    lockKey = intLock();
    pExcInfoNode = (wdbExcInfoNode_t *)dll_tail (&wdbExcEvtList);

    /* if event list if full and this is a task exception, just return */

    if ((pExcInfoNode->valid) && (context.contextType == WDB_CTX_TASK))
	{
	intUnlock (lockKey);
	return;
	}

    pExcInfoNode->valid     = TRUE;
    pExcInfoNode->context   = context;
    pExcInfoNode->excVector = vec;
    pExcInfoNode->pESF	    = pESF;

    dll_remove (&pExcInfoNode->node);
    dll_insert (&pExcInfoNode->node, &wdbExcEvtList);
    intUnlock (lockKey);

    /* exception in task context */

    if (wdbIsNowTasking())
	{
	wdbEventPost (&wdbExcEvtNode);
	return;
	}

    /* exception in system context - suspend system before posting event */

    wdbSuspendSystem (pRegs, wdbEventPost, (int)&wdbExcEvtNode);

    /* NOTREACHED */
    }
Exemple #14
0
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);
    }
Exemple #15
0
int dtq_rem_entry(int queue_id, TIMR_ENT *entry)
{
	int time_left, deltat = 0;

	DISABLE_AST
	deltat = get_elapsed_time();
	time_left = entry->time_left - deltat;
	if( Inside_ast ) 
	{
		timer_queues[queue_id].remove_entries++;
		entry->time = -1;
		ENABLE_AST
		return(time_left);
	}
	dll_remove(entry);
	free(entry);

	ENABLE_AST
	return(time_left);
}
Exemple #16
0
int dtq_delete(int queue_id)
{
	TIMR_ENT *queue_head, *entry;

	DISABLE_AST
	queue_head = timer_queues[queue_id].queue_head;
	if(queue_head)
	{
		while(!dll_empty((DLL *)queue_head))
		{
			entry = queue_head->next;
			dll_remove(entry);
			free(entry);
		}
		free(queue_head);
		timer_queues[queue_id].queue_head = 0;
	}
	ENABLE_AST
	return(1);			
}
Exemple #17
0
int main(int argc, char *argv[]) {

  dllist_t *list = (dllist_t*) malloc(sizeof(dllist_t));
  dll_init(list);
  dll_print(list);

  dll_add(list, 12);
  dll_print(list);

  dll_add(list, 12);
  dll_add(list, 13);
  dll_add(list, 14);
  dll_print(list);
  
  dll_remove(list, 12);
  dll_print(list);

  dll_delete(list);
  free(list);
  return 0;
}
Exemple #18
0
int main()
{
    chk_msg("dll_init");
    dll_t list;
    dll_init(&list);
    chk_dll_size(&list, 0);

    chk_msg("dll_push_back");
    dll_push_back(&list);
    chk_dll_size(&list, 1);

    chk_msg("dll_push_front");
    dll_push_front(&list);
    chk_dll_size(&list, 2);

    chk_msg("dll_destroy");
    dll_destroy(&list);
    chk_dll_size(&list, 0);

    chk_msg("dll_push_front");
    dll_push_front(&list);
    chk_dll_size(&list, 1);

    chk_msg("dll_pop_back");
    dll_pop_back(&list);
    chk_dll_size(&list, 0);

    chk_msg("dll_destroy");
    dll_destroy(&list);
    chk_dll_size(&list, 0);

    chk_msg("dll_destroy");
    dll_destroy(&list);
    chk_dll_size(&list, 0);

    chk_msg("dll_push_back");
    dll_item_t *item = dll_push_back(&list);
    chk_dll_size(&list, 1);

    chk_msg("dll_insert_before");
    item = dll_insert_before(&list, item);
    chk_dll_size(&list, 2);

    chk_msg("dll_insert_after");
    item = dll_insert_after(&list, item);
    chk_dll_size(&list, 3);

#if TRIGGER_INV_BUG
    chk_msg("dll_remove");
    dll_remove(&list, dll_next(dll_prev(dll_prev(dll_end(&list)))));
    chk_dll_size(&list, 2);
#endif

    chk_msg("dll_pop_front");
    dll_pop_front(&list);
    chk_dll_size(&list, 1);

#if TRIGGER_INV_BUG
    chk_msg("dll_remove");
    dll_remove(&list, dll_beg(&list));
    chk_dll_size(&list, 0);
#endif

    ___sl_plot(NULL);

    return 0;
}
Exemple #19
0
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);
    }
Exemple #20
0
static UINT32 wdbBpAdd
    (
    WDB_EVTPT_ADD_DESC *	pBreakPoint,
    UINT32 *			pId
    )
    {
    INSTR	val;
    BRKPT *	pBp;
    INSTR *	addr;

    switch (pBreakPoint->numArgs)
	{
	default:
	case 1:
#if ((CPU_FAMILY == ARM) && ARM_THUMB)
	    addr = (INSTR *) ((UINT32)((pBreakPoint->args[0]) & ~1));
#else /* CPU_FAMILY == ARM */
	    addr = (INSTR *) pBreakPoint->args[0];
#endif /* CPU_FAMILY == ARM */
	    break;
	case 0:
	    return (WDB_ERR_INVALID_PARAMS);
	}

    /* check validity of breakpoint address */

    TEXT_UNLOCK(addr);

    if (((*pWdbRtIf->memProbe) ((char *)addr, VX_READ,
				sizeof(INSTR), (char *)&val) != OK) ||
        ((*pWdbRtIf->memProbe) ((char *)addr, VX_WRITE,
				sizeof(INSTR), (char *)&val) != OK))
	{
	TEXT_LOCK(addr);
        return (WDB_ERR_MEM_ACCES);
	}

    TEXT_LOCK(addr);

    /* 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);
	}



    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;
    pBp->bp_addr = addr;
    pBp->bp_action = pBreakPoint->action.actionType;
#if ((CPU_FAMILY == ARM) && ARM_THUMB)
    pBp->bp_callRtn = (void (*)())((UINT32)pBreakPoint->action.callRtn | 1);
#else /* CPU_FAMILY == ARM */
    pBp->bp_callRtn = (void (*)())pBreakPoint->action.callRtn;
#endif /* CPU_FAMILY == ARM */
    pBp->bp_callArg = pBreakPoint->action.callArg;
    pBp->bp_instr = *(INSTR *)addr;

    if (pBreakPoint->numArgs > 1)	/* second argument is count */
   	pBp->bp_count = pBreakPoint->args[1];
    else
   	pBp->bp_count = 0;

    /* XXX - hack because host tools pass wrong info */

    if ((pBp->bp_action == 0) || (pBp->bp_action == WDB_ACTION_STOP))
	pBp->bp_action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY;

    /* set the context ID */

    switch (pBreakPoint->context.contextType)
        {
        case WDB_CTX_SYSTEM:
	    pBp->bp_task = BP_SYS;
            break;
        case WDB_CTX_ANY_TASK:
	    pBp->bp_task = BP_ANY_TASK;
            break;
        case WDB_CTX_TASK:
        default:
	    pBp->bp_task = pBreakPoint->context.contextId;
        }

    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);
    }