Exemplo n.º 1
0
/*
 *  ======== Semaphore_pendTimeout ========
 *  called by Clock when timeout for a semaphore expires
 */
Void Semaphore_pendTimeout(UArg arg)
{
    UInt hwiKey;
    Semaphore_PendElem *elem = (Semaphore_PendElem *)arg;

    hwiKey = Hwi_disable();

    /* Verify that Semaphore_post() hasn't already occurred */

    if (elem->pendState == Semaphore_PendState_CLOCK_WAIT) {

        /* remove task's qElem from semaphore queue */
        Queue_remove((Queue_Elem *)elem);

        elem->pendState = Semaphore_PendState_TIMEOUT;

        /* 
         *  put task back into readyQ
         *  No need for Task_disable/restore sandwich since this
         *  is called within Swi thread 
         */
        Task_unblockI(elem->tpElem.task, hwiKey);
    }

    Hwi_restore(hwiKey);
}
Exemplo n.º 2
0
/*
 *  ======== Event_pendTimeout ========
 *  called by Clock when timeout for a event expires
 */
Void Event_pendTimeout(UArg arg)
{
    UInt hwiKey;
    Event_PendElem *elem = (Event_PendElem *)xdc_uargToPtr(arg);

    hwiKey = Hwi_disable();

    /*
     *  Verify that Event_post() hasn't already serviced this qElem.
     */
    if (elem->pendState == Event_PendState_CLOCK_WAIT) {

        /* remove eventElem from event_Elem queue */
        Queue_remove((Queue_Elem *)elem);

        elem->pendState = Event_PendState_TIMEOUT;

        /*
         *  put task back into readyQ
         *  No need for Task_disable/restore sandwich since this
         *  is called within Swi (or Hwi) thread
         */
        Task_unblockI(elem->tpElem.task, hwiKey);
    }

    Hwi_restore(hwiKey);
}
Exemplo n.º 3
0
/*
 *  ======== Task_unblock ========
 */
Void Task_unblock(Task_Object *tsk)
{
    UInt hwiKey;

    hwiKey = Hwi_disable();

    Task_unblockI(tsk, hwiKey);

    Hwi_restore(hwiKey);
}
Exemplo n.º 4
0
/*
 *  ======== Event_post ========
 */
Void Event_post(Event_Object *event, UInt eventId)
{
    UInt tskKey, hwiKey;
    Event_PendElem *elem;
    Queue_Handle pendQ;

    Assert_isTrue((eventId != 0), Event_A_nullEventId);

    Log_write3(Event_LM_post, (UArg)event, (UArg)event->postedEvents, (UArg)eventId);

    pendQ = Event_Instance_State_pendQ(event);

    /* atomically post this event */
    hwiKey = Hwi_disable();

    /* or in this eventId */
    event->postedEvents |= eventId;

    /* confirm that ANY tasks are pending on this event */
    if (Queue_empty(pendQ)) {
        Hwi_restore(hwiKey);
        return;
    }

    tskKey = Task_disable();

    /* examine pendElem on pendQ */
    elem = (Event_PendElem *)Queue_head(pendQ);

    /* check for match, consume matching eventIds if so. */
    elem->matchingEvents = Event_checkEvents(event, elem->andMask, elem->orMask);

    if (elem->matchingEvents != 0) {

        /* remove event elem from elem queue */
        Queue_remove((Queue_Elem *)elem);

        /* mark the Event as having been posted */
        elem->pendState = Event_PendState_POSTED;

        /* disable Clock object */
        if (BIOS_clockEnabled && (elem->tpElem.clock != NULL)) {
            Clock_stop(elem->tpElem.clock);
        }

        /* put task back into readyQ */
        Task_unblockI(elem->tpElem.task, hwiKey);
    }

    Hwi_restore(hwiKey);

    /* context switch may occur here */
    Task_restore(tskKey);
}
Exemplo n.º 5
0
/*
 *  ======== Task_sleepTimeout ========
 *  called by Clock when timeout for a Task_sleep() expires
 */
