Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: WaitforSingleObject in linux (source code)

Author: Vincent Diepeveen

Date: 15:40:04 04/25/01

Go up one level in this thread


On April 25, 2001 at 17:34:59, Hristo wrote:

>Following is a code that you can use for locking
>and or signaling stuff in linux.
>This is the same as WaitForSingleObject ...
>
>Example:
>// create a locked semaphore
>// with maximum of 1 lock (non counting)
>CSISemaphore g_sem(0,1);


>void thread_func(){
>  while (1){
>    // do something
>
>    // signal the semaphore that we are done
>    // you can unlock it any number of times ...
>    // it is not counting semaphore so nothing bad happens
>    g_sem.unlock();
>  }
>}
>
>//
>//
>
>int main(){
>  start_my_thread(thread_func);
>
>  while(1){
>    // wait 100 ms for the semaphore to get signaled (unlocked)
>    if (g_sem.lock(100)){
>      cout << "The semaphore was signaled..." << endl;
>      break; /// ....
>    }else{
>      cout << "." << flush;
>    }
>  }
>  return 0;
>}
>
>
>This is the actual header and source stuff that you need.
>best regards.

Many thanks.

I don't see how it works, sorry to bother you again!

I do not want to waste 100ms of time for threads.

in my main i'm doing actually not only starting threads but also
other processes.

Basically those other processes i want to idle:

P1.Main() {
  allocate shared memory;
  start other searchprocesses P2..P4;
  start i/o thread

  thisprocessnumber = P1;
  Search();
}

.. iothread() {
  for(;;) {// this thread doing i/o for all processes
    now wait for keyboard input and idle when waiting for it;
    parse_keyboard_input();

    if( relevantkeyboardinput ) { /* so i start to search */
      // now somehow wakup P1..Pn. what i do now is, is to give it
      sharedtree->gosearch = true;
    }

  }
}

/* now one example is other search */

P2.Search() { /* in main already initialized and synchronized with P1 */

  idle till you get go command and don't waste 100ms or whatever before
  receiving it as it must wake up DIRECTLY
}

In short the interesting thing is what to do for P1() to message
both a thread in the own process to start searching and to also
message other processes to start searching. Bob says
i should use Select there somehow, with what function do i message
this function?

With signal?

Note locking/unlocking i'll manage myself. i've pretty much learned
to work with locking/unlocking but not with idling yet :)

So interesting to know is how to wait for keyboard input without
wasting system time while waiting and what
function to use to message Select in other processes (and one in
the own process) that it must wake up.

So please read carefully other PROCESSES not threads!!
It's especially the IPC that worries me :)

