aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-08-31 11:09:53 -0400
committerArjan van de Ven <arjan@linux.intel.com>2008-09-06 00:34:57 -0400
commitdf0cc0539b4127bd02f64de2c335b4af1fdb3845 (patch)
tree2ba23487a2a6c37cfdcd1f5c9edb31a5e0b0df22
parent7bb67439bf6bd3782f07f1d7be1e63406453d5de (diff)
select: add a timespec_add_safe() function
For the select() rework, it's important to be able to add timespec structures in an overflow-safe manner. This patch adds a timespec_add_safe() function for this which is similar in operation to ktime_add_safe(), but works on a struct timespec. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
-rw-r--r--include/linux/time.h4
-rw-r--r--kernel/time.c18
2 files changed, 22 insertions, 0 deletions
diff --git a/include/linux/time.h b/include/linux/time.h
index e15206a7e82e..726976478480 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -38,6 +38,8 @@ struct timezone {
38#define NSEC_PER_SEC 1000000000L 38#define NSEC_PER_SEC 1000000000L
39#define FSEC_PER_SEC 1000000000000000L 39#define FSEC_PER_SEC 1000000000000000L
40 40
41#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
42
41static inline int timespec_equal(const struct timespec *a, 43static inline int timespec_equal(const struct timespec *a,
42 const struct timespec *b) 44 const struct timespec *b)
43{ 45{
@@ -72,6 +74,8 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
72 const unsigned int min, const unsigned int sec); 74 const unsigned int min, const unsigned int sec);
73 75
74extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec); 76extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);
77extern struct timespec timespec_add_safe(const struct timespec lhs,
78 const struct timespec rhs);
75 79
76/* 80/*
77 * sub = lhs - rhs, in normalized form 81 * sub = lhs - rhs, in normalized form
diff --git a/kernel/time.c b/kernel/time.c
index 6a08660b4fac..d63a4336fad6 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -669,3 +669,21 @@ EXPORT_SYMBOL(get_jiffies_64);
669#endif 669#endif
670 670
671EXPORT_SYMBOL(jiffies); 671EXPORT_SYMBOL(jiffies);
672
673/*
674 * Add two timespec values and do a safety check for overflow.
675 * It's assumed that both values are valid (>= 0)
676 */
677struct timespec timespec_add_safe(const struct timespec lhs,
678 const struct timespec rhs)
679{
680 struct timespec res;
681
682 set_normalized_timespec(&res, lhs.tv_sec + rhs.tv_sec,
683 lhs.tv_nsec + rhs.tv_nsec);
684
685 if (res.tv_sec < lhs.tv_sec || res.tv_sec < rhs.tv_sec)
686 res.tv_sec = TIME_T_MAX;
687
688 return res;
689}