Results 1 to 4 of 4
Reading up the man pages about pthreads, I gather that up until Linux kernel version 2.6.9, the NPTL implementation of pthreads had a "bug" which I found quite useful in ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
- 08-20-2007 #1Just Joined!
- Join Date
- Aug 2007
- Posts
- 2
pthreads : thread time vs. process time
Reading up the man pages about pthreads, I gather that up until Linux kernel version 2.6.9, the NPTL implementation of pthreads had a "bug" which I found quite useful in that times() and getrusage() would return values on a per-thread basis rather than process-wide. I was then able to know how much CPU-time had a particular thread worked. However, I understand that this was fixed in kernel 2.6.9 because it was non-conforming with the POSIX specifications. I miss this accidental feature and would like to know if there exists a method or a series of method that I could use to get that information.
I have a set of data on which I would like a bunch of threads to work for at least 2 CPU-seconds each, while I don't care about the wall time. Using process time can't work because in extreme cases, a process using 10 threads could have a single thread work for 2 seconds and all of the 10 threads would return a process-time of 2 seconds, while 9 of them didn't get a chance to work.
Did the kernel 2.6.9 fix completely remove the ability to check a thread CPU-time or did that feature get hidden in another system call of which I am unaware?
Thanks.
- 12-10-2007 #2Just Joined!
- Join Date
- Dec 2007
- Posts
- 2
Hi,
I actually had the same problem.
I found out that the function clock_gettime returns timing per thread with more or less nanosecond precision (see clock_getres() )
To link you must use -lrt.Code:#include <time.h> #include <unistd.h> // for sysconf int err; struct timespec t; if (sysconf(_POSIX_THREAD_CPUTIME)){ err = clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t); }
It works per thread, except that the time returned is the sum of system time and user time.
So there are still unanswered questions:
1. Is there a method to split the system and user times?
2. Why POSIX standard doesn't allow to use getrusage per thread?
3. Is there a way to have all getrusage measurements per thread anyway?
Greetings,
Wojtek
- 12-10-2007 #3Just Joined!
- Join Date
- Dec 2007
- Posts
- 2
Actually the program I attached does not show that the system time is added to user time by clock_gettime, but it is. I checked this in a program using the harddisk intensively.
- 12-10-2007 #4Just Joined!
- Join Date
- Aug 2007
- Posts
- 2
Ugly hack
I managed to get the user time and system time of the thread with an ugly hack which might not be as portable as I would like it to be, but still mostly works until I find a POSIX way to do it. Here's what I've done:
The pseudo-file /proc/<PID>/task/<TID>/stat file contains a lot of info about the thread TID. Reading the file will yield 42 fields which are separated by whitespace. You can find out what each field means with "man 5 proc". utime (user time) and stime (system time) are respectively the 14th and 15th fields.
All you need to do then is parse(*) the string you get from reading /proc/<PID>/task/<TID>/stat and grab the 14th field, which represents the number of jiffies spent in user-time.
(*) While parsing the string, keep in mind that the second field (executable name) can contain whitespaces)
The operation isn't very fast, so it shouldn't be done in a tight loop, but it's more accurate than what rusage can provide me, and the processing is mostly done in system time, so it doesn't skew the results.
Code:unsigned long GetThreadTime() { char procFilename[256] ; char buffer[1024] ; pid_t pid = ::getpid() ; pid_t tid = ::gettid() ; sprintf(procFilename, "/proc/%d/task/%d/stat",pid,tid) ; int fd, num_read ; fd = open(procFilename, O_RDONLY, 0); num_read = read(fd, buffer, 1023); close(fd); buffer[num_read] = '\0'; char* ptrUsr = strrchr(buffer, ')') + 1 ; for(int i = 3 ; i != 14 ; ++i) ptrUsr = strchr(ptrUsr+1, ' ') ; ptrUsr++; long jiffies_user = atol(ptrUsr) ; long jiffies_sys = atol(strchr(ptrUsr,' ') + 1) ; return jiffies_user ; }


Reply With Quote
