]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * include/asm-s390/cputime.h | |
3 | * | |
4 | * (C) Copyright IBM Corp. 2004 | |
5 | * | |
6 | * Author: Martin Schwidefsky <[email protected]> | |
7 | */ | |
8 | ||
9 | #ifndef _S390_CPUTIME_H | |
10 | #define _S390_CPUTIME_H | |
11 | ||
76d4e00a MS |
12 | #include <linux/types.h> |
13 | #include <linux/percpu.h> | |
14 | #include <linux/spinlock.h> | |
1da177e4 LT |
15 | #include <asm/div64.h> |
16 | ||
aa5e97ce | 17 | /* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ |
1da177e4 LT |
18 | |
19 | typedef unsigned long long cputime_t; | |
20 | typedef unsigned long long cputime64_t; | |
21 | ||
22 | #ifndef __s390x__ | |
23 | ||
24 | static inline unsigned int | |
25 | __div(unsigned long long n, unsigned int base) | |
26 | { | |
27 | register_pair rp; | |
28 | ||
29 | rp.pair = n >> 1; | |
30 | asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1)); | |
31 | return rp.subreg.odd; | |
32 | } | |
33 | ||
34 | #else /* __s390x__ */ | |
35 | ||
36 | static inline unsigned int | |
37 | __div(unsigned long long n, unsigned int base) | |
38 | { | |
39 | return n / base; | |
40 | } | |
41 | ||
42 | #endif /* __s390x__ */ | |
43 | ||
44 | #define cputime_zero (0ULL) | |
a42548a1 | 45 | #define cputime_one_jiffy jiffies_to_cputime(1) |
1da177e4 LT |
46 | #define cputime_max ((~0UL >> 1) - 1) |
47 | #define cputime_add(__a, __b) ((__a) + (__b)) | |
48 | #define cputime_sub(__a, __b) ((__a) - (__b)) | |
49 | #define cputime_div(__a, __n) ({ \ | |
50 | unsigned long long __div = (__a); \ | |
51 | do_div(__div,__n); \ | |
52 | __div; \ | |
53 | }) | |
54 | #define cputime_halve(__a) ((__a) >> 1) | |
55 | #define cputime_eq(__a, __b) ((__a) == (__b)) | |
56 | #define cputime_gt(__a, __b) ((__a) > (__b)) | |
57 | #define cputime_ge(__a, __b) ((__a) >= (__b)) | |
58 | #define cputime_lt(__a, __b) ((__a) < (__b)) | |
59 | #define cputime_le(__a, __b) ((__a) <= (__b)) | |
aa5e97ce | 60 | #define cputime_to_jiffies(__ct) (__div((__ct), 4096000000ULL / HZ)) |
06b8e878 | 61 | #define cputime_to_scaled(__ct) (__ct) |
aa5e97ce | 62 | #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (4096000000ULL / HZ)) |
1da177e4 LT |
63 | |
64 | #define cputime64_zero (0ULL) | |
65 | #define cputime64_add(__a, __b) ((__a) + (__b)) | |
66 | #define cputime_to_cputime64(__ct) (__ct) | |
67 | ||
68 | static inline u64 | |
69 | cputime64_to_jiffies64(cputime64_t cputime) | |
70 | { | |
aa5e97ce | 71 | do_div(cputime, 4096000000ULL / HZ); |
1da177e4 LT |
72 | return cputime; |
73 | } | |
74 | ||
75 | /* | |
d57af9b2 | 76 | * Convert cputime to microseconds and back. |
1da177e4 LT |
77 | */ |
78 | static inline unsigned int | |
d57af9b2 | 79 | cputime_to_usecs(const cputime_t cputime) |
1da177e4 | 80 | { |
d57af9b2 | 81 | return cputime_div(cputime, 4096); |
1da177e4 LT |
82 | } |
83 | ||
84 | static inline cputime_t | |
d57af9b2 | 85 | usecs_to_cputime(const unsigned int m) |
1da177e4 | 86 | { |
d57af9b2 | 87 | return (cputime_t) m * 4096; |
1da177e4 LT |
88 | } |
89 | ||
90 | /* | |
91 | * Convert cputime to milliseconds and back. | |
92 | */ | |
93 | static inline unsigned int | |
94 | cputime_to_secs(const cputime_t cputime) | |
95 | { | |
aa5e97ce | 96 | return __div(cputime, 2048000000) >> 1; |
1da177e4 LT |
97 | } |
98 | ||
99 | static inline cputime_t | |
100 | secs_to_cputime(const unsigned int s) | |
101 | { | |
aa5e97ce | 102 | return (cputime_t) s * 4096000000ULL; |
1da177e4 LT |
103 | } |
104 | ||
105 | /* | |
106 | * Convert cputime to timespec and back. | |
107 | */ | |
108 | static inline cputime_t | |
109 | timespec_to_cputime(const struct timespec *value) | |
110 | { | |
aa5e97ce | 111 | return value->tv_nsec * 4096 / 1000 + (u64) value->tv_sec * 4096000000ULL; |
1da177e4 LT |
112 | } |
113 | ||
114 | static inline void | |
115 | cputime_to_timespec(const cputime_t cputime, struct timespec *value) | |
116 | { | |
117 | #ifndef __s390x__ | |
118 | register_pair rp; | |
119 | ||
120 | rp.pair = cputime >> 1; | |
aa5e97ce MS |
121 | asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); |
122 | value->tv_nsec = rp.subreg.even * 1000 / 4096; | |
1da177e4 LT |
123 | value->tv_sec = rp.subreg.odd; |
124 | #else | |
aa5e97ce MS |
125 | value->tv_nsec = (cputime % 4096000000ULL) * 1000 / 4096; |
126 | value->tv_sec = cputime / 4096000000ULL; | |
1da177e4 LT |
127 | #endif |
128 | } | |
129 | ||
130 | /* | |
131 | * Convert cputime to timeval and back. | |
132 | * Since cputime and timeval have the same resolution (microseconds) | |
133 | * this is easy. | |
134 | */ | |
135 | static inline cputime_t | |
136 | timeval_to_cputime(const struct timeval *value) | |
137 | { | |
aa5e97ce | 138 | return value->tv_usec * 4096 + (u64) value->tv_sec * 4096000000ULL; |
1da177e4 LT |
139 | } |
140 | ||
141 | static inline void | |
142 | cputime_to_timeval(const cputime_t cputime, struct timeval *value) | |
143 | { | |
144 | #ifndef __s390x__ | |
145 | register_pair rp; | |
146 | ||
147 | rp.pair = cputime >> 1; | |
aa5e97ce MS |
148 | asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); |
149 | value->tv_usec = rp.subreg.even / 4096; | |
1da177e4 LT |
150 | value->tv_sec = rp.subreg.odd; |
151 | #else | |
d5cd0343 | 152 | value->tv_usec = (cputime % 4096000000ULL) / 4096; |
aa5e97ce | 153 | value->tv_sec = cputime / 4096000000ULL; |
1da177e4 LT |
154 | #endif |
155 | } | |
156 | ||
157 | /* | |
158 | * Convert cputime to clock and back. | |
159 | */ | |
160 | static inline clock_t | |
161 | cputime_to_clock_t(cputime_t cputime) | |
162 | { | |
70f5dc51 | 163 | return cputime_div(cputime, 4096000000ULL / USER_HZ); |
1da177e4 LT |
164 | } |
165 | ||
166 | static inline cputime_t | |
167 | clock_t_to_cputime(unsigned long x) | |
168 | { | |
aa5e97ce | 169 | return (cputime_t) x * (4096000000ULL / USER_HZ); |
1da177e4 LT |
170 | } |
171 | ||
172 | /* | |
173 | * Convert cputime64 to clock. | |
174 | */ | |
175 | static inline clock_t | |
176 | cputime64_to_clock_t(cputime64_t cputime) | |
177 | { | |
70f5dc51 | 178 | return cputime_div(cputime, 4096000000ULL / USER_HZ); |
1da177e4 LT |
179 | } |
180 | ||
76d4e00a | 181 | struct s390_idle_data { |
e98bbaaf | 182 | unsigned int sequence; |
76d4e00a MS |
183 | unsigned long long idle_count; |
184 | unsigned long long idle_enter; | |
185 | unsigned long long idle_time; | |
3c5d92a0 | 186 | int nohz_delay; |
76d4e00a MS |
187 | }; |
188 | ||
189 | DECLARE_PER_CPU(struct s390_idle_data, s390_idle); | |
190 | ||
6377981f | 191 | void vtime_start_cpu(__u64 int_clock, __u64 enter_timer); |
e1c80530 MS |
192 | cputime64_t s390_get_idle_time(int cpu); |
193 | ||
194 | #define arch_idle_time(cpu) s390_get_idle_time(cpu) | |
195 | ||
6377981f MS |
196 | static inline void s390_idle_check(struct pt_regs *regs, __u64 int_clock, |
197 | __u64 enter_timer) | |
76d4e00a | 198 | { |
6377981f MS |
199 | if (regs->psw.mask & PSW_MASK_WAIT) |
200 | vtime_start_cpu(int_clock, enter_timer); | |
76d4e00a MS |
201 | } |
202 | ||
3c5d92a0 MS |
203 | static inline int s390_nohz_delay(int cpu) |
204 | { | |
205 | return per_cpu(s390_idle, cpu).nohz_delay != 0; | |
206 | } | |
207 | ||
208 | #define arch_needs_cpu(cpu) s390_nohz_delay(cpu) | |
209 | ||
1da177e4 | 210 | #endif /* _S390_CPUTIME_H */ |