5784 } else {
5785 return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
5786 }
5787 }
5788
5789 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
5790 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
5791 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
5792 } else {
5793 return slow_thread_cpu_time(thread, user_sys_cpu_time);
5794 }
5795 }
5796
5797 //
5798 // -1 on error.
5799 //
5800
5801 PRAGMA_DIAG_PUSH
5802 PRAGMA_FORMAT_NONLITERAL_IGNORED
5803 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
5804 static bool proc_task_unchecked = true;
5805 pid_t tid = thread->osthread()->thread_id();
5806 char *s;
5807 char stat[2048];
5808 int statlen;
5809 char proc_name[64];
5810 int count;
5811 long sys_time, user_time;
5812 char cdummy;
5813 int idummy;
5814 long ldummy;
5815 FILE *fp;
5816
5817 snprintf(proc_name, 64, "/proc/%d/stat", tid);
5818
5819 // The /proc/<tid>/stat aggregates per-process usage on
5820 // new Linux kernels 2.6+ where NPTL is supported.
5821 // The /proc/self/task/<tid>/stat still has the per-thread usage.
5822 // See bug 6328462.
5823 // There possibly can be cases where there is no directory
5824 // /proc/self/task, so we check its availability.
5825 if (proc_task_unchecked && os::Linux::is_NPTL()) {
5826 // This is executed only once
5827 proc_task_unchecked = false;
5828 fp = fopen("/proc/self/task", "r");
5829 if (fp != NULL) {
5830 snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
5831 fclose(fp);
5832 }
5833 }
5834
5835 fp = fopen(proc_name, "r");
5836 if ( fp == NULL ) return -1;
5837 statlen = fread(stat, 1, 2047, fp);
5838 stat[statlen] = '\0';
5839 fclose(fp);
5840
5841 // Skip pid and the command string. Note that we could be dealing with
5842 // weird command names, e.g. user could decide to rename java launcher
5843 // to "java 1.4.2 :)", then the stat file would look like
5844 // 1234 (java 1.4.2 :)) R ... ...
5845 // We don't really need to know the command string, just find the last
5846 // occurrence of ")" and then start parsing from there. See bug 4726580.
5847 s = strrchr(stat, ')');
5848 if (s == NULL ) return -1;
5849
5850 // Skip blank chars
5851 do s++; while (isspace(*s));
5852
5853 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
5854 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
|
5784 } else {
5785 return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
5786 }
5787 }
5788
5789 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
5790 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
5791 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
5792 } else {
5793 return slow_thread_cpu_time(thread, user_sys_cpu_time);
5794 }
5795 }
5796
5797 //
5798 // -1 on error.
5799 //
5800
5801 PRAGMA_DIAG_PUSH
5802 PRAGMA_FORMAT_NONLITERAL_IGNORED
5803 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
5804 pid_t tid = thread->osthread()->thread_id();
5805 char *s;
5806 char stat[2048];
5807 int statlen;
5808 char proc_name[64];
5809 int count;
5810 long sys_time, user_time;
5811 char cdummy;
5812 int idummy;
5813 long ldummy;
5814 FILE *fp;
5815
5816 snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
5817 fp = fopen(proc_name, "r");
5818 if ( fp == NULL ) return -1;
5819 statlen = fread(stat, 1, 2047, fp);
5820 stat[statlen] = '\0';
5821 fclose(fp);
5822
5823 // Skip pid and the command string. Note that we could be dealing with
5824 // weird command names, e.g. user could decide to rename java launcher
5825 // to "java 1.4.2 :)", then the stat file would look like
5826 // 1234 (java 1.4.2 :)) R ... ...
5827 // We don't really need to know the command string, just find the last
5828 // occurrence of ")" and then start parsing from there. See bug 4726580.
5829 s = strrchr(stat, ')');
5830 if (s == NULL ) return -1;
5831
5832 // Skip blank chars
5833 do s++; while (isspace(*s));
5834
5835 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
5836 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
|