/** * @brief Yields the processor. */ PUBLIC void yield(void) { struct process *p; /* Working process. */ struct process *next; /* Next process to run. */ /* Re-schedule process for execution. */ if (curr_proc->state == PROC_RUNNING) sched(curr_proc); /* Remember this process. */ last_proc = curr_proc; /* Check alarm. */ for (p = FIRST_PROC; p <= LAST_PROC; p++) { /* Skip invalid processes. */ if (!IS_VALID(p)) continue; /* Alarm has expired. */ if ((p->alarm) && (p->alarm < ticks)) p->alarm = 0, sndsig(p, SIGALRM); } /* Choose a process to run next. */ next = IDLE; for (p = FIRST_PROC; p <= LAST_PROC; p++) { /* Skip non-ready process. */ if (p->state != PROC_READY) continue; /* * Process with higher * waiting time found. */ if (p->counter > next->counter) { next->counter++; next = p; } /* * Increment waiting * time of process. */ else p->counter++; } /* Switch to next process. */ next->priority = PRIO_USER; next->state = PROC_RUNNING; next->counter = PROC_QUANTUM; switch_to(next); }
/** * @brief Sends a signal to process group. * * @details Sends the signal @p sig to the process group of the currently active * TTY device. * * @param sig Signal to be sent. */ PRIVATE void tty_signal(int sig) { for (struct process *p = FIRST_PROC; p <= LAST_PROC; p++) { /* Skip invalid processes. */ if (!IS_VALID(p)) continue; if (active->pgrp == p->pgrp) sndsig(p, sig); } }
/** * @brief Stops the current running process. */ PUBLIC void stop(void) { curr_proc->state = PROC_STOPPED; sndsig(curr_proc->father, SIGCHLD); yield(); }
/* * Sends a signal to a process or a process group. */ PUBLIC int sys_kill(pid_t pid, int sig) { int err; struct process *p; /* Invalid signal. */ if ((sig < 0) || (sig > NR_SIGNALS - 1)) return (-EINVAL); err = -ESRCH; /* Send signal to process. */ if (pid > 0) { /* Search for process. */ for (p = FIRST_PROC; p <= LAST_PROC; p++) { /* Skip invalid processes. */ if (!IS_VALID(p)) continue; /* Found. */ if (pid == p->pid) { err = -EPERM; if (AUTHORIZED(curr_proc, p, sig)) { err = 0; sndsig(p, sig); } } } } /* Send signal to process group. */ else if (pid == 0) { /* Search for processes. */ for (p = FIRST_PROC; p <= LAST_PROC; p++) { /* Skip invalid processes. */ if (!IS_VALID(p)) continue; /* Found. */ if (curr_proc->pgrp == p->pgrp) { err = -EPERM; if (AUTHORIZED(curr_proc, p, sig)) { err = 0; sndsig(p, sig); } } } } /* Send signal to all processes. */ else if (pid == -1) { err = -EPERM; /* Search for processes. */ for (p = FIRST_PROC; p <= LAST_PROC; p++) { /* Skip invalid processes. */ if (!IS_VALID(p)) continue; if (AUTHORIZED(curr_proc, p, sig)) { err = 0; sndsig(p, sig); } } } /* Send signal to absolute proces group. */ else { /* Search for processes. */ for (p = FIRST_PROC; p <= LAST_PROC; p++) { /* Skip invalid processes. */ if (!IS_VALID(p)) continue; /* Found. */ if (p->pgrp->pid == -pid) { err = -EPERM; if (AUTHORIZED(curr_proc, p, sig)) { err = 0; sndsig(p, sig); } } } } return (err); }