Messages in this thread | | | Date | Fri, 18 Dec 2009 15:30:35 +0100 | From | Miquel van Smoorenburg <> | Subject | spinlock which can morph into a mutex |
| |
I'm trying to implement a dynamically resizable hashtable, and I have found that after resizing the table I need to call synchronize_rcu() and finish up before letting other writers (inserts, deletes) access the table.
Ofcourse during the hashtable update a spinlock is held to exclude the other writers. But I cannot hold this spinlock over synchronize_rcu(), yet the other writers still need to be excluded.
So I probably need a mutex instead of a spinlock, but I want to keep minimal overhead for the common case (when no resizing is in progress). I think I need a spinlock that can morph into a mutex ..
I was thinking about using something like the code below. It is sortof like a spinlock, but it's ofcourse less fair than actual ticketed spinlocks.
I'm working off 2.6.27 at the moment, but I noticed that in 2.6.28 adaptive spinning was introduced for mutexes. Is the approach below still worth it with adaptive spinning or could I just convert the spinlocks to mutexes with minimal extra overhead ?
Example code:
int real_mutex_lock = 0; // can use int since mutex ops are barriers struct mutex mutex;
// 1. used instead of spinlock() [common case] while (mutex_trylock(&mutex) == 0) { if (real_mutex_lock) { mutex_lock(&mutex); break; } } .. have lock, do work mutex_unlock(&mutex);
// 2. When we want to lock and be able to sleep [seldomly used] mutex_lock(&mutex); real_mutex_lock = 1; smp_wmb();
.. do work .. real_mutex_lock = 0; mutex_unlock(&mutex);
Mike.
| |