[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[microblaze-uclinux] pthread_mutex_[un]lock - I have a bad feeling about this



Hi,

Looking at
http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/archive/2004/08/msg00
084.html I'd like to know if the problems have been fixed in the meanwhile.
Have things been fixed in the pthread lib since that mail?

Background: I have two threads just looping infinitely and inverting an LED
state every 1 second, it means I see 2 LEDs blinking. Both threads
constantly must check the time by calling gettimeofday() to find out the
switch-time. Since I read that function is not thread-safe I secure the call
to it with a mutex.
Now the effect is after 3 to 15 seconds one of the threads has locked
forever, obviously on that mutex. It's undeterminated which thread will
block, the other thread keeps on blinking.

Here's the 'ps' and logfile output of my application:

/usr> /bin/XXXXYYYY &
[56]
/usr> ps
  PID PORT STAT  SIZE SHARED %CPU COMMAND
    1      S      85K     0K 99.9 /sbin/init
    2      S       0K     0K  0.0 keventd
    3      S       0K     0K 99.9 ksoftirqd_CPU0
    4      S       0K     0K  0.0 kswapd
    5      S       0K     0K  0.0 bdflush
    6      S       0K     0K 99.9 kupdated
    7      S       0K     0K 99.9 mtdblockd
   15   S0 R     140K     0K  0.1 /bin/sh
   56   S0 S    3699K     0K 10.7 /bin/XXXXYYYY
   57   S0 S    3699K     0K  0.0 /bin/XXXXYYYY
   58   S0 S    3699K     0K 18.3 /bin/XXXXYYYY
   59   S0 R    3699K     0K 85.2 /bin/XXXXYYYY
/usr>cat vs.log
   y  m  d  h  m  s  ms
0000/00/00 01:28:42:741: calling run_io()
0000/00/00 01:28:42:749: calling run_service()
0000/00/00 01:28:42:769: ---> IDLE
0000/00/00 01:29:04:781: io: service thread not running! last state=1


It's also not clear to me why the sleeping thread (58) still has 18.3% CPU
load.
The crucial part of my test code is attached to this mail.
The files in uClibc/libpthread/linuxthreads/sysdeps/microblaze have a
modification time 24/01/2005.



Mit freundlichen Grüßen / Best regards

Falk Brettschneider
___________________________________

  Dipl.-Inform. Falk Brettschneider
  Softwareentwickler / Software Developer
  Baumer Optronic GmbH
  http://www.baumeroptronic.de
 

void run_io()
{
...
    while (!g_ioThread.bDoExit) {
        ioThreadState = 1;
        if (b_uelapsed(&ioBlinkTime) > 1000000) { // heart-beat of io task
            static int onOff = 0;
            ioThreadState = 2;
            b_gettimeofday(&ioBlinkTime, NULL);
            ioThreadState = 3;
            onOff = (onOff==1) ? 0 : 1;
            digio_LED(eLedPower, onOff);
            ioThreadState = 4;
        }
        ioThreadState = 5;
        bIoThreadRunning = true;
        if (bServiceThreadRunning && (b_uelapsed(&servIFaceBlinkTime) > 5000000)) {
            ioThreadState = 6;
            bServiceThreadRunning = false;
            b_log("io: service thread not running! last state=%d\r\n", serviceThreadState);
        }
        ...
        ioThreadState = 15;
        if (sched_yield() == -1) {
            b_warning("io: sched_yield failed\r\n");
        }
        ioThreadState = 16;
    }
}

void run_service()
{
...
    while (!g_serviceThread.bDoExit)
    {
#ifndef _APPSUITE
        serviceThreadState = 1;
        if (b_uelapsed(&servIFaceBlinkTime) > 1000000) { // heart-beat of service task (1sec)
            serviceThreadState = 2;
            b_gettimeofday(&servIFaceBlinkTime, NULL);
            serviceThreadState = 3;
            onOff = (onOff==1) ? 0 : 1;
            digio_LED(eLedFail, onOff);
            serviceThreadState = 4;
        }
        serviceThreadState = 5;
        bServiceThreadRunning = true;
        serviceThreadState = 6;
        if (bIoThreadRunning && (b_uelapsed(&ioBlinkTime) > 5000000)) {
            bIoThreadRunning = false;
            b_log("serv: io thread not running! last state=%d\r\n", ioThreadState);
        }
        serviceThreadState = 7;
        ...
        if (sched_yield() == -1) {
            b_warning("service: sched_yield failed\r\n");
        }
        serviceThreadState = 11;
    }
}

pthread_mutex_t s_accessToken;

void b_gettimeofday(struct timeval* tv, void* p)
{
    static bool bFirstTime = true;

    if (bFirstTime) {
        bFirstTime = false;
        pthread_mutex_init(&s_accessToken, 0);
    }

    pthread_mutex_lock(&s_accessToken); /* gettimeofday is not thread-safe! */
    gettimeofday(tv, p);
    pthread_mutex_unlock(&s_accessToken);
}

unsigned int b_uelapsed(struct timeval* startTime)
{
    unsigned int diff;
    struct timezone timezone;
    struct timeval curTime;
    b_gettimeofday(&curTime, &timezone);

    diff = 1000000 * (curTime.tv_sec - startTime->tv_sec);
    diff += curTime.tv_usec - startTime->tv_usec;
    return diff;
}