Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.25-rc7 /kernel/posix-cpu-timers.c

Filename:/kernel/posix-cpu-timers.c
Lines Added:34
Lines Deleted:4
Also changed in: (Previous) 2.6.25-rc6  2.6.25-rc5  2.6.25-rc4  2.6.25-rc3  2.6.25-rc2  2.6.25-rc1 
(Following) 2.6.25-rc8  2.6.25-rc9  2.6.25  2.6.25-git1  2.6.25-git2  2.6.25-git3 

Location
[  2.6.25-rc7
  [  kernel
     o  posix-cpu-timers.c

Patch

diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 68c9637..2eae91f 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -20,7 +20,7 @@ static int check_clock(const clockid_t which_clock)
       return 0;
 
    read_lock(&tasklist_lock);
-   p = find_task_by_pid(pid);
+   p = find_task_by_vpid(pid);
    if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ?
          same_thread_group(p, current) : thread_group_leader(p))) {
       error = -EINVAL;
@@ -305,7 +305,7 @@ 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 (same_thread_group(p, current)) {
@@ -354,7 +354,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
       if (pid == 0) {
          p = current;
       } else {
-         p = find_task_by_pid(pid);
+         p = find_task_by_vpid(pid);
          if (p && !same_thread_group(p, current))
             p = NULL;
       }
@@ -362,7 +362,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
       if (pid == 0) {
          p = current->group_leader;
       } else {
-         p = find_task_by_pid(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);
+      }
+   }
 }
 
 /*


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.