[ECOS] ecos sync problem: Does it work well?
张 亮
johnsonest@hotmail.com
Wed Mar 5 09:56:00 GMT 2003
Gary,
maybe you make mistakes.i am level-headed!
>From: "Gary D. Thomas" <gary.thomas@mind.be>
>To: ��<johnsonest@hotmail.com>
>CC: eCos Discussion
<ecos-discuss@sources.redhat.com>,nickg@calivar.demon.co.uk
>Subject: Re: [ECOS] ecos sync problem: Does it work well?
>Date: 04 Mar 2003 22:54:55 -0700
>
>On Tue, 2003-03-04 at 22:25, ��wrote:
> >
> > Hi,nickg!
> > in support to tcp/ip stack,ecos packs two new sync function:
> > cyg_tsleep(...)
> > cyg_wakeup(...)
> > in synch.c file.
> > according to ecos scheduler,I doubt it does not work well as
following:
> >
>
>Actually, this code works just fine, thank you.
>
>Have you ever tried any of this code, or do you just sit up late
>at night and read it to ask questions?
>
> > int
> > cyg_tsleep(void *chan, int pri, char *wmesg, int timo)
> > {
> > int i, res = 0;
> > struct wakeup_event *ev;
> > cyg_tick_count_t sleep_time;
> > cyg_handle_t self = cyg_thread_self();
> > int old_splflags = 0; // no flags held
> >
> > cyg_scheduler_lock();//*******************lock=1,threads switch
will be
> > impossible until last
cyg_scheduler_unlock(),right?********************/
> >
> > // Safely find a free slot:
> > for (i = 0, ev = wakeup_list; i < CYGPKG_NET_NUM_WAKEUP_EVENTS;
i++,
> > ev++) {
> > if (ev->chan == 0)
> > {
> > ev->chan = chan;
> > break;
> > }
> > }
> > CYG_ASSERT( i < CYGPKG_NET_NUM_WAKEUP_EVENTS, "no sleep slots" );
> > CYG_ASSERT( 1 == cyg_scheduler_read_lock(),
> > "Tsleep - called with scheduler locked" );
> > // Defensive:
> > if ( i >= CYGPKG_NET_NUM_WAKEUP_EVENTS ) {
> > cyg_scheduler_unlock();
> > return ETIMEDOUT;
> > }
> >
> > // If we are the owner, then we must release the mutex when
> > // we wait.
> > if ( self == splx_thread ) {
> > old_splflags = spl_state; // Keep them for restoration
> > CYG_ASSERT( spl_state, "spl_state not set" );
> > // Also want to assert that the mutex is locked...
> > CYG_ASSERT( splx_mutex.locked, "Splx mutex not locked" );
> > CYG_ASSERT( (cyg_handle_t)splx_mutex.owner == self, "Splx mutex
not
> > mine" );
> > splx_thread = 0;
> > spl_state = 0;
> > cyg_mutex_unlock( &splx_mutex );
> > }
> >
> > // Re-initialize the semaphore - it might have counted up
arbitrarily
> > // in the time between a prior sleeper being signalled and them
> > // actually running.
> > cyg_semaphore_init(&ev->sem, 0);
> >
> > // This part actually does the wait:
> > // As of the new kernel, we can do this without unlocking the
scheduler
> > if (timo) {
> > sleep_time = cyg_current_time() + timo;
> > if (!cyg_semaphore_timed_wait(&ev->sem, sleep_time)) {
> > /**********lock will >1,never wait!!!*****************************/
>
>Wrong; read the scheduling code - it handle this case properly.
//////// this is cyg_semaphore_timed_wait(..) lock =2///////////////////
Cyg_Scheduler::lock();
CYG_INSTRUMENT_CNTSEM( CLAIM, this, count );
if ( 0 < count ) {
count--;
Cyg_Scheduler::unlock();
}
else {
// Put thread in sleep state before setting timer since if the
// timeout is in the past, it will be re-awoken
// immediately. If this happens then wake_reason will not be
// NONE.
self->sleep();
self->set_timer( abs_timeout, Cyg_Thread::TIMEOUT );
// only enqueue if the timeout did not already happen
if( Cyg_Thread::NONE == self->get_wake_reason() )
queue.enqueue( self );
CYG_INSTRUMENT_CNTSEM( WAIT, this, 0 );
Cyg_Scheduler::unlock();
////////////// in Cyg_Scheduler::unlock(),_lock=2-1=1 >0,unlock_inner(...)
will never be called!
so threads switch is impossible!
inline void Cyg_Scheduler::unlock()
{
cyg_ucount32 __lock = get_sched_lock() - 1;
if( __lock == 0 ) unlock_inner(0);
else set_sched_lock(__lock);
}
////////////////////////////////////////////////////////////////////////
> > if( cyg_current_time() >= sleep_time )
> > res = ETIMEDOUT;
> > else
> > res = EINTR;
> > }
> > } else {
> > if (!cyg_semaphore_wait(&ev->sem) ) {**********never wait for
> > lock>1
> > res = EINTR;
> > }
> > }
> >
> > ev->chan = 0; // Free the slot - the wakeup call cannot do this.
> >
> > if ( old_splflags ) { // restore to previous state
> > // As of the new kernel, we can do this with the scheduler
locked
> > cyg_mutex_lock( &splx_mutex ); // this might wait
> > CYG_ASSERT( 0 == splx_thread, "Splx thread set in tsleep" );
> > CYG_ASSERT( 0 == spl_state, "spl_state set in tsleep" );
> > splx_thread = self; // got it now...
> > spl_state = old_splflags;
> > }
> >
> > cyg_scheduler_unlock();/****************till here,lock=0,threads
switch
> > is possible,this means tsleep will never sleep!!!*************** /
>
>You can only get here *after* waiting above.
>
> > return res;
> > }
> >
> >
> >
> > right?
> > but i do not know why redhat reported that stack works well?
> >
> >
> > BRS
> > johnsonest
> >
> > _________________________________________________________________
> > Ã¥Â
Âè´¹ä¸Âè½½ MSN Explorer: http://explorer.msn.com/lccn
> >
> >
> > --
> > Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
> > and search the list archive: http://sources.redhat.com/ml/ecos-discuss
>
>--
>.--------------------------------------------------------.
>| Mind: Embedded Linux and eCos Development |
>|--------------------------------------------------------|
>| Gary Thomas email: gary.thomas@mind.be |
>| Mind ( http://mind.be ) tel: +1 (970) 229-1963 |
>| gpg: http://www.chez-thomas.org/gary/gpg_key.asc |
>'--------------------------------------------------------'
>
_________________________________________________________________
Ãëê»úµÃÃ
óÃýøÃý»Ã÷£¬ÃëùÃà MSN Messenger: http://messenger.msn.com/cn
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss
More information about the Ecos-discuss
mailing list