Beispiel #1
0
// WHERE: 0 <= start && start < strlen(s);
// EFFECT: for each member m of tn that matches s[start,)
// add the concatenation of sb and m to q
// DETAILS: the sb should have the same string as before afetr
// the function returns
void tnode_lookup_generalized(tnode *tn, char *s, size_t start,
                              struct strbuf *sb, Queue q) {
  REQUIRES(is_tnode(tn));
  REQUIRES(s != NULL && 0 <= start && start < strlen(s));
  REQUIRES(is_strbuf(sb));
  REQUIRES(is_Queue(q));

  if (s[start] == '*') {
    if (tn == NULL) return;
    tnode_lookup_generalized(tn->left, s, start, sb, q);
    tnode_lookup_generalized(tn->right, s, start, sb, q);

    if (s[start + 1] == '\0' && tn->is_end) {
      strbuf_push(sb, s[start]);
      Queue_insert(q, strbuf_str(sb));
      strbuf_pop(sb);
      return;
    } else if (s[start + 1] == '\0') {
      tnode_lookup_generalized(tn->middle, s, start, sb, q);
    } else {
      ASSERT(s[start + 1] != '\n');
      strbuf_push(sb, s[start]);
      tnode_lookup_generalized(tn->middle, s, start, sb, q);
      tnode_lookup_generalized(tn->middle, s, start + 1, sb, q);
      strbuf_pop(sb);
    }
  } else {
    if (tn == NULL) return;
    if (s[i] < tn->c) {
      tnode_lookup_generalized(T->left, s, i, sb, q);
      return;
    } else if (s[i] > tn->c) {
      tnode_lookup_generalize(T->right, s, i, sb, q);
      return;
    } else if (s[i+1] == '\0') {
      strbuf_push(sb, s[i]);
      Queue_insert(q, sb);
      strbuf_pop(sb);
      return;
    }

    tnode_lookup(T->middle, s, i+1);
  }

  ENSURES(is_Queue(q));
}
Beispiel #2
0
/*
 *  ======== GateMutexPri_insertPri ========
 *  Inserts the element in order by priority, with higher priority
 *  elements at the head of the queue.
 */
Void GateMutexPri_insertPri(Queue_Object* queue, Queue_Elem* newElem, Int newPri)
{
    Queue_Elem* qelem;
    
    /* Iterate over the queue. */
    for (qelem = Queue_head(queue); qelem != (Queue_Elem *)queue; 
         qelem = Queue_next(qelem)) {
        /* Tasks of equal priority will be FIFO, so '>', not '>='. */
        if (newPri > Task_getPri((Task_Handle)qelem)) {
            /* Place the new element in front of the current qelem. */
            Queue_insert(qelem, newElem);
            return;
        }
    }
    
    /*
     * Put the task at the back of the queue if:
     *   1. The queue was empty.
     *   2. The task had the lowest priority in the queue.
     */
    Queue_enqueue(queue, newElem);
}
Beispiel #3
0
/*
 *  ======== Semaphore_pend ========
 */