>hristo
>
>
>--- header file ---
>/**
> * General purpose semaphore interface
> * Under unix there we are using mutex and
> * conditional variable to provide lock with
> * timeout. Since the lock with timeout is
> * not supported natively by the OS there are
> * some special issues that might occur. For
> * instance if the timeout value is not large
> * enough the thread might never accuire the
> * lock.
> *
> * @author Hristo Doichev
> * @version 0.1
> */
>class CSISemaphore{
>	public:
>        /**
>         * create a single semaphore.
>         *
>         * @param _initial determines the initial state of the semaphore.
>         *                 0 the semaphore is created and locked immediately.
>         *                 1 the semaphore is not locked within the constructor.
>         * @return
>         */
>		explicit CSISemaphore(unsigned int _initial);
>        /**
>         * create a counting Semaphore.
>         *
>         * @param _initial determines the amount of locks that can be applied to
>this semaphore
>         *                 after the cnstruction.
>         *                 0 the semaphore is completely locked.
>         *                 n <= _max is the number of loks that can be applied
>         * @param _max     the maximum number of locks this semaphore can take
>         *
>         * @return
>         */
>		explicit CSISemaphore(unsigned int _initial, unsigned int _max);
>		virtual ~CSISemaphore();
>
>		virtual bool check();
>		virtual void lock();
>		virtual void unlock();
>
>		virtual bool lock(unsigned int _time_out);
>	private:
>		pthread_mutex_t m_mut;
>        pthread_cond_t m_con;
>        int m_con_var;
>        int m_max_locks;
>};
>
>--- source ---
>
>
>#include THE_HEADER_FILE_ABOVE
>#include <errno.h>
>#include <unistd.h>
>#include <sys/time.h>
>#include <iostream>
>
>#define CSI_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {0, 0, 0,
>PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}
>
>
>/** purpose: create a single lock semaphore
>*/
>CSISemaphore::CSISemaphore(unsigned int
>_initial):m_con_var(_initial),m_max_locks(1)
>{
>    m_mut.__m_count = 0;
>    m_mut.__m_lock.__spinlock = 0;
>    m_mut.__m_lock.__status = 0;
>    m_mut.__m_owner = 0;
>    m_mut.__m_reserved = 0;
>    m_mut.__m_kind = PTHREAD_MUTEX_RECURSIVE_NP;
>    //m_mut = {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}};
>    pthread_mutex_init(&m_mut, 0);
>    pthread_cond_init(&m_con, 0);
>}
>/** purpose: create a counting Semaphore
>*/
>CSISemaphore::CSISemaphore(unsigned int _initial, unsigned int
>_max):m_con_var(_initial),m_max_locks(_max)
>{
>    m_mut.__m_count = 0;
>    m_mut.__m_lock.__spinlock = 0;
>    m_mut.__m_lock.__status = 0;
>    m_mut.__m_owner = 0;
>    m_mut.__m_reserved = 0;
>    m_mut.__m_kind = PTHREAD_MUTEX_RECURSIVE_NP;
>    //m_mut = {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}};
>    pthread_mutex_init(&m_mut, 0);
>    pthread_cond_init(&m_con, 0);
>    if (m_con_var > m_max_locks) {
>        m_con_var = m_max_locks;
>    }
>}
>/**
>*/
>CSISemaphore::~CSISemaphore(){
>    pthread_mutex_destroy(&m_mut);
>    pthread_cond_destroy(&m_con);
>}
>/**
>*/
>bool CSISemaphore::check(){
>    bool is_not_locked;
>    pthread_mutex_lock(&m_mut);
>    if (m_con_var > 0) {
>        is_not_locked = true;
>    }else{
>        is_not_locked = false;
>    }
>    pthread_mutex_unlock(&m_mut);
>    return is_not_locked;
>}
>/**
>*/
>void CSISemaphore::lock(void){
>    pthread_mutex_lock(&m_mut);
>    if (m_con_var == 0) {
>        do {
>            pthread_cond_wait(&m_con, &m_mut);
>        } while ( m_con_var == 0);
>    }
>    --m_con_var;// = 0;
>    pthread_mutex_unlock(&m_mut);
>}
>/**
>*/
>void CSISemaphore::unlock(void){
>    pthread_mutex_lock(&m_mut);
>    ++m_con_var;// = 1;
>    if (m_con_var > m_max_locks) {
>        m_con_var = m_max_locks;
>    }
>    pthread_mutex_unlock(&m_mut);
>    pthread_cond_signal(&m_con);
>    //sched_yield();
>}
>/**
>* This is perhaps the most complicatied of all sync functions.
>* The general unix pthread library does not support timeouts on
>* mutexes and therefore we need to use conditional variables.
>* However, the conditional variables do not guarantee smooth
>* execution. There are many conditions which can cause problems.
>*
>* _time_out in ms
>*/
>bool CSISemaphore::lock(unsigned int _time_out){
>    bool got_a_lock = false;
>    unsigned int status = 0;
>    struct timespec timeout;
>    struct timeval start_time;
>    // lock the mutex so we can check the predicate
>    pthread_mutex_lock(&m_mut);
>    // if someone has the predicate the wait on the condition variable
>TRY_TO_WAIT:
>    if (m_con_var == 0) {
>        gettimeofday(&start_time,0);
>        //cout << "  sec: " << start_time.tv_sec << ", usec: " <<
>start_time.tv_usec << endl;
>        unsigned int sec_delta = _time_out/1000;
>        timeout.tv_sec = start_time.tv_sec + (sec_delta);
>        timeout.tv_nsec = start_time.tv_usec +
>(_time_out-(sec_delta*1000))*100000;
>        //cout << "> sec: " << timeout.tv_sec << ", usec: " << timeout.tv_nsec
><< endl;
>        status = pthread_cond_timedwait(&m_con, &m_mut, &timeout);
>    }
>    if (m_con_var > 0) {
>        --m_con_var;// = 0;
>        got_a_lock = true;
>    }else{
>        if (status == ETIMEDOUT) {
>            got_a_lock = false;
>            cout << "timed wait status:" << status << endl;
>        }else{
>            unsigned int temp_time = (time(0) - timeout.tv_sec);
>            if ((_time_out/1000) > temp_time ) {
>                _time_out -= (temp_time*1000);
>                cout << ">> retry lock( " << _time_out << " )" << endl;
>                goto TRY_TO_WAIT;
>            }
>        }
>    }
>
>    // unlock the mutex so others can do their job (and wait)
>    pthread_mutex_unlock(&m_mut);
>    return got_a_lock;
>}



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.