Exemple #1
0
int
main(int argc, char **argv)
{
	Timer *timer;
	CLOCK period = { 1, 0 };

	counter = 10;
	if (1 < argc)
		counter = strtol(argv[1], NULL, 10);

	if ((timer = timerCreate(task, NULL, NULL, &period, 0)) == NULL)
		return 1;

	sleep(6);
	timerFree(timer);

	return 0;
}
Exemple #2
0
void clean() {

    cleanMemory();
    freeFileName();
    cmdFree();
    conFree();

#ifndef NO_GUI

    colourSpectrumClear();
    timerFree();

    if (video.sdlStarted) {
        TTF_Quit();
        SDL_Quit();
    }

#endif

}
Exemple #3
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SchedLoop
 *
 *  DESCRIPTION
 *      The main function of the background task scheduler. This
 *      invokes tasks as messages become available for them and
 *      delivers timed event calls.
 *
 *
 *  RETURNS
 *        void
 *
 *----------------------------------------------------------------------------*/
void SchedLoop(void *data)
{
    ThreadInstanceType *thread;
    uint32 eventBits, timeout;
    uint32 eventBitsOther;
    Time now;
    TimerType *timer;
    uint16 i;
    Result result;

    thread = (ThreadInstanceType *) data;

    result = EventWait(&thread->eventHandle, _EVENT_WAIT_INFINITE, &eventBits);
    if (result != _RESULT_SUCCESS) {
    //    Panic(_TECH_FW, _PANIC_FW_UNEXPECTED_VALUE, "Event wait failed");
    }
    eventBitsOther = (eventBits & ~START_EVENT);
    if (eventBitsOther) {
        /* If thread is signalled from another thread, by a message put,
         * then pass this signal to our self. */
        EventSet(&thread->eventHandle, eventBitsOther);
    }

    /* make sure the Sched loop continues until interrupted */
    thread->schedRunning = TRUE;

    /* Tasks' initialisation functions. */
    for (i = 0; i < thread->numberOfTasks; i ++) {
        thread->currentTask = (Task) (i | (thread->id << _SCHED_QUEUE_SEGMENT_SHIFT));

        if (thread->tasks[i].initFunction) {
            thread->tasks[i].initFunction(&(thread->tasks[i].instanceDataPointer));
        }
        thread->currentTask = _SCHED_TASK_ID;
    }

    i = 0;
    while (thread->schedRunning) {
        if (thread->pendingMessages > 0) {
            /* Consider each task in turn. */
            while (1) {
                TaskDefinitionType *task;

                if (i >= thread->numberOfTasks) {
                    i = 0;
                }

                task = &thread->tasks[i];
                if (task->messageQueueFirst) {
                    thread->currentTask = (int) (i | (thread->id << _SCHED_QUEUE_SEGMENT_SHIFT));

                    task->handlerFunction(&(task->instanceDataPointer));

                    thread->currentTask = _SCHED_TASK_ID;
                    i++;
                    break;
                }
                else {
                    i++;
                }
            }
        }

        /* if no internal messages wait for external event or a timer to to expire */
        if (thread->pendingMessages == 0) {
            /* Currently there is no messages on any of the Scheduler
               task queues. Wait for a timer or an external event to occur */
            if (thread->timerList != NULL) {
                now = TimeGet(NULL);
                if (thread->timerList->wrapCount > thread->currentWrapCount) {
                    timeout = (_SCHED_TIME_MAX - now + thread->timerList->when);
                    /* Avoid rounding to zero in division below. */
                    timeout += 999;
                }
                else {
                    if (now < thread->timerList->when) {
                        timeout = TimeSub(thread->timerList->when, now);
                        /* Avoid rounding to zero in division below. */
                        timeout += 999;
                    }
                    else {
                        timeout = 0;
                    }
                }
                timeout /= 1000;
                if (timeout >= _EVENT_WAIT_INFINITE) {
                    timeout = _EVENT_WAIT_INFINITE - 1;
                }
            }
            else {
                timeout = _EVENT_WAIT_INFINITE;
            }
        }
        else {
            timeout = 0;
        }
        if (EventWait(&thread->eventHandle, (uint16) timeout, &eventBits) == _RESULT_SUCCESS) {
            /* background interrupt */
            SchedBgint vector;

            vector = (SchedBgint) (eventBits & BG_INT_MASK);

            /* Are any background interrupts set? */
            if (vector) {
                uint32 j;

                j = 0;

                do {
                    BgIntType *bgint;

                    bgint = &instance->bgint[j];

                    /* Check if this bgint is set */
                    if (vector & bgint->eventBit) {
                        /* Clear the bit so the bgint is accounted for. */
                        vector &= ~bgint->eventBit;

                        thread->currentTask = bgint->qid;

                        bgint->handler(bgint->arg);

                        thread->currentTask = _SCHED_TASK_ID;
                    }

                    j++;
                } while (vector);
            }

            /* a message arriving from outside */
            if (EXT_MSG_EVENT & eventBits) {
                SchedTaskId qi;
                MessageQueueEntryType *message;

                MutexLock(&thread->qMutex);

                while (thread->extMsgQueueFirst != NULL) {
                    /* remove from ext queue */
                    message = thread->extMsgQueueFirst;
                    thread->extMsgQueueFirst = message->next;
                    message->next = NULL;

                    qi = message->receiver;

                    /* ...store the on the end of the task's message chain. */
                    if (thread->tasks[qi].messageQueueLast == NULL) {
                        thread->tasks[qi].messageQueueFirst = message;
                        thread->tasks[qi].messageQueueLast = message;
                    }
                    else {
                        thread->tasks[qi].messageQueueLast->next = message;
                        thread->tasks[qi].messageQueueLast = message;
                    }
                    thread->pendingMessages++;
                }

                /* At this point the external queue is empty. */
                thread->extMsgQueueLast = NULL;

                MutexUnlock(&thread->qMutex);
            }
            /* a sched stop req */
            if (STOP_REQ_EVENT & eventBits) {
                /* return stop cfm and break out of scheduler loop */
                thread->schedRunning = FALSE;
                EventSet(&instance->eventHandle, STOP_CFM_EVENT | (0x0001 << (uint32) thread->id));
                break;
            }
        }

        while (thread->timerList) {
            /* Now, back to timed events. */
            now = TimeGet(NULL);
            /* Handle timer wrap */
            adjust_wrap_count(thread, now);

            if (thread->timerList->wrapCount > thread->currentWrapCount) {
                /* The earliest deadline is more than 1 wrapCount in the future. */
                break;
            }
            else {
                if ((thread->timerList->when > now) &&
                    (thread->timerList->wrapCount == thread->currentWrapCount)) {
                    break;
                }
                else {
                    /* Run the timed event function. */
                    timer = thread->timerList;
                    timer->active = FALSE;

                    thread->timerList = timer->next;
                    if (thread->timerList != NULL) {
                        thread->timerList->prev = NULL;
                    }

                    thread->currentTask = timer->queue;

                    timer->eventFunction(timer->id, timer->fniarg, timer->fnvarg);

                    thread->currentTask = _SCHED_TASK_ID;

                    timerFree(thread, timer);
                }
            }
        }
    } /*  while (thread->schedRunning) */

    /* wait for deinit req event */
    while (1) {
        eventBits = 0;
        result = EventWait(&thread->eventHandle, _EVENT_WAIT_INFINITE, &eventBits);
        if ((result == _RESULT_SUCCESS) && (DEINIT_REQ_EVENT & eventBits)) {
            SchedTaskId qi;
            MessageQueueEntryType *message;

            /*
             * Pull any messages off the external queue and
             * put them on the relevant task queue. These may
             * be put here after we stopped because the sender
             * had not received its stop event yet.
             */
            while (thread->extMsgQueueFirst != NULL) {
                /* remove from ext queue */
                message = thread->extMsgQueueFirst;
                thread->extMsgQueueFirst = message->next;
                message->next = NULL;

                qi = message->receiver;

                /* ...store the on the end of the task's message chain. */
                if (thread->tasks[qi].messageQueueLast == NULL) {
                    thread->tasks[qi].messageQueueFirst = message;
                    thread->tasks[qi].messageQueueLast = message;
                }
                else {
                    thread->tasks[qi].messageQueueLast->next = message;
                    thread->tasks[qi].messageQueueLast = message;
                }
                thread->pendingMessages++;
            }

            /* deinit all tasks in this scheduler thread and
             * return deinit cfm */
            SchedInstanceTaskDeinit(thread);
            EventSet(&instance->eventHandle, DEINIT_CFM_EVENT | (0x0001 << (uint32) thread->id));
            return;
        }
        else if (result != _RESULT_SUCCESS) {
            GENERROR(("Failure in wait for thread deinit req"));
            return;
        }
    }
}
Exemple #4
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SchedTimerCancel
 *
 *  DESCRIPTION
 *      Attempts to prevent the timer with identifier "eventid" from
 *      occurring.
 *
 *  RETURNS
 *      BOOL - true if cancelled, false if the event has already occurred.
 *
 *----------------------------------------------------------------------------*/
