This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

pthread application consumes 100% CPU


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]