/* * 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 */
/* * 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 */