mercredi 23 janvier 2019

Using CLOCK_MONOTONIC type in the 'condition variable' wait_for() notify() mechanism

I am using code that runs on ARM (not Intel processor). Running c++11 code example (CODE A) from: http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/ to test the wait_for() mechanism. This is not working right - looks like the wait_for() does not wait. In Intel works fine. After some research and using pthread library directly and setting MONOTONIC_CLOCK definition, solves the issue (CODE B).

How can I force the C++11 API wait_for() to work with MONOTONIC_CLOCK?

Actually I would like to stay with 'CODE A' but with the support or setting of MONOTONIC_CLOCK. Thanks

CODE A

// condition_variable::wait_for example
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>             // std::chrono::seconds
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status

std::condition_variable cv;

int value;

void read_value() {
  std::cin >> value;
  cv.notify_one();
}

int main ()
{
  std::cout << "Please, enter an integer (I'll be printing dots): \n";
  std::thread th (read_value);

  std::mutex mtx;
  std::unique_lock<std::mutex> lck(mtx);
  while 
(cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout)        
{
    std::cout << '.' << std::endl;
  }
  std::cout << "You entered: " << value << '\n';

  th.join();

  return 0;
}

CODE B

#include <sys/time.h>
#include <unistd.h> 
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>             // std::chrono::seconds
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status

const size_t NUMTHREADS = 1;

pthread_mutex_t mutex;
pthread_cond_t cond;

int value;
bool done = false;

void* read_value( void* id )
{
    const int myid = (long)id; // force the pointer to be a 64bit integer
    std::cin >> value;
    done = true;
    printf( "[thread %d] done is now %d. Signalling cond.\n", myid, done 
);
    pthread_cond_signal( &cond ); 

}

int main ()
{

    struct timeval  now;

    pthread_mutexattr_t Attr;
    pthread_mutexattr_init(&Attr);
    pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&mutex, &Attr);

    pthread_condattr_t CaAttr;
    pthread_condattr_init(&CaAttr);
    pthread_condattr_setclock(&CaAttr, CLOCK_MONOTONIC);
    pthread_cond_init(&cond, &CaAttr);

    std::cout << "Please, enter an integer:\n";
    pthread_t threads[NUMTHREADS];
    int t = 0;
    pthread_create( &threads[t], NULL, read_value, (void*)(long)t );

    struct timespec ts;

    pthread_mutex_lock( &mutex );
    int rt = 0;

    while( !done )
    {
        clock_gettime(CLOCK_MONOTONIC, &ts);
        ts.tv_sec += 1;

        rt = pthread_cond_timedwait( & cond, & mutex, &ts );
        std::cout << "..." << std::endl;
    }

    pthread_mutex_unlock( & mutex );
    std::cout << "You entered: " << value << '\n';

    return 0;

}

Aucun commentaire:

Enregistrer un commentaire