Subversion Repositories Kolibri OS

Rev

Rev 4244 | Rev 6082 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5270 serge 1
#include 
3031 serge 2
 
3
 
4
 
5
#define HZ_TO_MSEC_MUL32 0xA0000000
6
#define HZ_TO_MSEC_ADJ32 0x0
7
#define HZ_TO_MSEC_SHR32 28
8
#define HZ_TO_MSEC_MUL64 0xA000000000000000
9
#define HZ_TO_MSEC_ADJ64 0x0
10
#define HZ_TO_MSEC_SHR64 60
11
#define MSEC_TO_HZ_MUL32 0xCCCCCCCD
12
#define MSEC_TO_HZ_ADJ32 0x733333333
13
#define MSEC_TO_HZ_SHR32 35
14
#define MSEC_TO_HZ_MUL64 0xCCCCCCCCCCCCCCCD
15
#define MSEC_TO_HZ_ADJ64 0x73333333333333333
16
#define MSEC_TO_HZ_SHR64 67
17
#define HZ_TO_MSEC_NUM 10
18
#define HZ_TO_MSEC_DEN 1
19
#define MSEC_TO_HZ_NUM 1
20
#define MSEC_TO_HZ_DEN 10
21
 
22
#define HZ_TO_USEC_MUL32 0x9C400000
23
#define HZ_TO_USEC_ADJ32 0x0
24
#define HZ_TO_USEC_SHR32 18
25
#define HZ_TO_USEC_MUL64 0x9C40000000000000
26
#define HZ_TO_USEC_ADJ64 0x0
27
#define HZ_TO_USEC_SHR64 50
28
#define USEC_TO_HZ_MUL32 0xD1B71759
29
#define USEC_TO_HZ_ADJ32 0x1FFF2E48E8A7
30
#define USEC_TO_HZ_SHR32 45
31
#define USEC_TO_HZ_MUL64 0xD1B71758E219652C
32
#define USEC_TO_HZ_ADJ64 0x1FFF2E48E8A71DE69AD4
33
#define USEC_TO_HZ_SHR64 77
34
#define HZ_TO_USEC_NUM 10000
35
#define HZ_TO_USEC_DEN 1
36
#define USEC_TO_HZ_NUM 1
37
#define USEC_TO_HZ_DEN 10000
38
 
39
 
40
#define MSEC_PER_SEC    1000L
41
#define USEC_PER_MSEC   1000L
42
#define NSEC_PER_USEC   1000L
43
#define NSEC_PER_MSEC   1000000L
44
#define USEC_PER_SEC    1000000L
45
#define NSEC_PER_SEC    1000000000L
46
#define FSEC_PER_SEC    1000000000000000LL
47
 
48
 
49
unsigned int jiffies_to_msecs(const unsigned long j)
50
{
51
#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
52
        return (MSEC_PER_SEC / HZ) * j;
53
#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
54
        return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
55
#else
56
# if BITS_PER_LONG == 32
57
        return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
58
# else
59
        return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
60
# endif
61
#endif
62
}
63
 
64
unsigned int jiffies_to_usecs(const unsigned long j)
65
{
66
#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
67
        return (USEC_PER_SEC / HZ) * j;
68
#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
69
        return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
70
#else
71
# if BITS_PER_LONG == 32
72
        return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
73
# else
74
        return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
75
# endif
76
#endif
77
}
78
 
79
 
80
/*
81
 * When we convert to jiffies then we interpret incoming values
82
 * the following way:
83
 *
84
 * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
85
 *
86
 * - 'too large' values [that would result in larger than
87
 *   MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
88
 *
89
 * - all other values are converted to jiffies by either multiplying
90
 *   the input value by a factor or dividing it with a factor
91
 *
92
 * We must also be careful about 32-bit overflows.
93
 */
