X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=kernel%2Fposix-cpu-timers.c;h=2eae91f954ca2ed98b05e2c145b38c2cb857fbb5;hb=25f666300625d894ebe04bac2b4b3aadb907c861;hp=b53c8fcd9d82d25044867c9529a17f9b1fdb00f8;hpb=5e16e3f0e24dadb79b96b6134cd3303f0d42f0c5;p=cascardo%2Flinux.git diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index b53c8fcd9d82..2eae91f954ca 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -20,9 +20,9 @@ static int check_clock(const clockid_t which_clock) return 0; read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (!p || (CPUCLOCK_PERTHREAD(which_clock) ? - p->tgid != current->tgid : p->tgid != pid)) { + p = find_task_by_vpid(pid); + if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ? + same_thread_group(p, current) : thread_group_leader(p))) { error = -EINVAL; } read_unlock(&tasklist_lock); @@ -305,16 +305,16 @@ int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) */ struct task_struct *p; rcu_read_lock(); - p = find_task_by_pid(pid); + p = find_task_by_vpid(pid); if (p) { if (CPUCLOCK_PERTHREAD(which_clock)) { - if (p->tgid == current->tgid) { + if (same_thread_group(p, current)) { error = cpu_clock_sample(which_clock, p, &rtn); } } else { read_lock(&tasklist_lock); - if (p->tgid == pid && p->signal) { + if (thread_group_leader(p) && p->signal) { error = cpu_clock_sample_group(which_clock, p, &rtn); @@ -354,16 +354,16 @@ int posix_cpu_timer_create(struct k_itimer *new_timer) if (pid == 0) { p = current; } else { - p = find_task_by_pid(pid); - if (p && p->tgid != current->tgid) + p = find_task_by_vpid(pid); + if (p && !same_thread_group(p, current)) p = NULL; } } else { if (pid == 0) { p = current->group_leader; } else { - p = find_task_by_pid(pid); - if (p && p->tgid != pid) + p = find_task_by_vpid(pid); + if (p && !thread_group_leader(p)) p = NULL; } } @@ -967,6 +967,7 @@ static void check_thread_timers(struct task_struct *tsk, { int maxfire; struct list_head *timers = tsk->cpu_timers; + struct signal_struct *const sig = tsk->signal; maxfire = 20; tsk->it_prof_expires = cputime_zero; @@ -1011,6 +1012,35 @@ static void check_thread_timers(struct task_struct *tsk, t->firing = 1; list_move_tail(&t->entry, firing); } + + /* + * Check for the special case thread timers. + */ + if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) { + unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max; + unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur; + + if (hard != RLIM_INFINITY && + tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { + /* + * At the hard limit, we just die. + * No need to calculate anything else now. + */ + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); + return; + } + if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) { + /* + * At the soft limit, send a SIGXCPU every second. + */ + if (sig->rlim[RLIMIT_RTTIME].rlim_cur + < sig->rlim[RLIMIT_RTTIME].rlim_max) { + sig->rlim[RLIMIT_RTTIME].rlim_cur += + USEC_PER_SEC; + } + __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); + } + } } /*