Void Task_sleepTimeout(UArg arg)
{
    UInt hwiKey;
    Task_PendElem *elem = (Task_PendElem *)xdc_uargToPtr(arg);

    hwiKey = Hwi_disable();

    /*
     * put tsk back into readyQ
     * No need for Task_disable/restore sandwich since this
     * is called within Swi (or Hwi) thread
     */
    Task_unblockI(elem->task, hwiKey);

    Hwi_restore(hwiKey);
}
Exemplo n.º 6
0
/*
 *  ======== Semaphore_post ========
 */
Void Semaphore_post(Semaphore_Object *sem)
{
    UInt tskKey, hwiKey;
    Semaphore_PendElem *elem;
    Queue_Handle pendQ;

    /* Event_post will do a Log_write, should we do one here too? */
    Log_write2(Semaphore_LM_post, (UArg)sem, (UArg)sem->count);

    pendQ = Semaphore_Instance_State_pendQ(sem);

    hwiKey = Hwi_disable();

    if (Queue_empty(pendQ)) {
        if (((UInt)sem->mode & 0x1) != 0) {   /* if BINARY bit is set */
            sem->count = 1;
        }
        else {
            sem->count++;
            Assert_isTrue((sem->count != 0), Semaphore_A_overflow);
        }

        Hwi_restore(hwiKey);
        
        if (Semaphore_supportsEvents && (sem->event != NULL)) {
            Semaphore_eventPost(sem->event, sem->eventId);
        }
        return;
    }
    
    /* lock task scheduler */
    tskKey = Task_disable();

    /* dequeue tsk from semaphore queue */
    elem = (Semaphore_PendElem *)Queue_dequeue(pendQ);

    /* mark the Semaphore as having been posted */
    elem->pendState = Semaphore_PendState_POSTED;

    /* put task back into readyQ */
    Task_unblockI(elem->tpElem.task, hwiKey);

    Hwi_restore(hwiKey);

    Task_restore(tskKey);
}
Exemplo n.º 7
0
/*
 *  ======== GateMutexPri_leave ========
 *  Only releases the gate if key == FIRST_ENTER.
 */
Void GateMutexPri_leave(GateMutexPri_Object *obj, IArg key)
{
    UInt tskKey, hwiKey;
    Task_Handle owner;
    Task_Handle newOwner;
    Task_PendElem *elem;
    Queue_Handle pendQ;

    pendQ = GateMutexPri_Instance_State_pendQ(obj);
    
    owner = Task_self();
    
    /* 
     * Prior to tasks starting, Task_self() will return NULL.
     * Simply return here as, by definition, there is
     * is only one thread running at this time.
     */
    if (owner == NULL) {
        return;
    }

    /* 
     * Gate may only be called from task context, so Task_disable is sufficient
     * protection.
     */
    tskKey = Task_disable();
    
    /* Assert that caller is gate owner. */
    // ASSERT(owner == obj->owner);
    
    /* If this is not the outermost call to leave, just return. */
    if (key != FIRST_ENTER) {
        Task_restore(tskKey);
        return;
    }
    
    /* 
     * Restore this task's priority. The if-test is worthwhile because of the
     * cost of a call to setPri.
     */
    if (obj->ownerOrigPri != Task_getPri(owner)) {
        Task_setPri(owner, obj->ownerOrigPri);
    }
    
    /* If the list of waiting tasks is not empty... */
    if (!Queue_empty(pendQ)) {
        
        /* 
         * Get the next owner from the front of the queue (the task with the
         * highest priority of those waiting on the queue). 
         */
        elem = (Task_PendElem *)Queue_dequeue(pendQ);
        newOwner = elem->task;
        
        /* Setup the gate. */
        obj->owner = newOwner;
        obj->ownerOrigPri = Task_getPri(newOwner);
        
        /* Task_unblockI must be called with interrupts disabled. */
        hwiKey = Hwi_disable();
        Task_unblockI(newOwner, hwiKey);
        Hwi_restore(hwiKey);

    }
    /* If the gate is to be posted... */
    else {
        obj->mutexCnt = 1;
    }
    
    Task_restore(tskKey); 
}