Exemple #1
0
static void signal_default(struct task *current, int signum)
{
    /* Init ignores every signal */
    if (current->pid == 1)
        return ;

    switch (signum) {
    case SIGCHLD:
    case SIGCONT:
    case SIGWINCH:
        /* Ignore */
        break;

    case SIGSTOP:
    case SIGTSTP:
    case SIGTTIN:
    case SIGTTOU:
        kp(KP_TRACE, "task %d: Handling stop (%d)\n", current->pid, signum);
        current->ret_signal = TASK_SIGNAL_STOP | signum;
        current->state = TASK_STOPPED;

        if (current->parent)
            scheduler_task_wake(current->parent);

        scheduler_task_yield();
        break;

    default:
        current->ret_signal = signum;
        sys_exit(0);
    }
}
Exemple #2
0
static int packet_process_thread(void *p)
{
    while (1) {
        using_spinlock(&packet_queue_lock) {
            kp(KP_NORMAL, "packet-queue awake\n");

            while (!list_empty(&packet_queue)) {
                struct packet *packet = list_take_first(&packet_queue, struct packet, packet_entry);

                kp(KP_NORMAL, "Recieved packet! len: %d\n", packet_len(packet));
                kp(KP_NORMAL, "Packets in queue: %d\n", --packet_queue_length);

                not_using_spinlock(&packet_queue_lock)
                    packet_linklayer_rx(packet);
            }

            sleep {
                if (list_empty(&packet_queue)) {
                    not_using_spinlock(&packet_queue_lock)
                        scheduler_task_yield();
                }
            }
        }
    }

    return 0;
}
Exemple #3
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 */
Exemple #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 */