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