diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-01-10 18:19:53 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-10 18:19:53 +0100 |
commit | 281322b2e56e292dadcb14458bed6cbe448076d6 (patch) | |
tree | 2d67916be406bbe90e52722e611a6773c1413aee | |
parent | 025fd8d5f7b6b3a0b58b5bdaba578d1dd8377eee (diff) | |
download | hda-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.h | 10 | ||||
-rw-r--r-- | include/linux/spinlock.h | 30 | ||||
-rw-r--r-- | include/wrapper.h | 4 | ||||
-rw-r--r-- | snd-wrapper.c | 77 |
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 */ |