Beispiel #1
0
/*
 * task_yield
 * This function is used to yield the current task. This can be called from any
 * task. Depending on task priority the current task will be preempted or
 * continue to run after this is called. This function will also enable
 * interrupts when required.
 */
void task_yield(void)
{
    INT_LVL interrupt_level;
    uint8_t in_isr = FALSE;

    /* If we are in an interrupt. */
    if (current_task == NULL)
    {
        /* Return task should not be null. */
        ASSERT(return_task == NULL);

        /* Pick the return task. */
        current_task = return_task;

        /* We are in an interrupt. */
        in_isr = TRUE;
    }

    /* Check if we can actually yield the current task. */
    if (current_task->lock_count == 0)
    {
        /* Disable interrupts. */
        interrupt_level = GET_INTERRUPT_LEVEL();
        DISABLE_INTERRUPTS();

        /* Re-enqueue/schedule this task in the scheduler. */
        scheduler_task_yield(current_task, YIELD_MANUAL);

        /* Schedule next task and enable interrupts. */
        CONTROL_TO_SYSTEM();

        /* Restore old interrupt level. */
        SET_INTERRUPT_LEVEL(interrupt_level);
    }

    else
    {
        /* Set the flag that we need to process a context switch. */
        current_task->flags |= TASK_SCHED_DRIFT;
    }

    if (in_isr == TRUE)
    {
        /* Save the return task. */
        return_task = current_task;

        /* Clear current task. */
        current_task = NULL;
    }

} /* task_yield */
Beispiel #2
0
/*
 * current_system_tick
 * @return: Current system tick.
 * This function returns the number of system ticks elapsed from the system
 * boot.
 */
uint32_t current_system_tick(void)
{
    uint32_t return_tick;
    INT_LVL interrupt_level = GET_INTERRUPT_LEVEL();

    /* Disable global interrupts. */
    DISABLE_INTERRUPTS();

    /* Atomically save the current system tick. */
    return_tick = current_tick;

    /* Restore old interrupt level. */
    SET_INTERRUPT_LEVEL(interrupt_level);

    /* Return current system tick. */
   return (return_tick);

} /* current_system_tick */
Beispiel #3
0
/*
 * sleep_ticks
 * @ticks: Number of ticks for which this task is needed to sleep.
 * This function sleeps/suspends the current task for the given number of system
 * ticks.
 */
void sleep_ticks(uint32_t ticks)
{
    TASK *tcb;
    uint32_t interrupt_level;

    /* Save the current task pointer. */
    tcb = get_current_task();

    /* Current task should not be null. */
    OS_ASSERT(tcb == NULL);

    /* Interrupts must not be locked. */
    OS_ASSERT(tcb->interrupt_lock_count != 0);

    /* Lock the scheduler. */
    scheduler_lock();

    /* Add current task to the sleep list. */
    sleep_add_to_list(tcb, ticks);

    /* Disable interrupts. */
    interrupt_level = GET_INTERRUPT_LEVEL();
    DISABLE_INTERRUPTS();

    /* Task is being suspended. */
    tcb->status = TASK_SUSPENDED;

    /* Return control to the system.
     * We will resume from here when our required delay has been achieved. */
    CONTROL_TO_SYSTEM();

    /* Restore old interrupt level. */
    SET_INTERRUPT_LEVEL(interrupt_level);

    /* Enable scheduling. */
    scheduler_unlock();

} /* sleep_ticks */
Beispiel #4
0
/*
 * scheduler_task_add
 * @tcb: Task control block that is needed to be added in the system.
 * @priority: Priority for this task.
 * This function adds a task in the system, the task must be initialized before
 * adding.
 */
void scheduler_task_add(TASK *tcb, uint8_t priority)
{
    INT_LVL interrupt_level;

    /* Disable interrupts. */
    interrupt_level = GET_INTERRUPT_LEVEL();
    DISABLE_INTERRUPTS();

    /* Update the task control block. */
    tcb->priority = priority;

    /* Enqueue this task in the ready list. */
    scheduler_task_yield(tcb, YIELD_INIT);

#ifdef TASK_STATS
    /* Append this task to the global task list. */
    sll_append(&sch_task_list, tcb, OFFSETOF(TASK, next_global));
#endif /* TASK_STATS */

    /* Restore old interrupt level. */
    SET_INTERRUPT_LEVEL(interrupt_level);

} /* scheduler_task_add */