This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
[Semaphore]Set_timer in Cyg_Counting_Semaphore::wait at cnt_sem.cxx
- From: "PATTAYA" <pattayaroot at yahoo dot com dot tw>
- To: <ecos-discuss at sourceware dot org>
- Date: Thu, 19 Mar 2009 18:02:22 +0800
- Subject: [ECOS] [Semaphore]Set_timer in Cyg_Counting_Semaphore::wait at cnt_sem.cxx
Dear developers,
I have a question about usage of timer in
cyg_bool Cyg_Counting_Semaphore::wait( cyg_tick_count timeout ).
If timeout is larger than current time and count is larger than 0, eCos
still set timer.
Is it necessary? Why not skip setting timer in this case for better
performance?
Actually, the self->set_timer will consume around 80us in my current ARM
platform.
Following is original source with my modification.
I have a brief test and the result is passed.
It seems workable and has a better performance.
Regards,
PATTAYA
cyg_bool
Cyg_Counting_Semaphore::wait( cyg_tick_count timeout )
{
cyg_bool result = true;
Cyg_Thread *self = Cyg_Thread::self();
/*** PATTAYA_add_begin ***/
cyg_bool skip_timer = false;
/*** PATTAYA_add_end ***/
// Prevent preemption
Cyg_Scheduler::lock();
CYG_INSTRUMENT_CNTSEM( CLAIM, this, count );
/*** PATTAYA_add_begin ***/
if (count > 0)
{
// count > 0 , no need to set up timer.
skip_timer = true;
}
else
{
/*** PATTAYA_add_end ***/
// Set the timer _once_ outside the loop.
self->set_timer( timeout, Cyg_Thread::TIMEOUT );
// If the timeout is in the past, the wake reason will have been
// set to something other than NONE already. If the count is zero,
// set the result false to force an immediate return. If the count
// is non-zero, then this wait will succeed anyway.
if( self->get_wake_reason() != Cyg_Thread::NONE &&
0 == count )
result = false;
/*** PATTAYA_add_begin ***/
}
/*** PATTAYA_add_end ***/
while ( 0 == count && result ) {
// must reset the sleep reason every time
self->set_sleep_reason( Cyg_Thread::TIMEOUT );
self->sleep();
queue.enqueue( self );
CYG_INSTRUMENT_CNTSEM( WAIT, this, 0 );
// Allow other threads to run
Cyg_Scheduler::reschedule();
CYG_INSTRUMENT_CNTSEM( WOKE, this, count );
switch( self->get_wake_reason() )
{
case Cyg_Thread::TIMEOUT:
result = false;
CYG_INSTRUMENT_CNTSEM( TIMEOUT, this, count);
break;
case Cyg_Thread::DESTRUCT:
case Cyg_Thread::BREAK:
result = false;
break;
case Cyg_Thread::EXIT:
self->exit();
break;
default:
break;
}
}
// Clear the timeout. It is irrelevant whether the alarm has
// actually gone off or not.
/*** PATTAYA_add_begin ***/
if (skip_timer == false)
/*** PATTAYA_add_end ***/
self->clear_timer();
if ( result ) count--;
// Unlock the scheduler and maybe switch threads
Cyg_Scheduler::unlock();
return result;
}
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss