This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ecos sync problem: Does it work well?


Gary,
   maybe you make mistakes.i am level-headed!

From: "Gary D. Thomas" <gary dot thomas at mind dot be>
To: 寮?浜?<johnsonest at hotmail dot com>
CC: eCos Discussion
<ecos-discuss at sources dot redhat dot com>,nickg at calivar dot demon dot co dot 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 dot thomas at mind dot 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]