Allow timeout implementations to block, by using a kernel thread instead of a timer.
[sliver-openvswitch.git] / datapath / linux-2.4 / compat-2.4 / include / linux / delay.h
1 #ifndef __LINUX_DELAY_WRAPPER_H
2 #define __LINUX_DELAY_WRAPPER_H 1
3
4 #include_next <linux/delay.h>
5
6 #include <linux/version.h>
7 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29)
8 #include <linux/time.h>
9 #include <asm/param.h>
10 /*
11  * We define MAX_MSEC_OFFSET as the maximal value that can be accepted by
12  * msecs_to_jiffies() without risking a multiply overflow. This function
13  * returns MAX_JIFFY_OFFSET for arguments above those values.
14  */
15
16 #if HZ <= 1000 && !(1000 % HZ)
17 #  define MAX_MSEC_OFFSET \
18         (ULONG_MAX - (1000 / HZ) + 1)
19 #elif HZ > 1000 && !(HZ % 1000)
20 #  define MAX_MSEC_OFFSET \
21         (ULONG_MAX / (HZ / 1000))
22 #else
23 #  define MAX_MSEC_OFFSET \
24         ((ULONG_MAX - 999) / HZ)
25 #endif
26
27 /*
28  * Convert jiffies to milliseconds and back.
29  *
30  * Avoid unnecessary multiplications/divisions in the
31  * two most common HZ cases:
32  */
33 static inline unsigned int jiffies_to_msecs(const unsigned long j)
34 {
35 #if HZ <= 1000 && !(1000 % HZ)
36         return (1000 / HZ) * j;
37 #elif HZ > 1000 && !(HZ % 1000)
38         return (j + (HZ / 1000) - 1)/(HZ / 1000);
39 #else
40         return (j * 1000) / HZ;
41 #endif
42 }
43
44 static inline unsigned long msecs_to_jiffies(const unsigned int m)
45 {
46         if (MAX_MSEC_OFFSET < UINT_MAX && m > (unsigned int)MAX_MSEC_OFFSET)
47                 return MAX_JIFFY_OFFSET;
48 #if HZ <= 1000 && !(1000 % HZ)
49         return ((unsigned long)m + (1000 / HZ) - 1) / (1000 / HZ);
50 #elif HZ > 1000 && !(HZ % 1000)
51         return (unsigned long)m * (HZ / 1000);
52 #else
53         return ((unsigned long)m * HZ + 999) / 1000;
54 #endif
55 }
56
57 #endif /* linux kernel < 2.4.29 */
58
59 /**
60  * msleep_interruptible - sleep waiting for waitqueue interruptions
61  * @msecs: Time in milliseconds to sleep for
62  */
63 static inline unsigned long msleep_interruptible(unsigned int msecs)
64 {
65        unsigned long timeout = msecs_to_jiffies(msecs);
66
67        while (timeout && !signal_pending(current)) {
68                set_current_state(TASK_INTERRUPTIBLE);
69                timeout = schedule_timeout(timeout);
70        }
71        return jiffies_to_msecs(timeout);
72 }
73
74 #endif