[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.programming.threads

What am i missing?

John

8/7/2004 12:26:00 AM

Hi. I've been fighting with the following bit of code for quite a while
now. It is part of a multithreaded ringbuffer module, and I'm getting
unpredictable values when the test driver runs against this module, so there
must be an error here in my logic. Hopefully it's something glaringly
obvious, but that i'm not seeing cuz i'm burned out =)

All the error checking for malloc and semaphore operations are taking place,
though it is not shown below. Some code (which I believe is unrelated to
the problem) is left out for brevity's sake. If needed, I can post the
whole source somewhere. Also forgive the lousy formatting... Outlook
Express isn't a friend of mine.

Thanks in advance for any and all help in this matter!

----------------------------------

int readyToPut( ringbuf_t* );
int readyToGet( ringbuf_t* );

ringbuf_t*
ringbuf_alloc( int num_elements ){
DEBUG("In ringbuf_alloc\n");

/* make a new ringbuf_t and malloc room for it */
ringbuf_t *ringbuf;
ringbuf = Malloc( sizeof(ringbuf_t) );
/* malloc enough to hold num_elements of value_type */
value_type *bufspace;
bufspace = Malloc( num_elements * sizeof( value_type ) );

/* init a mutex that will protect access to the buffah
and notEmpty / notFull condition variables */


Sem_init( &ringbuf->notEmpty, 0, 0 );
Sem_init( &ringbuf->notFull, 0, 1 );
Sem_init( &ringbuf->mutex, 0, 1 );

return( ringbuf );
}

void
ringbuf_put( ringbuf_t *ringbuf,value_type val ){

while( !readyToPut( ringbuf ) )
Sem_wait( &ringbuf->notFull );

Sem_wait( &ringbuf->mutex );
DEBUG("\n:::: putting %d in %d\n",val,ringbuf->putspot);
ringbuf->buffer[ ringbuf->putspot ] = val;
ringbuf->putspot = ( ringbuf->putspot +1 ) % ringbuf->maxSize;
DEBUG(":::: next putspot %d\n\n",ringbuf->putspot );
ringbuf->itemCount++;
Sem_post( &ringbuf->mutex );
Sem_post( &ringbuf->notEmpty );

}

value_type
ringbuf_get( ringbuf_t *ringbuf ){

while( !readyToGet( ringbuf ) )
Sem_wait( &ringbuf->notEmpty );

Sem_wait( &ringbuf->mutex );
DEBUG("IN ringbuf_get\n");
value_type val = ringbuf->buffer[ ringbuf->nextGet ];
ringbuf->nextGet = (ringbuf->nextGet +1) % ringbuf->maxSize;
ringbuf->itemCount--;
Sem_post( &ringbuf->mutex );

Sem_post( &ringbuf->notFull );

return( val );
}

void
ringbuf_dealloc( ringbuf_t *ringbuf ){
/* free the buffer space and the mutex */
Sem_destroy( &ringbuf->notEmpty );
Sem_destroy( &ringbuf->notFull );
Sem_destroy( &ringbuf->mutex );
free( ringbuf->buffer );
free( ringbuf );
}


int
readyToPut( ringbuf_t *ringbuf ){
/* Is the buffer _not_ full? Then we can put */
return( ringbuf->itemCount != ringbuf->maxSize );
}

int
readyToGet( ringbuf_t *ringbuf ){
/* Is the buffer _not_empty? Then we can get */
return( ringbuf->itemCount != 0 );
}


4 Answers

Joe Seigh

8/7/2004 12:43:00 AM

0



John wrote:
>
> Hi. I've been fighting with the following bit of code for quite a while
> now. It is part of a multithreaded ringbuffer module, and I'm getting
> unpredictable values when the test driver runs against this module, so there
> must be an error here in my logic. Hopefully it's something glaringly
> obvious, but that i'm not seeing cuz i'm burned out =)
>
> All the error checking for malloc and semaphore operations are taking place,
> though it is not shown below. Some code (which I believe is unrelated to
> the problem) is left out for brevity's sake. If needed, I can post the
> whole source somewhere. Also forgive the lousy formatting... Outlook
> Express isn't a friend of mine.
>
> Thanks in advance for any and all help in this matter!
>

Semaphores aren't condition variables so don't try to use them like
one because it won't work. Get rid of the loop on those sem_waits.
Also use a mutex for a mutex, not a semaphore. And initalize the
sempahores properly. The sempahore guarding the empty buffers should
be initalized to the number of empty buffers, and the semaphore
guarding the full buffers should be initialized to zero. You only
need a mutex for coordinating actual buffer usage if you have more
than one producer or more than one consumer.

Joe Seigh

John

8/7/2004 12:47:00 AM

0

I do have multiple threads reading and writing simultaneously.

With your other suggestions in mind, I'll try some stuff. Thanks.


"Joe Seigh" <jseigh_01@xemaps.com> wrote in message
news:411427E0.42FC8C15@xemaps.com...
>
>
> John wrote:
>>
>> Hi. I've been fighting with the following bit of code for quite a while
>> now. It is part of a multithreaded ringbuffer module, and I'm getting
>> unpredictable values when the test driver runs against this module, so
>> there
>> must be an error here in my logic. Hopefully it's something glaringly
>> obvious, but that i'm not seeing cuz i'm burned out =)
>>
>> All the error checking for malloc and semaphore operations are taking
>> place,
>> though it is not shown below. Some code (which I believe is unrelated to
>> the problem) is left out for brevity's sake. If needed, I can post the
>> whole source somewhere. Also forgive the lousy formatting... Outlook
>> Express isn't a friend of mine.
>>
>> Thanks in advance for any and all help in this matter!
>>
>
> Semaphores aren't condition variables so don't try to use them like
> one because it won't work. Get rid of the loop on those sem_waits.
> Also use a mutex for a mutex, not a semaphore. And initalize the
> sempahores properly. The sempahore guarding the empty buffers should
> be initalized to the number of empty buffers, and the semaphore
> guarding the full buffers should be initialized to zero. You only
> need a mutex for coordinating actual buffer usage if you have more
> than one producer or more than one consumer.
>
> Joe Seigh


Joe Seigh

8/7/2004 1:15:00 AM

0



John wrote:
>
> I do have multiple threads reading and writing simultaneously.
>
> With your other suggestions in mind, I'll try some stuff. Thanks.
>


Basic logic for consumer will look like

sem_wait(fullSem);
pthread_mutex_lock();
...
pthread_mutex_unlock;
sem_post(emptySem);

vice versa for producer

fullSem initialized to 0;
emptySem initalized to #buffers;

The only tricky thing is termination as semaphores
don't lend themselves naturally to that.

Joe Seigh

John

8/7/2004 3:20:00 AM

0

Ah =) Poifect. Thanks indeed for the help.


"Joe Seigh" <jseigh_01@xemaps.com> wrote in message
news:41142F65.52451771@xemaps.com...
>
>
> John wrote:
>>
>> I do have multiple threads reading and writing simultaneously.
>>
>> With your other suggestions in mind, I'll try some stuff. Thanks.
>>
>
>
> Basic logic for consumer will look like
>
> sem_wait(fullSem);
> pthread_mutex_lock();
> ...
> pthread_mutex_unlock;
> sem_post(emptySem);
>
> vice versa for producer
>
> fullSem initialized to 0;
> emptySem initalized to #buffers;
>
> The only tricky thing is termination as semaphores
> don't lend themselves naturally to that.
>
> Joe Seigh