bool SchedTimerCancel(SchedTid tid,
    uint16 *pmi,
    void **pmv)
{
    bool rv;

    if (tid != _SCHED_TID_INVALID) {
        uint8 index;

        index = GetThreadIndex();
        if (index < _SCHED_MAX_SEGMENTS) {
            ThreadInstanceType *thread;
            TimerType *timer;

            thread = &instance->thread[index];

            /* Unlink the timer from the list. */
            timer = thread->timer[tid];

            if (timer && timer->active) {
                TimerType *prev, *next;

                timer->active = FALSE;
                rv = TRUE;

                prev = timer->prev;
                next = timer->next;

                if ((prev != NULL) && (next != NULL)) {
                    /* In the middle of the list. */

                    next->prev = prev;
                    prev->next = next;
                }
                else if ((prev == NULL) && (next != NULL)) {
                    /* Removing the list head. */

                    thread->timerList = next;
                    next->prev = NULL;
                }
                else if ((prev != NULL) && (next == NULL)) {
                    /* Removing the list tail. */
                    prev->next = NULL;
                }
                else {
                    /* Removing the only active timer. */
                    thread->timerList = NULL;
                }

                if (pmi != NULL) {
                    *pmi = timer->fniarg;
                }
                if (pmv != NULL) {
                    *pmv = timer->fnvarg;
                }

                timerFree(thread, timer);
            }
            else {
                rv = FALSE;
            }
        }
        else {
            rv = FALSE;
       //     Panic(_TECH_FW, _PANIC_FW_UNEXPECTED_VALUE,
       //         "SchedTimerCancel not called from scheduler thread");
        }
    }
    else {
        rv = FALSE;
    }

    return rv;
}