Find the answer to your Linux question:
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.
  1. #1
    Just 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.

  2. #2
    Just 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() )
    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);
    }
    To link you must use -lrt.
    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
    Attached Files Attached Files

  3. #3
    Just 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.

  4. $spacer_open
    $spacer_close
  5. #4
    Just Joined!
    Join Date
    Aug 2007
    Posts
    2

    Cool 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 ;
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •