Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 #include <hwcore/irq.h> 019 #include <hwcore/irq.h>
020 #include <sos/kmalloc.h> 020 #include <sos/kmalloc.h>
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/calcload.h> 022 #include <sos/calcload.h>
023 023
024 024
025 025
026 026
027 027
028 028
029 029
030 030
031 031
032 032
033 033
034 034
035 035
036 036
037 037
038 038
039 039
040 040
041 041
042 042
043 043
044 044
045 045
046 046
047 047
048 048
049 049
050 #define SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR 050 #define SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR 10
051 051
052 052
053 053
054 054
055 055
056 056
057 057
058 058
059 059
060 060
061 061
062 062
063 063
064 064
065 065
066 066
067 067
068 068
069 069
070 070
071 071
072 #define NB_SECS 900 072 #define NB_SECS 900
073 073
074 074
075 075
076 struct load_entry 076 struct load_entry
077 { 077 {
078 sos_ui32_t nb_ticks; 078 sos_ui32_t nb_ticks;
079 079
080 sos_ui32_t nb_user_running; 080 sos_ui32_t nb_user_running;
081 sos_ui32_t nb_kernel_running; 081 sos_ui32_t nb_kernel_running;
082 082
083 sos_ui32_t nb_user_ready; 083 sos_ui32_t nb_user_ready;
084 sos_ui32_t nb_kernel_ready; 084 sos_ui32_t nb_kernel_ready;
085 }; 085 };
086 086
087 struct load_entry current_load_entry; 087 struct load_entry current_load_entry;
088 088
089 089
090 090
091 struct recorded_loads 091 struct recorded_loads
092 { 092 {
093 sos_ui32_t most_recent; 093 sos_ui32_t most_recent;
094 sos_ui32_t max_entries; 094 sos_ui32_t max_entries;
095 095
096 struct load_entry *load_entries; 096 struct load_entry *load_entries;
097 }; 097 };
098 098
099 #define LOAD_GET_ENTRY(loads,age) \ 099 #define LOAD_GET_ENTRY(loads,age) \
100 (&((loads).load_entries[( (loads).max_entrie 100 (&((loads).load_entries[( (loads).max_entries + (loads).most_recent - (age))\
101 % ((loads).max_entri 101 % ((loads).max_entries)]))
102 102
103 103
104 struct sliding_window 104 struct sliding_window
105 { 105 {
106 sos_ui32_t max_entries; 106 sos_ui32_t max_entries;
107 sos_ui32_t nb_entries; 107 sos_ui32_t nb_entries;
108 108
109 sos_ui32_t sigma_nb_ticks; 109 sos_ui32_t sigma_nb_ticks;
110 sos_ui32_t sigma_nb_user_running; 110 sos_ui32_t sigma_nb_user_running;
111 sos_ui32_t sigma_nb_kernel_running; 111 sos_ui32_t sigma_nb_kernel_running;
112 sos_ui32_t sigma_nb_user_ready; 112 sos_ui32_t sigma_nb_user_ready;
113 sos_ui32_t sigma_nb_kernel_ready; 113 sos_ui32_t sigma_nb_kernel_ready;
114 }; 114 };
115 115
116 116
117 117
118 static struct recorded_loads recorded_loads; 118 static struct recorded_loads recorded_loads;
119 119
120 120
121 static struct sliding_window load_1mn, load_5m 121 static struct sliding_window load_1mn, load_5mn, load_15mn;
122 122
123 123
124 static struct sos_timeout_action calcload_time 124 static struct sos_timeout_action calcload_timeout;
125 static void calcload_routine(struct sos_timeou 125 static void calcload_routine(struct sos_timeout_action *a);
126 126
127 127
128 static void _reinit_load_subsystem() !! 128 static void _reinit_load_subsystem(void)
129 { 129 {
130 memset(& recorded_loads, 0x0, sizeof(recorde 130 memset(& recorded_loads, 0x0, sizeof(recorded_loads));
131 memset(& current_load_entry, 0x0, sizeof(str 131 memset(& current_load_entry, 0x0, sizeof(struct load_entry));
132 memset(& load_1mn, 0x0, sizeof(load_1mn)); 132 memset(& load_1mn, 0x0, sizeof(load_1mn));
133 memset(& load_5mn, 0x0, sizeof(load_5mn)); 133 memset(& load_5mn, 0x0, sizeof(load_5mn));
134 memset(& load_15mn, 0x0, sizeof(load_15mn)); 134 memset(& load_15mn, 0x0, sizeof(load_15mn));
135 } 135 }
136 136
137 137
138 sos_ret_t sos_load_subsystem_setup(void) 138 sos_ret_t sos_load_subsystem_setup(void)
139 { 139 {
140 struct sos_time period; 140 struct sos_time period;
141 _reinit_load_subsystem(); 141 _reinit_load_subsystem();
142 142
143 if (recorded_loads.load_entries) 143 if (recorded_loads.load_entries)
144 sos_kfree((sos_vaddr_t) recorded_loads.loa 144 sos_kfree((sos_vaddr_t) recorded_loads.load_entries);
145 _reinit_load_subsystem(); 145 _reinit_load_subsystem();
146 146
147 147
148 148
149 recorded_loads.max_entries = NB_SECS; 149 recorded_loads.max_entries = NB_SECS;
150 recorded_loads.load_entries 150 recorded_loads.load_entries
151 = (struct load_entry*) sos_kmalloc(NB_SECS 151 = (struct load_entry*) sos_kmalloc(NB_SECS * sizeof(struct load_entry),
152 0); 152 0);
153 if (! recorded_loads.load_entries) 153 if (! recorded_loads.load_entries)
154 { 154 {
155 return -SOS_ENOMEM; 155 return -SOS_ENOMEM;
156 } 156 }
157 157
158 158
159 load_1mn.max_entries = 60; 159 load_1mn.max_entries = 60;
160 load_5mn.max_entries = 300; 160 load_5mn.max_entries = 300;
161 load_15mn.max_entries = 900; 161 load_15mn.max_entries = 900;
162 162
163 163
164 sos_time_init_action(& calcload_timeout); 164 sos_time_init_action(& calcload_timeout);
165 period.sec = 1; period.nanosec = 0; 165 period.sec = 1; period.nanosec = 0;
166 return sos_time_register_action_relative(& c 166 return sos_time_register_action_relative(& calcload_timeout,
167 & p 167 & period,
168 cal 168 calcload_routine,
169 NUL 169 NULL);
170 } 170 }
171 171
172 172
173 173
174 static void update_sliding_window(struct slidi 174 static void update_sliding_window(struct sliding_window *w)
175 { 175 {
176 176
177 177
178 178
179 179
180 180
181 w->sigma_nb_ticks += current_load_e 181 w->sigma_nb_ticks += current_load_entry.nb_ticks;
182 w->sigma_nb_user_running += current_load_e 182 w->sigma_nb_user_running += current_load_entry.nb_user_running;
183 w->sigma_nb_kernel_running += current_load_e 183 w->sigma_nb_kernel_running += current_load_entry.nb_kernel_running;
184 w->sigma_nb_user_ready += current_load_e 184 w->sigma_nb_user_ready += current_load_entry.nb_user_ready;
185 w->sigma_nb_kernel_ready += current_load_e 185 w->sigma_nb_kernel_ready += current_load_entry.nb_kernel_ready;
186 186
187 187
188 188
189 if (w->nb_entries < w->max_entries) 189 if (w->nb_entries < w->max_entries)
190 { 190 {
191 w->nb_entries ++; 191 w->nb_entries ++;
192 } 192 }
193 else 193 else
194 { 194 {
195 struct load_entry * oldest_entry; 195 struct load_entry * oldest_entry;
196 oldest_entry = LOAD_GET_ENTRY(recorded_l 196 oldest_entry = LOAD_GET_ENTRY(recorded_loads, w->nb_entries - 1);
197 w->sigma_nb_ticks -= oldest_ent 197 w->sigma_nb_ticks -= oldest_entry->nb_ticks;
198 w->sigma_nb_user_running -= oldest_ent 198 w->sigma_nb_user_running -= oldest_entry->nb_user_running;
199 w->sigma_nb_kernel_running -= oldest_ent 199 w->sigma_nb_kernel_running -= oldest_entry->nb_kernel_running;
200 w->sigma_nb_user_ready -= oldest_ent 200 w->sigma_nb_user_ready -= oldest_entry->nb_user_ready;
201 w->sigma_nb_kernel_ready -= oldest_ent 201 w->sigma_nb_kernel_ready -= oldest_entry->nb_kernel_ready;
202 } 202 }
203 } 203 }
204 204
205 205
206 206
207 static void calcload_routine(struct sos_timeou 207 static void calcload_routine(struct sos_timeout_action *a)
208 { 208 {
209 struct load_entry * new_head; 209 struct load_entry * new_head;
210 struct sos_time delay; 210 struct sos_time delay;
211 211
212 if (! recorded_loads.load_entries) 212 if (! recorded_loads.load_entries)
213 return; 213 return;
214 214
215 215
216 update_sliding_window(& load_1mn); 216 update_sliding_window(& load_1mn);
217 update_sliding_window(& load_5mn); 217 update_sliding_window(& load_5mn);
218 update_sliding_window(& load_15mn); 218 update_sliding_window(& load_15mn);
219 219
220 220
221 recorded_loads.most_recent 221 recorded_loads.most_recent
222 = (recorded_loads.most_recent + 1) % recor 222 = (recorded_loads.most_recent + 1) % recorded_loads.max_entries;
223 223
224 224
225 new_head = & recorded_loads.load_entries[rec 225 new_head = & recorded_loads.load_entries[recorded_loads.most_recent];
226 memcpy(new_head, & current_load_entry, sizeo 226 memcpy(new_head, & current_load_entry, sizeof(current_load_entry));
227 227
228 228
229 memset(& current_load_entry, 0x0, sizeof(cur 229 memset(& current_load_entry, 0x0, sizeof(current_load_entry));
230 230
231 231
232 delay.sec = 1; 232 delay.sec = 1;
233 delay.nanosec = 0; 233 delay.nanosec = 0;
234 sos_time_register_action_relative(a, & delay 234 sos_time_register_action_relative(a, & delay, calcload_routine, NULL);
235 } 235 }
236 236
237 237
238 sos_ret_t sos_load_do_timer_tick(sos_bool_t cu 238 sos_ret_t sos_load_do_timer_tick(sos_bool_t cur_is_user,
239 sos_ui32_t nb 239 sos_ui32_t nb_user_ready,
240 sos_ui32_t nb 240 sos_ui32_t nb_kernel_ready)
241 { 241 {
242 sos_ui32_t flags; 242 sos_ui32_t flags;
243 243
244 sos_disable_IRQs(flags); 244 sos_disable_IRQs(flags);
245 current_load_entry.nb_ticks ++; 245 current_load_entry.nb_ticks ++;
246 current_load_entry.nb_user_ready += nb_user_ 246 current_load_entry.nb_user_ready += nb_user_ready;
247 current_load_entry.nb_kernel_ready += nb_ker 247 current_load_entry.nb_kernel_ready += nb_kernel_ready;
248 if (cur_is_user) 248 if (cur_is_user)
249 current_load_entry.nb_user_running ++; 249 current_load_entry.nb_user_running ++;
250 else 250 else
251 current_load_entry.nb_kernel_running ++; 251 current_load_entry.nb_kernel_running ++;
252 sos_restore_IRQs(flags); 252 sos_restore_IRQs(flags);
253 253
254 return SOS_OK; 254 return SOS_OK;
255 } 255 }
256 256
257 257
258 void sos_load_to_string(char dest[11], sos_ui3 258 void sos_load_to_string(char dest[11], sos_ui32_t load_value)
259 { 259 {
260 sos_bool_t print0 = FALSE; 260 sos_bool_t print0 = FALSE;
261 sos_ui32_t d; 261 sos_ui32_t d;
262 262
263 #define PUTCH(c) ({ *dest = (c); dest ++; }) 263 #define PUTCH(c) ({ *dest = (c); dest ++; })
264 264
265 for (d = 1000000000UL ; d > 0 ; d /= 10) 265 for (d = 1000000000UL ; d > 0 ; d /= 10)
266 { 266 {
267 sos_ui32_t digit = (load_value / d) % 10 267 sos_ui32_t digit = (load_value / d) % 10;
268 268
269 if (digit > 0) 269 if (digit > 0)
270 { 270 {
271 PUTCH(digit + '0'); 271 PUTCH(digit + '0');
272 print0 = TRUE; 272 print0 = TRUE;
273 } 273 }
274 else if (print0) 274 else if (print0)
275 PUTCH('0'); 275 PUTCH('0');
276 276
277 if (d == SOS_LOAD_DISPLAY_MULTIPLICATION 277 if (d == SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR)
278 { 278 {
279 if (! print0) 279 if (! print0)
280 PUTCH('0'); 280 PUTCH('0');
281 281
282 PUTCH('.'); 282 PUTCH('.');
283 print0 = TRUE; 283 print0 = TRUE;
284 } 284 }
285 } 285 }
286 *dest = '\0'; 286 *dest = '\0';
287 } 287 }
288 288
289 289
290 void sos_load_get_uload(sos_ui32_t * _load_1mn 290 void sos_load_get_uload(sos_ui32_t * _load_1mn,
291 sos_ui32_t * _load_5mn 291 sos_ui32_t * _load_5mn,
292 sos_ui32_t * _load_15m 292 sos_ui32_t * _load_15mn)
293 { 293 {
294 sos_ui32_t flags; 294 sos_ui32_t flags;
295 295
296 if (load_1mn.sigma_nb_ticks < 1) 296 if (load_1mn.sigma_nb_ticks < 1)
297 return; 297 return;
298 298
299 sos_disable_IRQs(flags); 299 sos_disable_IRQs(flags);
300 *_load_1mn = ( load_1mn.sigma_nb_user_ready 300 *_load_1mn = ( load_1mn.sigma_nb_user_ready
301 + load_1mn.sigma_nb_user_run 301 + load_1mn.sigma_nb_user_running)
302 * SOS_LOAD_DISPLAY_MULTIPLICAT 302 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
303 / load_1mn.sigma_nb_ticks; 303 / load_1mn.sigma_nb_ticks;
304 *_load_5mn = ( load_5mn.sigma_nb_user_ready 304 *_load_5mn = ( load_5mn.sigma_nb_user_ready
305 + load_5mn.sigma_nb_user_run 305 + load_5mn.sigma_nb_user_running)
306 * SOS_LOAD_DISPLAY_MULTIPLICAT 306 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
307 / load_5mn.sigma_nb_ticks; 307 / load_5mn.sigma_nb_ticks;
308 *_load_15mn = ( load_15mn.sigma_nb_user_rea 308 *_load_15mn = ( load_15mn.sigma_nb_user_ready
309 + load_15mn.sigma_nb_user_r 309 + load_15mn.sigma_nb_user_running)
310 * SOS_LOAD_DISPLAY_MULTIPLICA 310 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
311 / load_15mn.sigma_nb_ticks; 311 / load_15mn.sigma_nb_ticks;
312 sos_restore_IRQs(flags); 312 sos_restore_IRQs(flags);
313 } 313 }
314 314
315 315
316 void sos_load_get_sload(sos_ui32_t * _load_1mn 316 void sos_load_get_sload(sos_ui32_t * _load_1mn,
317 sos_ui32_t * _load_5mn 317 sos_ui32_t * _load_5mn,
318 sos_ui32_t * _load_15m 318 sos_ui32_t * _load_15mn)
319 { 319 {
320 sos_ui32_t flags; 320 sos_ui32_t flags;
321 321
322 if (load_1mn.sigma_nb_ticks < 1) 322 if (load_1mn.sigma_nb_ticks < 1)
323 return; 323 return;
324 324
325 325
326 SOS_ASSERT_FATAL(load_1mn.sigma_nb_kernel_re 326 SOS_ASSERT_FATAL(load_1mn.sigma_nb_kernel_ready
327 + load_1mn.sigma_nb_kernel_ 327 + load_1mn.sigma_nb_kernel_running
328 >= load_1mn.sigma_nb_ticks) 328 >= load_1mn.sigma_nb_ticks);
329 329
330 330
331 sos_disable_IRQs(flags); 331 sos_disable_IRQs(flags);
332 *_load_1mn = ( load_1mn.sigma_nb_kernel_rea 332 *_load_1mn = ( load_1mn.sigma_nb_kernel_ready
333 + load_1mn.sigma_nb_kernel_r 333 + load_1mn.sigma_nb_kernel_running
334 - load_1mn.sigma_nb_ticks) 334 - load_1mn.sigma_nb_ticks)
335 * SOS_LOAD_DISPLAY_MULTIPLICAT 335 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
336 / load_1mn.sigma_nb_ticks; 336 / load_1mn.sigma_nb_ticks;
337 *_load_5mn = ( load_5mn.sigma_nb_kernel_rea 337 *_load_5mn = ( load_5mn.sigma_nb_kernel_ready
338 + load_5mn.sigma_nb_kernel_r 338 + load_5mn.sigma_nb_kernel_running
339 - load_5mn.sigma_nb_ticks) 339 - load_5mn.sigma_nb_ticks)
340 * SOS_LOAD_DISPLAY_MULTIPLICAT 340 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
341 / load_5mn.sigma_nb_ticks; 341 / load_5mn.sigma_nb_ticks;
342 *_load_15mn = ( load_15mn.sigma_nb_kernel_r 342 *_load_15mn = ( load_15mn.sigma_nb_kernel_ready
343 + load_15mn.sigma_nb_kernel 343 + load_15mn.sigma_nb_kernel_running
344 - load_15mn.sigma_nb_ticks) 344 - load_15mn.sigma_nb_ticks)
345 * SOS_LOAD_DISPLAY_MULTIPLICA 345 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
346 / load_15mn.sigma_nb_ticks; 346 / load_15mn.sigma_nb_ticks;
347 sos_restore_IRQs(flags); 347 sos_restore_IRQs(flags);
348 } 348 }
349 349
350 350
351 void sos_load_get_uratio(sos_ui32_t * _load_1m 351 void sos_load_get_uratio(sos_ui32_t * _load_1mn,
352 sos_ui32_t * _load_5m 352 sos_ui32_t * _load_5mn,
353 sos_ui32_t * _load_15 353 sos_ui32_t * _load_15mn)
354 { 354 {
355 sos_ui32_t flags; 355 sos_ui32_t flags;
356 356
357 if (load_1mn.sigma_nb_ticks < 1) 357 if (load_1mn.sigma_nb_ticks < 1)
358 return; 358 return;
359 359
360 sos_disable_IRQs(flags); 360 sos_disable_IRQs(flags);
361 *_load_1mn = load_1mn.sigma_nb_user_running 361 *_load_1mn = load_1mn.sigma_nb_user_running
362 * 100 * SOS_LOAD_DISPLAY_MULTI 362 * 100 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
363 / load_1mn.sigma_nb_ticks; 363 / load_1mn.sigma_nb_ticks;
364 *_load_5mn = load_5mn.sigma_nb_user_running 364 *_load_5mn = load_5mn.sigma_nb_user_running
365 * 100 * SOS_LOAD_DISPLAY_MULTI 365 * 100 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
366 / load_5mn.sigma_nb_ticks; 366 / load_5mn.sigma_nb_ticks;
367 *_load_15mn = load_15mn.sigma_nb_user_runni 367 *_load_15mn = load_15mn.sigma_nb_user_running
368 * 100 * SOS_LOAD_DISPLAY_MULT 368 * 100 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
369 / load_15mn.sigma_nb_ticks; 369 / load_15mn.sigma_nb_ticks;
370 sos_restore_IRQs(flags); 370 sos_restore_IRQs(flags);
371 } 371 }
372 372
373 373
374 void sos_load_get_sratio(sos_ui32_t * _load_1m 374 void sos_load_get_sratio(sos_ui32_t * _load_1mn,
375 sos_ui32_t * _load_5m 375 sos_ui32_t * _load_5mn,
376 sos_ui32_t * _load_15 376 sos_ui32_t * _load_15mn)
377 { 377 {
378 sos_ui32_t flags; 378 sos_ui32_t flags;
379 379
380 if (load_1mn.sigma_nb_ticks < 1) 380 if (load_1mn.sigma_nb_ticks < 1)
381 return; 381 return;
382 382
383 383
384 384
385 sos_disable_IRQs(flags); 385 sos_disable_IRQs(flags);
386 *_load_1mn = load_1mn.sigma_nb_kernel_runni 386 *_load_1mn = load_1mn.sigma_nb_kernel_running
387 * 100 * SOS_LOAD_DISPLAY_MULTI 387 * 100 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
388 / load_1mn.sigma_nb_ticks; 388 / load_1mn.sigma_nb_ticks;
389 *_load_5mn = load_5mn.sigma_nb_kernel_runni 389 *_load_5mn = load_5mn.sigma_nb_kernel_running
390 * 100 * SOS_LOAD_DISPLAY_MULTI 390 * 100 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
391 / load_5mn.sigma_nb_ticks; 391 / load_5mn.sigma_nb_ticks;
392 *_load_15mn = load_15mn.sigma_nb_kernel_run 392 *_load_15mn = load_15mn.sigma_nb_kernel_running
393 * 100 * SOS_LOAD_DISPLAY_MULT 393 * 100 * SOS_LOAD_DISPLAY_MULTIPLICATION_FACTOR
394 / load_15mn.sigma_nb_ticks; 394 / load_15mn.sigma_nb_ticks;
395 sos_restore_IRQs(flags); 395 sos_restore_IRQs(flags);
396 } 396 }