2010-05-21 14:02:54 pthreads and nice (process priority works backwards?)
Steve Strobel (UNITED STATES)
Message: 89645
After upgrading one of our projects from uClinux-dist-2008R1.5-RC3 to uClinux-dist-2009R1.1-RC4 it seems that the process priorities for a task started in a pthread work differently (and it seems to me, wrong).
The main task is started with a low priority with the command "nice -n 10 core". It then uses pthread_create to start a background thread that polls a UART for incoming data every 4mS, which is often enough to prevent overflows (it is legacy code and should be rewritten as a proper driver, but that is another subject).
Before going into a while(1) loop with a call to nanosleep to control the polling interval, in the past it has called "nice(-40)" to increase the process priority as much as possible (set it to the most negative number in the -20 to +20 range). After switching to 2009R1.1-RC4, that no longer seems to work (the polling interval varies from about 8mS to more than 20mS). The thing that really confuses me is that changing the call to nice to "nice(20)" seems to make it work well, polling at 3 to 5mS intervals; it seems to me that a priority value of 20 should be the lowest priority and give very inconsistent and long polling intervals rather than improving things.
The same thing happens (the polling interval improves) if we use "renice -n 20 -p 222" from the command line. Using renice to set the priority to -20 does not (like I think it should). In other words, renice from the command line works similarly to the nice function call, and both of them seem wrong in the new distribution. I wondered if the priority numbers were consistently messed up (maybe negated or something), but running renice on other processes works exactly as it should (and as it did before).
Using a priority value of 20 seems to work fine, so I don't really have a problem that needs fixed, but I would like to understand what changed. More details follow...
The pthread is started like this:
pthread_t threadID;
void * arg = NULL;
pthread_create(&threadID,NULL,BufferedUART::PollUART,arg);
The polling routine:
/*static*/ void * BufferedUART::PollUART( void * args )
{
#if 0 // this used to work in uClinux-dist-2008R1.5-RC3
nice(-40);
#else // this works (but shouldn't?) in uClinux-dist-2009R1.1-RC4
nice(20);
#endif
while(1)
{
// poll the uart and put received data into a thread-safe queue
// nanosleep for 4 milliseconds
}
}
The nanosleep is implemented like this:
// sleep for 4 milliseconds
uint32_t delay_in_mS = 2; // set this to 2 to get 4 mS delay,
// 4 to get 8 mS delay
// 500 to get 504 mS delay
struct timespec req;
req.tv_sec = delay_in_mS/1000;
req.tv_nsec = (delay_in_mS%1000)*1000000;
nanosleep(&req, NULL);
I don't know if this is related or not, but top and ps indicate that two new processes get created with the call to pthread_create(). Maybe that is typical for a pthread, but I don't understand why. It makes figuring out which PID to use with renice more difficult.
Steve
QuoteReplyEditDelete
2011-03-21 14:22:42 Re: pthreads and nice (process priority works backwards?)
Stefan Wanja (GERMANY)
Message: 99105
Hey Steve,
I believe to see the same behaviour. Did you find out anything about this by now?
Kind Regards,
Stefan
QuoteReplyEditDelete
2011-03-21 16:13:57 Re: pthreads and nice (process priority works backwards?)
Steve Strobel (UNITED STATES)
Message: 99106
Nothing new. It continues to work when we set up the high priority thread with "nice(20)", so we just keep using it that way We are still using Linux release 2.6.28.10-ADI-2009R1.1. When we update, we will check it again.
Steve