Bool Semaphore_pend(Semaphore_Object *sem, UInt timeout)
{
    UInt hwiKey, tskKey;
    Semaphore_PendElem elem;
    Queue_Handle pendQ;
    Clock_Struct clockStruct;

    Log_write3(Semaphore_LM_pend, (IArg)sem, (UArg)sem->count, (IArg)((Int)timeout));

    /*
     *  Consider fast path check for count != 0 here!!!
     */

    /* 
     *  elem is filled in entirely before interrupts are disabled.
     *  This significantly reduces latency.
     */

    /* add Clock event if timeout is not FOREVER nor NO_WAIT */
    if (BIOS_clockEnabled
            && (timeout != BIOS_WAIT_FOREVER) 
            && (timeout != BIOS_NO_WAIT)) {
        Clock_Params clockParams;
        Clock_Params_init(&clockParams);
        clockParams.arg = (UArg)&elem;
        clockParams.startFlag = FALSE;  /* will start when necessary, thankyou */
        Clock_construct(&clockStruct, (Clock_FuncPtr)Semaphore_pendTimeout, 
                                        timeout, &clockParams);
        elem.tpElem.clock = Clock_handle(&clockStruct);
        elem.pendState = Semaphore_PendState_CLOCK_WAIT;
    }
    else {
        elem.tpElem.clock = NULL;
        elem.pendState = Semaphore_PendState_WAIT_FOREVER;
    }

    pendQ = Semaphore_Instance_State_pendQ(sem);

    hwiKey = Hwi_disable();

    /* check semaphore count */
    if (sem->count == 0) {

        if (timeout == BIOS_NO_WAIT) {
            Hwi_restore(hwiKey);
            return (FALSE);
        }

        Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task),
                        Semaphore_A_badContext);

        /* lock task scheduler */
        tskKey = Task_disable();

        /* get task handle and block tsk */
        elem.tpElem.task = Task_self();

        /* leave a pointer for Task_delete() */
        elem.tpElem.task->pendElem = (Task_PendElem *)&(elem);

        Task_blockI(elem.tpElem.task);

        if (((UInt)sem->mode & 0x2) != 0) {    /* if PRIORITY bit is set */
            Semaphore_PendElem *tmpElem;
            Task_Handle tmpTask;
            UInt selfPri;
            
            tmpElem = Queue_head(pendQ);
            selfPri = Task_getPri(elem.tpElem.task);

            while (tmpElem != (Semaphore_PendElem *)pendQ) {
                tmpTask = tmpElem->tpElem.task;
                /* use '>' here so tasks wait FIFO for same priority */
                if (selfPri > Task_getPri(tmpTask)) {
                    break;
                }
                else {
                    tmpElem = Queue_next((Queue_Elem *)tmpElem);
                }
            }
            
            Queue_insert((Queue_Elem *)tmpElem, (Queue_Elem *)&elem);
        }
        else {      
            /* put task at the end of the pendQ */
            Queue_enqueue(pendQ, (Queue_Elem *)&elem);
        }

        /* start Clock if appropriate */
        if (BIOS_clockEnabled && 
                (elem.pendState == Semaphore_PendState_CLOCK_WAIT)) {
            Clock_startI(elem.tpElem.clock);
        }

        Hwi_restore(hwiKey);

        Task_restore(tskKey);   /* the calling task will block here */

        /* Here on unblock due to Semaphore_post or timeout */

        if (Semaphore_supportsEvents && (sem->event != NULL)) {
            /* synchronize Event state */
            hwiKey = Hwi_disable();
            Semaphore_eventSync(sem->event, sem->eventId, sem->count);
            Hwi_restore(hwiKey);
        }

        /* deconstruct Clock if appropriate */
        if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) {
            Clock_destruct(Clock_struct(elem.tpElem.clock));
        }

        elem.tpElem.task->pendElem = NULL;

        return ((Bool)(elem.pendState));
    }
    else {
        --sem->count;

        if (Semaphore_supportsEvents && (sem->event != NULL)) {
            /* synchronize Event state */
            Semaphore_eventSync(sem->event, sem->eventId, sem->count);
        }

        Hwi_restore(hwiKey);

        /* deconstruct Clock if appropriate */
        if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) {
            Clock_destruct(Clock_struct(elem.tpElem.clock));
        }

        return (TRUE);
    }
}
/*
 *  ======== Task_setPri ========
 */
UInt Task_setPri(Task_Object *tsk, Int priority)
{
    Int oldPri;
    UInt newMask, tskKey, hwiKey;
    Queue_Handle newQ;

    Assert_isTrue((((priority == -1) || (priority > 0) ||
                  ((priority == 0 && Task_module->idleTask == NULL))) &&
                   (priority < (Int)Task_numPriorities)),
                   Task_A_badPriority);

    Log_write4(Task_LM_setPri, (UArg)tsk, (UArg)tsk->fxn,
                       (UArg)tsk->priority, (UArg)priority);

    tskKey = Task_disable();
    hwiKey = Hwi_disable();

    oldPri = tsk->priority;

    if (oldPri == priority) {
        Hwi_restore(hwiKey);
        Task_restore(tskKey);
        return (oldPri);
    }

    if (priority < 0) {
        newMask = 0;
        newQ = Task_Module_State_inactiveQ();
    }
    else {
        newMask = 1 << priority;
        newQ = (Queue_Handle)((UInt8 *)(Task_module->readyQ) +
                (UInt)(priority*(2*sizeof(Ptr))));
    }

    if (tsk->mode == Task_Mode_READY) {
        Queue_remove((Queue_Elem *)tsk);

        /* if last task in readyQ, remove corresponding bit in curSet */
        if (Queue_empty(tsk->readyQ)) {
            Task_module->curSet &= ~tsk->mask;
        }

        if (Task_module->curTask == tsk) {
            Task_module->curQ = newQ;   /* force a Task_switch() */
                                        /* if no longer maxQ */
            /* Put current task at front of its new readyQ */
            Queue_insert(((Queue_Elem *)(newQ))->next, (Queue_Elem *)tsk);
        }
        else {
            /* place task at end of its readyQ */
            Queue_enqueue(newQ, (Queue_Elem *)tsk);
        }

        Task_module->curSet |= newMask;
    }

    tsk->priority = priority;
    tsk->mask = newMask;
    tsk->readyQ = newQ;

    if (priority < 0) {
        Task_module->curQ = NULL;   /* force a Task_switch() */
    }

    Task_module->workFlag = 1;

    Hwi_restore(hwiKey);
    Task_restore(tskKey);

    return oldPri;
}