Merge branch '138-toggle-free-look-with-hotkey' into 'main/atys-live'
[ryzomcore.git] / nel / src / misc / cpu_time_stat.cpp
blobb61e07825ec21859c7f19199152e143528af5361
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdmisc.h"
22 #include "nel/misc/cpu_time_stat.h"
23 #include "nel/misc/common.h"
24 #include "nel/misc/debug.h"
26 #ifdef NL_OS_UNIX
27 #include <unistd.h>
28 #else
29 #include <process.h>
30 #endif
32 using namespace std;
34 #ifdef DEBUG_NEW
35 #define new DEBUG_NEW
36 #endif
38 namespace NLMISC
42 // Get absolute ticks value for the whole cpu set
43 bool CCPUTimeStat::getCPUTicks(uint64& user, uint64& nice, uint64& system, uint64& idle, uint64& iowait)
45 #ifdef NL_OS_UNIX
47 const char* statfile = "/proc/stat";
48 FILE* f = nlfopen(statfile, "r");
50 if (f == NULL)
51 return false;
53 // /proc/stat
54 // cpu [user] [nice] [system] [idle] [iowait] [irq] [softirq]
55 if (fscanf(f, "cpu %" NL_I64 "u %" NL_I64 "u %" NL_I64 "u %" NL_I64 "u %" NL_I64 "u", &user, &nice, &system, &idle, &iowait) != 5)
56 nlwarning("Failed to parse /proc/stat");
58 fclose(f);
60 return true;
61 #else
62 return false;
63 #endif
66 // Get absolute ticks values for a specified pid
67 bool CCPUTimeStat::getPIDTicks(uint64& utime, uint64& stime, uint64& cutime, uint64& cstime, uint pid)
69 #ifdef NL_OS_UNIX
71 std::string statfile = NLMISC::toString("/proc/%u/stat", pid);
72 FILE* f = nlfopen(statfile, "r");
74 if (f == NULL)
75 return false;
77 // /proc/<pid>/stat
78 // pid com sta ppi pgi ses tty tpg fla mif maf cmi cma [utime] [stime] [cutime] [cstime] ...
79 if (fscanf(f, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %" NL_I64 "u %" NL_I64 "u %" NL_I64 "u %" NL_I64 "u", &utime, &stime, &cutime, &cstime) != 4)
80 nlwarning("Failed to parse /proc/<pid>/stat");
82 fclose(f);
84 return true;
85 #else
86 utime = 0;
87 stime = 0;
88 cutime = 0;
89 cstime = 0;
90 nlunreferenced(pid);
91 return false;
92 #endif
95 CCPUTimeStat::CCPUTimeStat() : _PID(0), _FirstTime(true), _LastCPUTicks(0), _LastPIDTicks(0)
97 #ifdef NL_OS_UNIX
99 _PID = getpid();
101 #else
103 _PID = _getpid();
105 #endif
110 // Peek measure
111 void CCPUTimeStat::peekMeasures()
113 NLMISC::TTime ctime = NLMISC::CTime::getLocalTime();
115 uint64 u, n, s, i, io;
116 uint64 ut, st, cut, cst;
117 if (getCPUTicks(u, n, s, i, io) && getPIDTicks(ut, st, cut, cst, _PID))
119 uint64 cpuTicks = u+n+s+i+io;
120 uint64 pidTicks = ut+st+cut+cst;
122 // only compute diff
123 if (_LastCPUTicks == cpuTicks || _LastPIDTicks == pidTicks)
124 return;
126 _LastCPUTicks = cpuTicks;
127 _CPUUser.computeDiff(u);
128 _CPUNice.computeDiff(n);
129 _CPUSystem.computeDiff(s);
130 _CPUIdle.computeDiff(i);
131 _CPUIOWait.computeDiff(io);
133 _LastPIDTicks = pidTicks;
134 _PIDUTime.computeDiff(ut);
135 _PIDSTime.computeDiff(st);
136 _PIDCUTime.computeDiff(cut);
137 _PIDCSTime.computeDiff(cst);
139 if (!_FirstTime)
141 uint32 cpuTotal = _CPUUser.Diff+_CPUNice.Diff+_CPUSystem.Diff+_CPUIdle.Diff+_CPUIOWait.Diff;
143 _CPUUser.computeLoad(cpuTotal, ctime);
144 _CPUNice.computeLoad(cpuTotal, ctime);
145 _CPUSystem.computeLoad(cpuTotal, ctime);
146 _CPUIdle.computeLoad(cpuTotal, ctime);
147 _CPUIOWait.computeLoad(cpuTotal, ctime);
149 uint32 pidTotal = _PIDUTime.Diff+_PIDSTime.Diff+_PIDCUTime.Diff+_PIDCSTime.Diff;
150 if (pidTotal > cpuTotal)
152 // EEK! should not happen!!
153 cpuTotal = pidTotal;
156 _PIDUTime.computeLoad(cpuTotal, ctime);
157 _PIDSTime.computeLoad(cpuTotal, ctime);
158 _PIDCUTime.computeLoad(cpuTotal, ctime);
159 _PIDCSTime.computeLoad(cpuTotal, ctime);
162 _FirstTime = false;