/* * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
/** /proc/[number]/stat Status information about the process. This is used by ps(1). It is defined in /usr/src/linux/fs/proc/array.c.
The fields, in order, with their proper scanf(3) format specifiers, are:
1. pid %d The process id.
2. comm %s The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out.
3. state %c One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in uninterruptible disk sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging.
4. ppid %d The PID of the parent.
5. pgrp %d The process group ID of the process.
6. session %d The session ID of the process.
7. tty_nr %d The tty the process uses.
8. tpgid %d The process group ID of the process which currently owns the tty that the process is connected to.
9. flags %lu The flags of the process. The math bit is decimal 4, and the traced bit is decimal 10.
10. minflt %lu The number of minor faults the process has made which have not required loading a memory page from disk.
11. cminflt %lu The number of minor faults that the process's waited-for children have made.
12. majflt %lu The number of major faults the process has made which have required loading a memory page from disk.
13. cmajflt %lu The number of major faults that the process's waited-for children have made.
14. utime %lu The number of jiffies that this process has been scheduled in user mode.
15. stime %lu The number of jiffies that this process has been scheduled in kernel mode.
16. cutime %ld The number of jiffies that this process's waited-for children have been scheduled in user mode. (See also times(2).)
17. cstime %ld The number of jiffies that this process' waited-for children have been scheduled in kernel mode.
18. priority %ld The standard nice value, plus fifteen. The value is never negative in the kernel.
19. nice %ld The nice value ranges from 19 (nicest) to -19 (not nice to others).
20. 0 %ld This value is hard coded to 0 as a placeholder for a removed field.
21. itrealvalue %ld The time in jiffies before the next SIGALRM is sent to the process due to an interval timer.
22. starttime %lu The time in jiffies the process started after system boot.
23. vsize %lu Virtual memory size in bytes.
24. rss %ld Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes. This is just the pages which count towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out.
25. rlim %lu Current limit in bytes on the rss of the process (usually 4294967295 on i386).
26. startcode %lu The address above which program text can run.
27. endcode %lu The address below which program text can run.
28. startstack %lu The address of the start of the stack.
29. kstkesp %lu The current value of esp (stack pointer), as found in the kernel stack page for the process.
30. kstkeip %lu The current EIP (instruction pointer).
31. signal %lu The bitmap of pending signals (usually 0).
32. blocked %lu The bitmap of blocked signals (usually 0, 2 for shells).
33. sigignore %lu The bitmap of ignored signals.
34. sigcatch %lu The bitmap of caught signals.
35. wchan %lu This is the "channel" in which the process is waiting. It is the address of a system call, and can be looked up in a namelist if you need a textual name. (If you have an up-to-date /etc/psdatabase, then try ps -l to see the WCHAN field in action.)
36. nswap %lu Number of pages swapped - not maintained.
37. cnswap %lu Cumulative nswap for child processes.
38. exit_signal %d Signal to be sent to parent when we die.
/** * For platforms that have them, when declaring * a printf-style function, * formatSpec is the parameter number (starting at 1) * that is the format argument ("%d pid %s") * params is the parameter number where the actual args to * the format starts. If the args are in a va_list, this * should be 0.
*/ #ifndef PRINTF_ARGS # define PRINTF_ARGS(formatSpec, params) ATTRIBUTE_PRINTF(formatSpec, params) #endif
/** reads /proc/<pid>/stat data, with some checks and some skips. * Ensure that 'fmt' does _NOT_ contain the first two "%d %s"
*/ staticint SCANF_ARGS(2, 0) vread_statdata(constchar* procfile, _SCANFMT_ constchar* fmt, va_list args) {
FILE*f; int n; char buf[2048];
buf[n-1] = '\0'; /** skip through pid and exec name. */ if ((tmp = strrchr(buf, ')')) != NULL) { // skip the ')' and the following space // but check that buffer is long enough
tmp += 2; if (tmp < buf + n) {
n = vsscanf(tmp, fmt, args);
}
}
}
staticint get_systemtype(void) { staticint procEntriesType = UNDETECTED;
DIR *taskDir;
if (procEntriesType != UNDETECTED) { return procEntriesType;
}
// Check whether we have a task subdirectory if ((taskDir = opendir("/proc/self/task")) == NULL) {
procEntriesType = UNDETECTABLE;
} else { // The task subdirectory exists; we're on a Linux >= 2.6 system
closedir(taskDir);
procEntriesType = LINUX26_NPTL;
}
return procEntriesType;
}
/** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */ staticint read_ticks(constchar* procfile, uint64_t* userTicks, uint64_t* systemTicks) { return read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " UINT64_FORMAT " " UINT64_FORMAT,
userTicks, systemTicks);
}
/** * Return the number of ticks spent in any of the processes belonging * to the JVM on any CPU.
*/ static OSReturn get_jvm_ticks(os::Linux::CPUPerfTicks* pticks) {
uint64_t userTicks;
uint64_t systemTicks;
if (get_systemtype() != LINUX26_NPTL) { return OS_ERR;
}
if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) { return OS_ERR;
}
// get the total if (! os::Linux::get_tick_information(pticks, -1)) { return OS_ERR;
}
/** * Return the load of the CPU as a double. 1.0 means the CPU process uses all * available time for user or system processes, 0.0 means the CPU uses all time * being idle. * * Returns a negative value if there is a problem in determining the CPU load.
*/ staticdouble get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) {
uint64_t udiff, kdiff, tdiff;
os::Linux::CPUPerfTicks* pticks;
os::Linux::CPUPerfTicks tmp; double user_load;
// seems like we sometimes end up with less kernel ticks when // reading /proc/self/stat a second time, timing issue between cpus? if (pticks->usedKernel < tmp.usedKernel) {
kdiff = 0;
} else {
kdiff = pticks->usedKernel - tmp.usedKernel;
}
tdiff = pticks->total - tmp.total;
udiff = pticks->used - tmp.used;
// First time through bootTime will be zero. if (bootTime == 0) {
uint64_t tmp; if (get_boot_time(&tmp) < 0) { return OS_ERR;
}
bt = tmp * 1000;
}
res = OS_OK;
pthread_mutex_lock(&contextSwitchLock);
{
uint64_t sw;
s8 t, d;
if (bootTime == 0) { // First interval is measured from boot time which is // seconds since the epoch. Thereafter we measure the // elapsed time using javaTimeNanos as it is monotonic- // non-decreasing.
lastTimeNanos = os::javaTimeNanos();
t = os::javaTimeMillis();
d = t - bt; // keep bootTime zero for now to use as a first-time-through flag
} else {
t = os::javaTimeNanos();
d = nanos_to_millis(t - lastTimeNanos);
}
class CPUPerformanceInterface::CPUPerformance : public CHeapObj<mtInternal> { friendclass CPUPerformanceInterface; private:
CPUPerfCounters _counters;
int cpu_load(int which_logical_cpu, double* cpu_load); int context_switch_rate(double* rate); int cpu_load_total_process(double* cpu_load); int cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad);
// For the CPU load total
os::Linux::get_tick_information(&_counters.cpus[_counters.nProcs], -1);
// For each CPU for (int i = 0; i < _counters.nProcs; i++) {
os::Linux::get_tick_information(&_counters.cpus[i], i);
} // For JVM load
get_jvm_ticks(&_counters.jvmTicks);
// initialize context switch system // the double is only for init double init_ctx_switch_rate;
perf_context_switch_rate(&init_ctx_switch_rate);
// if it has a numeric name, is a directory and has a 'stat' file in it bool SystemProcessInterface::SystemProcesses::ProcessIterator::is_valid_entry(struct dirent* entry) const { char buffer[PATH_MAX];
uint64_t size = 0;
// find out how long the file is (stat always returns 0) while (fread(&dummy, 1, 1, fp) == 1) {
size++;
} if (size > 0) {
cmdline = NEW_C_HEAP_ARRAY(char, size + 1, mtInternal);
cmdline[0] = '\0'; if (fseek(fp, 0, SEEK_SET) == 0) { if (fread(cmdline, 1, size, fp) == size) { // the file has the arguments separated by '\0', // so we translate '\0' to ' ' for (size_t i = 0; i < size; i++) { if (cmdline[i] == '\0') {
cmdline[i] = ' ';
}
}
cmdline[size] = '\0';
}
}
}
fclose(fp);
} return cmdline;
}
// get full path to exe from /proc/<pid>/exe symlink char* SystemProcessInterface::SystemProcesses::ProcessIterator::get_exe_path() { char buffer[PATH_MAX];
int SystemProcessInterface::SystemProcesses::ProcessIterator::next_process() { if (!is_valid()) { return OS_ERR;
}
do {
_entry = os::readdir(_dir); if (_entry == NULL) { // Error or reached end. Could use errno to distinguish those cases.
_valid = false; return OS_ERR;
}
} while(!is_valid_entry(_entry));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.