94
unsigned long msecs_to_jiffies(const unsigned int m)
95
{
96
    /*
97
     * Negative value, means infinite timeout:
98
     */
99
    if ((int)m < 0)
100
        return MAX_JIFFY_OFFSET;
101
 
102
#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
103
    /*
104
     * HZ is equal to or smaller than 1000, and 1000 is a nice
105
     * round multiple of HZ, divide with the factor between them,
106
     * but round upwards:
107
     */
108
    return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
109
#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
110
    /*
111
     * HZ is larger than 1000, and HZ is a nice round multiple of
112
     * 1000 - simply multiply with the factor between them.
113
     *
114
     * But first make sure the multiplication result cannot
115
     * overflow:
116
     */
117
    if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
118
        return MAX_JIFFY_OFFSET;
119
 
120
    return m * (HZ / MSEC_PER_SEC);
121
#else
122
    /*
123
     * Generic case - multiply, round and divide. But first
124
     * check that if we are doing a net multiplication, that
125
     * we wouldn't overflow:
126
     */
127
    if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
128
        return MAX_JIFFY_OFFSET;
129
 
130
    return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
131
        >> MSEC_TO_HZ_SHR32;
132
#endif
133
}
5270 serge 134
EXPORT_SYMBOL(msecs_to_jiffies);
3031 serge 135
 
136
unsigned long usecs_to_jiffies(const unsigned int u)
137
{
138
    if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
139
        return MAX_JIFFY_OFFSET;
140
#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
141
    return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
142
#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
143
    return u * (HZ / USEC_PER_SEC);
144
#else
145
    return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
146
        >> USEC_TO_HZ_SHR32;
147
#endif
148
}
5270 serge 149
EXPORT_SYMBOL(usecs_to_jiffies);
3031 serge 150
 
5270 serge 151
/*
152
 * The TICK_NSEC - 1 rounds up the value to the next resolution.  Note
153
 * that a remainder subtract here would not do the right thing as the
154
 * resolution values don't fall on second boundries.  I.e. the line:
155
 * nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding.
156
 * Note that due to the small error in the multiplier here, this
157
 * rounding is incorrect for sufficiently large values of tv_nsec, but
158
 * well formed timespecs should have tv_nsec < NSEC_PER_SEC, so we're
159
 * OK.
160
 *
161
 * Rather, we just shift the bits off the right.
162
 *
163
 * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
164
 * value to a scaled second value.
165
 */
166
static unsigned long
167
__timespec_to_jiffies(unsigned long sec, long nsec)
3297 Serge 168
{
5270 serge 169
	nsec = nsec + TICK_NSEC - 1;
3297 Serge 170
 
171
    if (sec >= MAX_SEC_IN_JIFFIES){
172
            sec = MAX_SEC_IN_JIFFIES;
173
            nsec = 0;
174
    }
175
    return (((u64)sec * SEC_CONVERSION) +
176
            (((u64)nsec * NSEC_CONVERSION) >>
177
             (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
178
 
179
}
180
 
5270 serge 181
unsigned long
182
timespec_to_jiffies(const struct timespec *value)
183
{
184
	return __timespec_to_jiffies(value->tv_sec, value->tv_nsec);
185
}
186
 
187
EXPORT_SYMBOL(timespec_to_jiffies);
188
 
189
void
190
jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
191
{
192
	/*
193
	 * Convert jiffies to nanoseconds and separate with
194
	 * one divide.
195
	 */
196
	u32 rem;
197
	value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
198
				    NSEC_PER_SEC, &rem);
199
	value->tv_nsec = rem;
200
}
201
EXPORT_SYMBOL(jiffies_to_timespec);
202
 
4244 Serge 203
s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
204
{
205
        u64 quotient;
206
 
207
        if (dividend < 0) {
208
                quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder);
209
                *remainder = -*remainder;
210
                if (divisor > 0)
211
                        quotient = -quotient;
212
        } else {
213
                quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder);
214
                if (divisor < 0)
215
                        quotient = -quotient;
216
        }
217
        return quotient;
218
}
219
 
220
struct timespec ns_to_timespec(const s64 nsec)
221
{
222
        struct timespec ts;
223
        s32 rem;
224
 
225
        if (!nsec)
226
                return (struct timespec) {0, 0};
227
 
228
        ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
229
        if (unlikely(rem < 0)) {
230
                ts.tv_sec--;
231
                rem += NSEC_PER_SEC;
232
        }
233
        ts.tv_nsec = rem;
234
 
235
        return ts;
236
}
237