strace scheduling fairness

Denys Vlasenko dvlasenk at redhat.com
Tue May 15 15:09:21 UTC 2012


#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define NTHD 10
static int thd_no;
static void *sub_thd(void *c) {
         printf("thread created: %d\n", ++thd_no);
         for (;;) getuid();
         return NULL;
}
int main(int argc, char **argv) {
         int i;
         pthread_t thd;
         for (i = 0; i < NTHD; i++)
                 pthread_create(&thd, NULL, sub_thd, NULL);
         sleep(1);
         return 0;
}

The above program runs like this:

$ gcc -lpthread -Wall test.c
$ ./a.out
thread created: 3
thread created: 1
thread created: 2
thread created: 4
thread created: 6
thread created: 7
thread created: 8
thread created: 5
thread created: 9
thread created: 10

But under strace it most of the time never finishes:

$ strace -f -o /dev/null ./a.out
thread created: 1
thread created: 2
thread created: 3
thread created: 4
<...big pause...>
thread created: 5
<...waits forever...>

Testcase essentially starts threads, each if which does this:

         for (;;) getuid();

Since getuid is a very cheap syscall, it finishes very quickly.

When there are 2-3 such threads, strace's waitpid() picks up one, restarts it,
picks another, restarts it, ...and meanwhile first thread stops again at
syscall entry/exit and is ready to be picked up again.

It may happen so that the very first thread, which starts all others, even
though it is also ready to be handled by strace, will never be picked up
because there is always at least one other getuid'ing thread, and that thread
gets picked up instead.

One solution is to run waitpid() in a loop until it returns 0 "no more tracees
to wait", then handle them all. It was NAKed a few years ago.

Do we want to fix it, of do we chalk it to
"thread scheduling fairness is busted up under strace, won't fix"?

-- 
vda




More information about the Strace-devel mailing list