Hi Kai, On Wed, Nov 9, 2011 at 3:12 PM, Kai Meyer <kai@gnukai.com> wrote:
Ok, I need mutual exclusion on a data structure regardless of interrupts and core. It sounds like it can be done by using a spinlock and disabling interrupts, but you mention that "spinlocks are intended to provide mutual exclsion between interrupt context and non-interrupt context." Should I be using a semaphore (mutex) instead?
It depends. If the function is only called from thread context, then you probably want to use a mutex. If there is a possibility that it might be called from interrupt context, then you can't use a mutex. Also, remember that spin-locks are no-ops on a single processor machine, so as coded, you have no protection on a single-processor machine if you're calling from thread context.
Perhaps I could explain my problem with some code: struct my_struct *get_data(spinlock_t *mylock, int ALLOC_DATA) { struct my_struct *mydata = NULL; spin_lock(mylock); if (test_bit(index, mybitmap)) mydata = retrieve_data(); if (!mydata && ALLOC_DATA) { mydata = alloc_data(); set_bit(index, mybitmap); } spin_unlock(mylock); return mydata; }
I need to prevent retrieve_data from being called if the index bit is set in mybitmap and alloc_data has not completed, so I use a bitmap to indicate that alloc_data has completed. I also need to protect alloc_data from being run multiple times, so I use the spin_lock to ensure that test_bit (and possibly retrieve_data) is not run while alloc_data is being run (because it runs while the bit is cleared).
If alloc_data might block, then you can't disable interrupts and you definitely shouldn't be using spinlocks. -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com