This is the mail archive of the ecos-discuss@sourceware.org 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: question on eCos mutex behavior


On Wed, Apr 25, 2007 at 03:20:58PM -0400, David Hill wrote:

> I'm experiencing some unexpected behavior using mutexes under eCos
> and I'm wondering if this is just the way it works or if I might be
> missing something.? I created a simple test case below to illustrate
> the behavior - I have two threads that are both running at the same
> priority and always trying to get a mutex lock.? The only difference
> between them is that I guaranteed that the first would win the first
> time by inserting an artificial delay into the 2nd thread. I
> expected that when the 1st thread unlocks the mutex, and tries to
> take it again, the cyg_mutex_lock() function would hang because
> there is already another thread pending on that mutex.?

You can see the code in packages/kernel/current/src/sync/mutex.cxx

The unlock call in thread1 just marks thread2 as runnable. Since both
threads are running with the same priority, there will not be a
preemption. So thread1 loops around and since the mutex is not locked
yet, it locks it.

When you add the delay, thread2 gets chance to run after being made
runnable via the unlock. It then claims the lock and you get the ping
pong behaviour.

In order for mutex's to work as you thought they should work, it would
be necessary for the unlock call to actually re-lock the mutex in the
name of thread2. This seems a bit ugly to me. 

> However,
> what I'm seeing is that the 1st thread continues to succeed over and
> over again and the 2nd thread gets starved, so I see lots of "LOCK0"
> statements and no "LOCK1" statements.? If I uncomment the
> 'cyg_thread_delay(1)' statement after the mutex is unlocked, then I
> get the nice ping-pong effect I was expecting, but I can't really
> use that workaround for my application.

You could also use cyg_thread_yield(). 

> If this is expected behavior, then is there a different mutual
> exclusion primitive that will provide ordering?

You could do something like:
    
for (;;) {
    cyg_mutex_lock()
    cyg_thread_set_priority(cyg_thread_get_priority()-1);
    work();
    cyg_mutex_unlock
    cyg_thread_set_priority(cyg_thread_get_priority()+1);
}

but cyg_thread_yield() seems like a cleaner solution.

    Andrew
    

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


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