rtems_event_receive() return code question

Joel Sherrill joel.sherrill at OARcorp.com
Mon Feb 2 18:01:58 UTC 2004

Thomas Rauscher wrote:

>>-----Original Message-----
>>From: Sergei Organov [mailto:osv at topconrd.ru] 
>>Sent: Monday, February 02, 2004 6:13 PM
>>To: Thomas Rauscher
>>Cc: rtems-users at rtems.com
>>Subject: Re: rtems_event_receive() return code question
>>"Thomas Rauscher" <trauscher at loytec.com> writes:
>>>I've a question regarding the rtems_event_receive() semantics.
>>>The API documentation unfortunately leaves some open questions.
>>>If a rtems_event_receive() function is called with timeout, but
>>>receives events just while returning after a timeout, is it 
>>correct to
>>>return RTEMS_TIMEOUT but have the event_out parameter set to
>>>a satisfying event set?
>>While not explicitly documented, the 'event_out' is left untouched
> when
>>RTEMS_TIMEOUT is returned. Thus, you need to initialize it to 0 before
> calling
>>rtems_event_receive() (it's almost always a good idea to 
>>initialize all your variables anyway). Alternatively, check return
> code and don't 
>>use 'event_out' when something other than RTEMS_SUCCESSFUL is
> returned.
> Well, in my case *event_out is always zero before being used.
> I think, that the code path I'm talking about, includes a race condition
> when the rtems_event_receive() caller actually is dispatched after
> waiting. 
> Then the return code is RTEMS_TIMEOUT and 'event_out' is changed.
> At least I didn't see that the Wait.count variable of the waiting thread
> is set to zero by the _Event_Timeout() function, like it is done by the
> _Event_Surrender() function. This was added 2001 or so,
> as it fixes a bug when sending events from interrupt service handlers.
> Please correct me, if I'm wrong.
> BTW, I can happily live with a return code of RTEMS_TIMEOUT and set 
> output events. I just wanted to make sure that this is the intended
> behavior.

It is not the intended behavior.  If you get a non-successful status,
then there should be no events received.

Technically the timeout code may need to be more paranoid in the case
an event generating interrupt source nests the timeout code in the
clock tick ISR.  So it might be worth considering, something like this:

   _ISR_Disable( ... );
     if ( the_thread->Wait.count ) {  /* verify thread is waiting */
         the_thread->Wait.return_code = RTEMS_TIMEOUT;
         the_thread->Wait.count = 0;
         _ISR_Enable( ... )
         _Thread_Unblock( the_thread );
      } else
       _ISR_Enable( ... );

What about that for the else case in _Event_Timeout()?

> Best regards,
> Thomas

More information about the users mailing list