<para>
For our first example, we assume that all operations are in user
context (ie. from system calls), so we can sleep. This means we can
-use a semaphore to protect the cache and all the objects within
+use a mutex to protect the cache and all the objects within
it. Here's the code:
</para>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#include <asm/errno.h>
struct object
};
/* Protects the cache, cache_num, and the objects within it */
-static DECLARE_MUTEX(cache_lock);
+static DEFINE_MUTEX(cache_lock);
static LIST_HEAD(cache);
static unsigned int cache_num = 0;
#define MAX_CACHE_SIZE 10
obj->id = id;
obj->popularity = 0;
- down(&cache_lock);
+ mutex_lock(&cache_lock);
__cache_add(obj);
- up(&cache_lock);
+ mutex_unlock(&cache_lock);
return 0;
}
void cache_delete(int id)
{
- down(&cache_lock);
+ mutex_lock(&cache_lock);
__cache_delete(__cache_find(id));
- up(&cache_lock);
+ mutex_unlock(&cache_lock);
}
int cache_find(int id, char *name)
struct object *obj;
int ret = -ENOENT;
- down(&cache_lock);
+ mutex_lock(&cache_lock);
obj = __cache_find(id);
if (obj) {
ret = 0;
strcpy(name, obj->name);
}
- up(&cache_lock);
+ mutex_unlock(&cache_lock);
return ret;
}
</programlisting>
int popularity;
};
--static DECLARE_MUTEX(cache_lock);
+-static DEFINE_MUTEX(cache_lock);
+static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(cache);
static unsigned int cache_num = 0;
obj->id = id;
obj->popularity = 0;
-- down(&cache_lock);
+- mutex_lock(&cache_lock);
+ spin_lock_irqsave(&cache_lock, flags);
__cache_add(obj);
-- up(&cache_lock);
+- mutex_unlock(&cache_lock);
+ spin_unlock_irqrestore(&cache_lock, flags);
return 0;
}
void cache_delete(int id)
{
-- down(&cache_lock);
+- mutex_lock(&cache_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&cache_lock, flags);
__cache_delete(__cache_find(id));
-- up(&cache_lock);
+- mutex_unlock(&cache_lock);
+ spin_unlock_irqrestore(&cache_lock, flags);
}
int ret = -ENOENT;
+ unsigned long flags;
-- down(&cache_lock);
+- mutex_lock(&cache_lock);
+ spin_lock_irqsave(&cache_lock, flags);
obj = __cache_find(id);
if (obj) {
ret = 0;
strcpy(name, obj->name);
}
-- up(&cache_lock);
+- mutex_unlock(&cache_lock);
+ spin_unlock_irqrestore(&cache_lock, flags);
return ret;
}