aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-10 18:19:53 +0100
committerTakashi Iwai <tiwai@suse.de>2013-01-10 18:19:53 +0100
commit281322b2e56e292dadcb14458bed6cbe448076d6 (patch)
tree2d67916be406bbe90e52722e611a6773c1413aee
parent025fd8d5f7b6b3a0b58b5bdaba578d1dd8377eee (diff)
downloadhda-emu-281322b2e56e292dadcb14458bed6cbe448076d6.tar.gz
Add proper rwlock and rw_semaphore implementation
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/linux/mutex.h10
-rw-r--r--include/linux/spinlock.h30
-rw-r--r--include/wrapper.h4
-rw-r--r--snd-wrapper.c77
4 files changed, 106 insertions, 15 deletions
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index b2b9a83..b68c8a8 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -13,4 +13,14 @@ struct mutex {
#define DEFINE_MUTEX(x) struct mutex x = { .lock = MYLOCK_UNLOCKED }
+struct rw_semaphore {
+ int lock;
+};
+
+#define rwsem_init(x) mylock_init(&(x)->lock)
+#define down_read(x) mylock_read_lock(&(x)->lock, __FILE__, __LINE__)
+#define up_read(x) mylock_read_unlock(&(x)->lock, __FILE__, __LINE__)
+#define down_write(x) mylock_write_lock(&(x)->lock, __FILE__, __LINE__)
+#define up_write(x) mylock_write_unlock(&(x)->lock, __FILE__, __LINE__)
+
#endif /* __LINUX_MUTEX_H */
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 4ad3cc8..4ae6e6e 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -9,21 +9,21 @@ typedef int rwlock_t;
#define spin_unlock(x) mylock_unlock(x, __FILE__, __LINE__)
#define spin_lock_irq(x) mylock_lock(x, __FILE__, __LINE__)
#define spin_unlock_irq(x) mylock_unlock(x, __FILE__, __LINE__)
-#define spin_lock_irqsave(x, flags) do { (flags) = 0; mylock_lock(x); } while (0)
-#define spin_unlock_irqrestore(x, flags) do { (flags) = 0; mylock_unlock(x); } while (0)
+#define spin_lock_irqsave(x, flags) do { (flags) = 0; mylock_lock(x, __FILE__, __LINE__); } while (0)
+#define spin_unlock_irqrestore(x, flags) do { (flags) = 0; mylock_unlock(x, __FILE__, __LINE__); } while (0)
-#define rwlock_init(x)
-#define read_lock(x)
-#define read_unlock(x)
-#define read_lock_irq(x)
-#define read_unlock_irq(x)
-#define read_lock_irqsave(x, flags) ((flags) = 0)
-#define read_unlock_irqrestore(x, flags) ((flags) = 0)
-#define write_lock(x)
-#define write_unlock(x)
-#define write_lock_irq(x)
-#define write_unlock_irq(x)
-#define write_lock_irqsave(x, flags) ((flags) = 0)
-#define write_unlock_irqrestore(x, flags) ((flags) = 0)
+#define rwlock_init(x) mylock_init(x)
+#define read_lock(x) mylock_read_lock(x, __FILE__, __LINE__)
+#define read_unlock(x) mylock_read_unlock(x, __FILE__, __LINE__)
+#define read_lock_irq(x) mylock_read_lock(x, __FILE__, __LINE__)
+#define read_unlock_irq(x) mylock_read_unlock(x, __FILE__, __LINE__)
+#define read_lock_irqsave(x, flags) do { (flags) = 0; mylock_read_lock(x, __FILE__, __LINE__); } while (0)
+#define read_unlock_irqrestore(x, flags) do { (flags) = 0; mylock_read_unlock(x, __FILE__, __LINE__); } while (0)
+#define write_lock(x) mylock_write_lock(x, __FILE__, __LINE__)
+#define write_unlock(x) mylock_write_unlock(x, __FILE__, __LINE__)
+#define write_lock_irq(x) mylock_write_lock(x, __FILE__, __LINE__)
+#define write_unlock_irq(x) mylock_write_unlock(x, __FILE__, __LINE__)
+#define write_lock_irqsave(x, flags) do { (flags) = 0; mylock_write_lock(x, __FILE__, __LINE__); } while (0)
+#define write_unlock_irqrestore(x, flags) do { (flags) = 0; mylock_write_unlock(x, __FILE__, __LINE__); } while (0)
#endif
diff --git a/include/wrapper.h b/include/wrapper.h
index 67387e5..66d781b 100644
--- a/include/wrapper.h
+++ b/include/wrapper.h
@@ -216,6 +216,10 @@ enum {
void mylock_init(int *lock);
void mylock_lock(int *lock, const char *file, int line);
void mylock_unlock(int *lock, const char *file, int line);
+void mylock_read_lock(int *lock, const char *file, int line);
+void mylock_read_unlock(int *lock, const char *file, int line);
+void mylock_write_lock(int *lock, const char *file, int line);
+void mylock_write_unlock(int *lock, const char *file, int line);
#include "linux/spinlock.h"
#include "linux/pci_ids.h"
diff --git a/snd-wrapper.c b/snd-wrapper.c
index 69cd19c..9e428bc 100644
--- a/snd-wrapper.c
+++ b/snd-wrapper.c
@@ -258,6 +258,83 @@ void mylock_unlock(int *lock, const char *file, int line)
}
}
+#define MYLOCK_WRITE_LOCKED 0x10000
+
+void mylock_read_lock(int *lock, const char *file, int line)
+{
+ if (*lock == MYLOCK_UNINIT) {
+ hda_log(HDA_LOG_ERR, "Read-locking uninitialized obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ if (*lock >= MYLOCK_WRITE_LOCKED) {
+ hda_log(HDA_LOG_ERR, "Read-locking write-locked obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ (*lock)++;
+}
+
+void mylock_read_unlock(int *lock, const char *file, int line)
+{
+ if (*lock == MYLOCK_UNINIT) {
+ hda_log(HDA_LOG_ERR, "Read-unlocking uninitialized obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ if (*lock == MYLOCK_UNLOCKED) {
+ hda_log(HDA_LOG_ERR, "Read-unlocking unlocked obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ if (*lock >= MYLOCK_WRITE_LOCKED) {
+ hda_log(HDA_LOG_ERR, "Read-unlocking write-locked obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ (*lock)--;
+}
+
+void mylock_write_lock(int *lock, const char *file, int line)
+{
+ if (*lock == MYLOCK_UNINIT) {
+ hda_log(HDA_LOG_ERR, "Write-locking uninitialized obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ if (*lock == MYLOCK_WRITE_LOCKED) {
+ hda_log(HDA_LOG_ERR, "Double write-locking at %s:%d\n",
+ file, line);
+ return;
+ }
+ if (*lock != MYLOCK_UNLOCKED) {
+ hda_log(HDA_LOG_ERR, "Write-locking read-locked obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ *lock = MYLOCK_WRITE_LOCKED;
+}
+
+void mylock_write_unlock(int *lock, const char *file, int line)
+{
+ if (*lock == MYLOCK_UNINIT) {
+ hda_log(HDA_LOG_ERR, "Write-unlocking uninitialized obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ if (*lock == MYLOCK_UNLOCKED) {
+ hda_log(HDA_LOG_ERR, "Write-unlocking unlocked obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ if (*lock != MYLOCK_WRITE_LOCKED) {
+ hda_log(HDA_LOG_ERR, "Write-unlocking read-locked obj at %s:%d\n",
+ file, line);
+ return;
+ }
+ *lock = MYLOCK_UNLOCKED;
+}
+
/*
* standard channel mapping helpers
*/