This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
pthread application consumes 100% CPU
- From: MOHAN JANGIRLAL <mohanlal at samsung dot com>
- To: libc-help at sourceware dot org
- Date: Mon, 11 Jan 2010 00:30:03 +0000 (GMT)
- Subject: pthread application consumes 100% CPU
- Msgkey: 20100111001335994@mohanlal
- Reply-to: mohanlal at samsung dot com
Dear list members,
This question is related to pthread API. Please direct me to correct list if this is not the one.
I am working on a 64bit MIPS based multi-core system. I am running an application where many threads are waiting on pthread_cond_timedwait while one thread is signalling using pthread_cond_signal. The source code for the application is pasted at the end of email.
When I start this application the CPU usage of each core is 30%. If I stop signalling by "kill -USR2 <pid>" (refer source code), the CPU usage falls to 0%. This looks all right and is expected behavior.
However, after continuously running this application for 6 hours, the CPU usages increases to 80%. And if I stop signalling again by "kill -USR2 <pid>", the CPU usage goes 100% (ideally it must have fallen to 0%) !!
Do you think, it could be a problem in pthread library or kernel !
uname -a
Linux 255_00_04_CP_CPU1 2.6.21.7-hrt1 #3 SMP PREEMPT Sat Jan 9 10:56:46 KST 2010 mips64 mips64 mips64 GNU/Linux
libraries:
/lib64/libc-2.5.so
/lib64/libpthread-2.5.so
Following is application source code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>
#define MAX_THREAD_CNT 32
static bool f_stop_cond_signal = true;
static void commExitHandler(int signo, siginfo_t *infoSignal, void *pData)
{
printf(" SIGUSR1:D'%d SIGUSR2:D'%d SIGTERM:D'%d, \n",SIGUSR1,SIGUSR2,SIGTERM);
switch(signo)
{
case SIGCHLD:
printf("SIGCHLD... ignore \n");
break;
case SIGUSR2:
if ( f_stop_cond_signal == true )
{
printf(" WILL STOP f_stop_cond_signal \n");
f_stop_cond_signal = false;
}
else
{
printf(" WILL SEND f_stop_cond_signal \n");
f_stop_cond_signal = true;
}
break;
case SIGTERM:
_exit(signo);
break;
default:
printf("signal:%d\n", signo);
_exit(signo);
}
return;
}
static void commRegisterExitHandler()
{
printf(" called commRegisterExitHandler . \n");
struct sigaction sigAct;
sigAct.sa_handler = (void(*)(int))commExitHandler;
sigAct.sa_sigaction = commExitHandler;
sigemptyset(&sigAct.sa_mask);
sigAct.sa_flags = SA_RESTART | SA_NOMASK | SA_SIGINFO;
for ( int32_t Idx = 1; Idx <= SIGRTMAX; Idx++)
{
if ( Idx == SIGUSR2 || Idx == SIGTERM )
{
if(sigaction(Idx, &sigAct, NULL) < 0)
{
printf("%d signal handler is not registered!\n", Idx);
}
}
}
return;
}
static unsigned int status_success[100] = {0};
static unsigned int status_etimeout[100] = {0};
static unsigned int status_others[100] = {0};
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
static void waitabit(int id)
{
struct timeval now;
struct timespec timeout;
int done, rc;
gettimeofday(&now,NULL);
timeout.tv_sec = now.tv_sec;
timeout.tv_nsec = now.tv_usec * 1000;
unsigned long arg_l_msec = 1000;
timeout.tv_sec += arg_l_msec/1000L;
done = 0;
int loopcnt = 0;
while (!done)
{
pthread_mutex_lock(&m);
rc = pthread_cond_timedwait(&c, &m, &timeout);
pthread_mutex_unlock(&m);
switch(rc)
{
case 0:
done = 1;
status_success[id]++;
break;
case ETIMEDOUT:
done = 1;
status_etimeout[id]++;
break;
default:
printf(" unex error (D'%d) \n",rc);
status_others[id]++;
if ( (loopcnt++) >= 100 )
_exit(1);
break;
}
}
return;
}
static void* run(void *arg)
{
int id = *(int*)arg;
printf(" thread D'%u \n",pthread_self());
while ( 1 )
{
waitabit(id);
}
return NULL;
}
static void* run2(void *arg)
{
while ( 1 )
{
if ( f_stop_cond_signal == true )
{
int thrcnt = 0;
for ( thrcnt = 0; thrcnt < 1; thrcnt++ )
{
int rrtn;
pthread_mutex_lock(&m);
rrtn = pthread_cond_signal(&(c));
if ( rrtn < 0 ) perror(" pthread_cond_signal fail \n");
pthread_mutex_unlock(&m);
}
}
else
sleep(1);
}
return NULL;
}
static pthread_t the_thread[100];
static int the_thread2[100];
int main()
{
commRegisterExitHandler();
int ret, thrcnt = 0;
for (thrcnt = 0; thrcnt < MAX_THREAD_CNT; thrcnt++)
{
the_thread2[thrcnt] = thrcnt;
ret = pthread_create(&the_thread[thrcnt], NULL, run, &the_thread2[thrcnt]);
if (ret != 0) { perror("pthread_create"); return 1; }
}
ret = pthread_create(&the_thread[thrcnt], NULL, run2, NULL);
while(1)
{
sleep (10);
}
return 0;
}