1 /* getidle.c - by David van Moolenbroek <dcvmoole@cs.vu.nl> */ 2 3 /* Usage: 4 * 5 * double idleperc; 6 * getidle(); 7 * ... 8 * idleperc = getidle(); 9 * if (idleperc >= 0.0) 10 * printf("CPU usage: %lg%%\n", 100.0 - idleperc); 11 * 12 * Notes: 13 * - This functionality can only be used by system processes. 14 * - Only one getidle() run is allowed per process at a time. 15 * 16 */ 17 18 #define _SYSTEM 1 19 #include <lib.h> 20 #include <minix/u64.h> 21 #include <minix/sysutil.h> 22 #include <minix/syslib.h> 23 #include <minix/minlib.h> 24 25 static u64_t start, idle; 26 static int running = 0; 27 make_double(u64_t d)28static double make_double(u64_t d) 29 { 30 /* Convert a 64-bit fixed point value into a double. 31 * This whole thing should be replaced by something better eventually. 32 */ 33 double value; 34 size_t i; 35 36 value = (double) ex64hi(d); 37 for (i = 0; i < sizeof(unsigned long); i += 2) 38 value *= 65536.0; 39 40 value += (double) ex64lo(d); 41 42 return value; 43 } 44 getidle(void)45double getidle(void) 46 { 47 u64_t stop, idle2; 48 u64_t idelta, tdelta; 49 double ifp, tfp, rfp; 50 int r; 51 52 if (!running) { 53 if ((r = sys_getidletsc(&idle)) != OK) 54 return -1.0; 55 56 running = 1; 57 58 read_tsc_64(&start); 59 60 return 0.0; 61 } 62 else { 63 read_tsc_64(&stop); 64 65 running = 0; 66 67 if ((r = sys_getidletsc(&idle2)) != OK) 68 return -1.0; 69 70 idelta = idle2 - idle; 71 tdelta = stop - start; 72 73 if (idelta >= tdelta) 74 return 100.0; 75 76 ifp = make_double(idelta); 77 tfp = make_double(tdelta); 78 79 rfp = ifp / tfp * 100.0; 80 81 if (rfp < 0.0) rfp = 0.0; 82 else if (rfp > 100.0) rfp = 100.0; 83 84 return rfp; 85 } 86 } 87