Implementation of condition variables

To understand the code for pthread condition variables, I wrote my own version. Does this look right? I use it in the program, I work it, but it works surprisingly much faster. Initially, the program takes about 2.5 seconds, and with my version of the variable conditions it takes only 0.8 seconds, and the program output is also correct. However, I am not sure if my implementation is correct.

struct cond_node_t
{
    sem_t s;
    cond_node_t * next;
};

struct cond_t
{
    cond_node_t * q;                // Linked List
    pthread_mutex_t qm;                 // Lock for the Linked List
};

int my_pthread_cond_init( cond_t * cond )
{
    cond->q = NULL;
    pthread_mutex_init( &(cond->qm), NULL );
}

int my_pthread_cond_wait( cond_t* cond, pthread_mutex_t* mutex )
{
    cond_node_t * self;

    pthread_mutex_lock(&(cond->qm));
    self = (cond_node_t*)calloc( 1, sizeof(cond_node_t) );
    self->next = cond->q;
    cond->q = self;
    sem_init( &self->s, 0, 0 );
    pthread_mutex_unlock(&(cond->qm));

    pthread_mutex_unlock(mutex);
    sem_wait( &self->s );
    free( self ); // Free the node
    pthread_mutex_lock(mutex);
}

int my_pthread_cond_signal( cond_t * cond )
{
    pthread_mutex_lock(&(cond->qm));
    if (cond->q != NULL) 
    {
        sem_post(&(cond->q->s));
        cond->q = cond->q->next;
    }
    pthread_mutex_unlock(&(cond->qm));
}

int my_pthread_cond_broadcast( cond_t * cond )
{
    pthread_mutex_lock(&(cond->qm));
    while ( cond->q != NULL) 
    {
        sem_post( &(cond->q->s) );
        cond->q = cond->q->next;
    }
    pthread_mutex_unlock(&(cond->qm));
}
+7
source share
3 answers

Basically, your strategy looks fine, but you have one serious danger, some undefined behavior and a nit choice:

  • POSIX. , sem_wait , . .
  • . - - , undefined. , , .
  • malloc calloc

: malloc/free . .

+2

, , :

  • sem_destroy .
  • / cond_node_t , .

:

  • , , POSIX , . , , .
  • .
  • (, - pthread_cond_timedwait) .
  • userland, ; , .
  • LIFO. (, - ), . FIFO, .
+4

, :

condition cond; " , ". , , , , , pthread_cond_broadcast() pthread_cond_signal() , , .

You unlock and wait. Another thread can do many things between these operations.

PS I'm not sure if I am interpreting this paragraph correctly, feel free to indicate my mistake.

+2
source

All Articles