X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Ftimer.c;h=f7d42e8ec28d8f32b369cfd0257e43cc2179dc18;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=08cec6ae76e375ea613a21af3a137112c065926d;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/kernel/timer.c b/kernel/timer.c index 08cec6ae7..f7d42e8ec 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -31,8 +31,12 @@ #include #include #include +#include +#include +#include #include +#include #include #include @@ -317,10 +321,16 @@ EXPORT_SYMBOL(del_timer); * * Synchronization rules: callers must prevent restarting of the timer, * otherwise this function is meaningless. It must not be called from - * interrupt contexts. Upon exit the timer is not queued and the handler - * is not running on any CPU. + * interrupt contexts. The caller must not hold locks which would prevent + * completion of the timer's handler. Upon exit the timer is not queued and + * the handler is not running on any CPU. * * The function returns whether it has deactivated a pending timer or not. + * + * del_timer_sync() is slow and complicated because it copes with timer + * handlers which re-arm the timer (periodic timers). If the timer handler + * is known to not do this (a single shot timer) then use + * del_singleshot_timer_sync() instead. */ int del_timer_sync(struct timer_list *timer) { @@ -332,7 +342,7 @@ int del_timer_sync(struct timer_list *timer) del_again: ret += del_timer(timer); - for_each_cpu(i) { + for_each_online_cpu(i) { base = &per_cpu(tvec_bases, i); if (base->running_timer == timer) { while (base->running_timer == timer) { @@ -348,8 +358,36 @@ del_again: return ret; } - EXPORT_SYMBOL(del_timer_sync); + +/*** + * del_singleshot_timer_sync - deactivate a non-recursive timer + * @timer: the timer to be deactivated + * + * This function is an optimization of del_timer_sync for the case where the + * caller can guarantee the timer does not reschedule itself in its timer + * function. + * + * Synchronization rules: callers must prevent restarting of the timer, + * otherwise this function is meaningless. It must not be called from + * interrupt contexts. The caller must not hold locks which wold prevent + * completion of the timer's handler. Upon exit the timer is not queued and + * the handler is not running on any CPU. + * + * The function returns whether it has deactivated a pending timer or not. + */ +int del_singleshot_timer_sync(struct timer_list *timer) +{ + int ret = del_timer(timer); + + if (!ret) { + ret = del_timer_sync(timer); + BUG_ON(ret); + } + + return ret; +} +EXPORT_SYMBOL(del_singleshot_timer_sync); #endif static int cascade(tvec_base_t *base, tvec_t *tv, int index) @@ -757,12 +795,12 @@ static inline void do_process_times(struct task_struct *p, psecs = (p->utime += user); psecs += (p->stime += system); - if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) { + if (psecs / HZ >= p->rlim[RLIMIT_CPU].rlim_cur) { /* Send SIGXCPU every second.. */ if (!(psecs % HZ)) send_sig(SIGXCPU, p, 1); /* and SIGKILL when we go over max.. */ - if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_max) + if (psecs / HZ >= p->rlim[RLIMIT_CPU].rlim_max) send_sig(SIGKILL, p, 1); } } @@ -794,7 +832,7 @@ static inline void do_it_prof(struct task_struct *p) } } -void update_one_process(struct task_struct *p, unsigned long user, +static void update_one_process(struct task_struct *p, unsigned long user, unsigned long system, int cpu) { do_process_times(p, user, system); @@ -918,7 +956,7 @@ void do_timer(struct pt_regs *regs) update_times(); } -#if !defined(__alpha__) && !defined(__ia64__) +#ifdef __ARCH_WANT_SYS_ALARM /* * For backwards compatibility? This can be done in libc so Alpha @@ -961,7 +999,7 @@ asmlinkage unsigned long sys_alarm(unsigned int seconds) */ asmlinkage long sys_getpid(void) { - return current->tgid; + return vx_map_tgid(current->vx_info, current->tgid); } /* @@ -1005,7 +1043,7 @@ asmlinkage long sys_getppid(void) #endif break; } - return pid; + return vx_map_tgid(current->vx_info, pid); } asmlinkage long sys_getuid(void) @@ -1109,7 +1147,7 @@ fastcall signed long __sched schedule_timeout(signed long timeout) add_timer(&timer); schedule(); - del_timer_sync(&timer); + del_singleshot_timer_sync(&timer); timeout = expire - jiffies; @@ -1214,6 +1252,8 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info) tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; tp.tv_sec++; } + if (vx_flags(VXF_VIRT_UPTIME, 0)) + vx_vsi_uptime(&tp, NULL); val.uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); @@ -1223,6 +1263,9 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info) val.procs = nr_threads; } while (read_seqretry(&xtime_lock, seq)); +/* if (vx_flags(VXF_VIRT_CPU, 0)) + vx_vsi_cpu(val); +*/ si_meminfo(&val); si_swapinfo(&val); @@ -1451,3 +1494,20 @@ unregister_time_interpolator(struct time_interpolator *ti) spin_unlock(&time_interpolator_lock); } #endif /* CONFIG_TIME_INTERPOLATION */ + +/** + * msleep - sleep safely even with waitqueue interruptions + * @msecs: Time in milliseconds to sleep for + */ +void msleep(unsigned int msecs) +{ + unsigned long timeout = msecs_to_jiffies(msecs); + + while (timeout) { + set_current_state(TASK_UNINTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } +} + +EXPORT_SYMBOL(msleep); +