static NOINLINE_NOCLONE NORETURN void
stdarg (int f UNUSED, ...)
{
    sighandler_t sigusr2_orig = signal (SIGUSR2, sigusr2);
    assert (sigusr2_orig == SIG_DFL);
    errno = 0;
    if (ptraceme)
    {
        long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
        assert (errno == 0);
        assert (l == 0);
    }
#ifdef __x86_64__
    if (! gencore)
    {
        /* Execution will get PC patched into function jmp.  */
        raise (SIGUSR1);
    }
#endif
    sigusr2 (SIGUSR2);
    /* Not reached.  */
    abort ();
}
Beispiel #2
0
//PAGEBREAK: 42
// Per-CPU process scheduler.
// Each CPU calls scheduler() after setting itself up.
// Scheduler never returns.  It loops, doing:
//  - choose a process to run
//  - swtch to start running that process
//  - eventually that process transfers control
//      via swtch back to the scheduler.
void
scheduler(void)
{
    struct proc *p;
    uint mask;
    sighandler_t *handler;

    for(;;) {
        // Enable interrupts on this processor.
        sti();

        // Loop over process table looking for process to run.
        acquire(&ptable.lock);
        for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) {
            if(p->state != RUNNABLE)
                continue;

            // Switch to chosen process.  It is the process's job
            // to release ptable.lock and then reacquire it
            // before jumping back to us.
            proc = p;
            switchuvm(p);

            /* A&T - SIGNALS start */
            if (p->signal != 0) {	/* A&T - were any signals recieved? */
                /* cprintf("DEBUG: pid=%d, p->signal=%d\n", p->pid, p->signal); */
                mask = (1 << 31);	/* the stack is a LIFO structure, so
                                 * we'll be pushing the LEAST important
                                 * signals first, so they'll run last. */
                /* cprintf("DEBUG: mask=%d\n", mask); */
                handler = &proc->handlers[31];
                while(mask > 8) {
                    /* a mask to check whether a signal's
                                        bit is up - not for builtin 3 signal
                                        hadlers, since they should be called
                                        from kernel space and not userspace. */
                    if ((p->signal & mask) && (*handler != 0))
                        register_handler(*handler); /* add the handler to
                                                 the stack, if it exists */


                    mask >>= 1;	/* move the mask to the next bit to check. */
                    handler--;	/* move the pointer to the next hendler */
                }
                while (mask > 0) {
                    if (p->signal & mask) {
                        if (*handler == 0) /* call the built-in handler */
                            switch(mask) {
                            case 8:
                                sigchld();
                                break;
                            case 4:
                                sigusr2();
                                break;
                            case 2:
                                sigusr1();
                                break;
                            case 1:
                                sigint();
                                break;
                            default:
                                break;
                            }
                        else
                            register_handler(*handler);
                    }
                    mask >>= 1;
                    handler--;
                }
                p->signal = 0;	/* initialize the signal data word to 0 */
            }
            /* A&T - SIGNALS end */

            p->state = RUNNING;
            swtch(&cpu->scheduler, proc->context);
            switchkvm();

            // Process is done running for now.
            // It should have changed its p->state before coming back.
            proc = 0;
        }
        release(&ptable.lock);

    }