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: at91 SPI driver, use of cyg_drv_dsr_lock()


On Mon, 2006-03-20 at 13:57 +0100, Peter Kooiman wrote:
> Hello all,
> 
> I cannot for the life of me get my head around this code in spi_at91.c (in 
> packages\devs\spi\arm\at91\current\src), function spi_at91_transfer:
> 
> 
>             // Unmask the SPI int
>             cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_SPI);
> 
>             // Wait for its completition
>             cyg_drv_dsr_lock();
>             {
>                 while (!spi_bus->transfer_end)
>                     cyg_drv_cond_wait(&spi_bus->transfer_cond);
>             }
>             cyg_drv_dsr_unlock();
> 
> Now, the condition variable spi_bus->transfer_cond is signalled from the 
> DSR:
>         // Transfer ended
>         spi_bus->transfer_end = true;
>         cyg_drv_cond_signal(&spi_bus->transfer_cond);
> 
> However, if I understand correctly, cyg_drv_dsr_lock() will prevent the 
> (any) DSR from being run, so...while holding the DSR lock the code waits for 
> a condition variable that must be signalled from the DSR that we have just 
> prevented from running in the first place??
> 
> Either I completely misunderstand the way cyg_drv_dsr_lock() works (very 
> possible), or this code is broken...anyone care to comment?

cyg_drv_dsr_lock() only prevents DSRs until the thread gives up the CPU
or cyg_drv_dsr_unlock() is called.  In this case, if the thread decides
tp call cyg_drv_cond_wait(), then the DSR lock is dropped.  Once the DSR
runs and signals the condition variable, the thread is resumed - *with*
DSRs locked again.  Once the thread exits the 'while()' loop, the DSR
lock will once again be dropped.

It has to work this way to be safe - otherwise there could be a 
[however small] race where the thread thinks that the DSR hasn't
run (spi_bus->transfer_end not set), decides to wait for it and
just at that instant, the DSR runs, setting the end condition.
If this were to happen, the thread would sleep forever.

-- 
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------


-- 
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]