X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=libcfs%2Finclude%2Flibcfs%2Fuser-lock.h;h=8c70f05e5c019a62c5c36e94c6ee06aa4b57b0e8;hb=49b74e8ab7c0bf76a4ff5b0b2cce15314b1ca8f8;hp=4759e8216d94cf201bcd46ca1433a9b2863af623;hpb=70e80ade90af09300396706b8910e196a7928520;p=fs%2Flustre-release.git diff --git a/libcfs/include/libcfs/user-lock.h b/libcfs/include/libcfs/user-lock.h index 4759e82..8c70f05 100644 --- a/libcfs/include/libcfs/user-lock.h +++ b/libcfs/include/libcfs/user-lock.h @@ -16,8 +16,8 @@ * in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see [sun.com URL with a - * copy of GPLv2]. + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or @@ -26,7 +26,7 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. */ /* @@ -56,192 +56,332 @@ */ #ifndef __KERNEL__ -#include -#include -#if 0 +/* + * The userspace implementations of linux/spinlock.h vary; we just + * include our own for all of them + */ +#define __LINUX_SPINLOCK_H + /* * Optional debugging (magic stamping and checking ownership) can be added. */ /* - * spin_lock + * cfs_spin_lock * - * - spin_lock_init(x) - * - spin_lock(x) - * - spin_unlock(x) - * - spin_trylock(x) + * - cfs_spin_lock_init(x) + * - cfs_spin_lock(x) + * - cfs_spin_unlock(x) + * - cfs_spin_trylock(x) + * - cfs_spin_lock_bh_init(x) + * - cfs_spin_lock_bh(x) + * - cfs_spin_unlock_bh(x) * - * - spin_lock_irqsave(x, f) - * - spin_unlock_irqrestore(x, f) + * - cfs_spin_is_locked(x) + * - cfs_spin_lock_irqsave(x, f) + * - cfs_spin_unlock_irqrestore(x, f) * * No-op implementation. */ -struct spin_lock {int foo;}; +struct cfs_spin_lock {int foo;}; -typedef struct spin_lock spinlock_t; +typedef struct cfs_spin_lock cfs_spinlock_t; -#define SPIN_LOCK_UNLOCKED (spinlock_t) { } -#define LASSERT_SPIN_LOCKED(lock) do {} while(0) +#define CFS_SPIN_LOCK_UNLOCKED (cfs_spinlock_t) { } +#define LASSERT_SPIN_LOCKED(lock) do {(void)sizeof(lock);} while(0) +#define LINVRNT_SPIN_LOCKED(lock) do {(void)sizeof(lock);} while(0) +#define LASSERT_SEM_LOCKED(sem) do {(void)sizeof(sem);} while(0) -void spin_lock_init(spinlock_t *lock); -void spin_lock(spinlock_t *lock); -void spin_unlock(spinlock_t *lock); -int spin_trylock(spinlock_t *lock); -void spin_lock_bh_init(spinlock_t *lock); -void spin_lock_bh(spinlock_t *lock); -void spin_unlock_bh(spinlock_t *lock); -static inline int spin_is_locked(spinlock_t *l) {return 1;} +void cfs_spin_lock_init(cfs_spinlock_t *lock); +void cfs_spin_lock(cfs_spinlock_t *lock); +void cfs_spin_unlock(cfs_spinlock_t *lock); +int cfs_spin_trylock(cfs_spinlock_t *lock); +void cfs_spin_lock_bh_init(cfs_spinlock_t *lock); +void cfs_spin_lock_bh(cfs_spinlock_t *lock); +void cfs_spin_unlock_bh(cfs_spinlock_t *lock); -static inline void spin_lock_irqsave(spinlock_t *l, unsigned long f){} -static inline void spin_unlock_irqrestore(spinlock_t *l, unsigned long f){} +static inline int cfs_spin_is_locked(cfs_spinlock_t *l) {return 1;} +static inline void cfs_spin_lock_irqsave(cfs_spinlock_t *l, unsigned long f){} +static inline void cfs_spin_unlock_irqrestore(cfs_spinlock_t *l, + unsigned long f){} /* * Semaphore * - * - sema_init(x, v) + * - cfs_sema_init(x, v) * - __down(x) * - __up(x) */ -typedef struct semaphore { +typedef struct cfs_semaphore { int foo; -} mutex_t; +} cfs_semaphore_t; -void sema_init(struct semaphore *s, int val); -void __down(struct semaphore *s); -void __up(struct semaphore *s); +void cfs_sema_init(cfs_semaphore_t *s, int val); +void __down(cfs_semaphore_t *s); +void __up(cfs_semaphore_t *s); /* - * Mutex: + * Completion: * - * - init_mutex(x) - * - init_mutex_locked(x) - * - mutex_up(x) - * - mutex_down(x) + * - cfs_init_completion_module(c) + * - cfs_call_wait_handler(t) + * - cfs_init_completion(c) + * - cfs_complete(c) + * - cfs_wait_for_completion(c) + * - cfs_wait_for_completion_interruptible(c) */ -#define mutex_up(s) __up(s) -#define mutex_down(s) __down(s) +typedef struct { + unsigned int done; + cfs_waitq_t wait; +} cfs_completion_t; -#define init_mutex(x) sema_init(x, 1) -#define init_mutex_locked(x) sema_init(x, 0) +typedef int (*cfs_wait_handler_t) (int timeout); +void cfs_init_completion_module(cfs_wait_handler_t handler); +int cfs_call_wait_handler(int timeout); +void cfs_init_completion(cfs_completion_t *c); +void cfs_complete(cfs_completion_t *c); +void cfs_wait_for_completion(cfs_completion_t *c); +int cfs_wait_for_completion_interruptible(cfs_completion_t *c); -/* - * Completion: - * - * - init_completion(c) - * - complete(c) - * - wait_for_completion(c) - */ -#if 0 -struct completion {}; +#define CFS_COMPLETION_INITIALIZER(work) \ + { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } + +#define CFS_DECLARE_COMPLETION(work) \ + cfs_completion_t work = CFS_COMPLETION_INITIALIZER(work) + +#define CFS_INIT_COMPLETION(x) ((x).done = 0) -void init_completion(struct completion *c); -void complete(struct completion *c); -void wait_for_completion(struct completion *c); -#endif /* - * rw_semaphore: + * cfs_rw_semaphore: * - * - init_rwsem(x) - * - down_read(x) - * - up_read(x) - * - down_write(x) - * - up_write(x) + * - cfs_init_rwsem(x) + * - cfs_down_read(x) + * - cfs_down_read_trylock(x) + * - cfs_down_write(struct cfs_rw_semaphore *s); + * - cfs_down_write_trylock(struct cfs_rw_semaphore *s); + * - cfs_up_read(x) + * - cfs_up_write(x) + * - cfs_fini_rwsem(x) */ -struct rw_semaphore {}; - -void init_rwsem(struct rw_semaphore *s); -void down_read(struct rw_semaphore *s); -int down_read_trylock(struct rw_semaphore *s); -void down_write(struct rw_semaphore *s); -int down_write_trylock(struct rw_semaphore *s); -void up_read(struct rw_semaphore *s); -void up_write(struct rw_semaphore *s); +typedef struct cfs_rw_semaphore { + int foo; +} cfs_rw_semaphore_t; + +void cfs_init_rwsem(cfs_rw_semaphore_t *s); +void cfs_down_read(cfs_rw_semaphore_t *s); +int cfs_down_read_trylock(cfs_rw_semaphore_t *s); +void cfs_down_write(cfs_rw_semaphore_t *s); +int cfs_down_write_trylock(cfs_rw_semaphore_t *s); +void cfs_up_read(cfs_rw_semaphore_t *s); +void cfs_up_write(cfs_rw_semaphore_t *s); +void cfs_fini_rwsem(cfs_rw_semaphore_t *s); +#define CFS_DECLARE_RWSEM(name) cfs_rw_semaphore_t name = { } /* * read-write lock : Need to be investigated more!! * XXX nikita: for now, let rwlock_t to be identical to rw_semaphore * - * - DECLARE_RWLOCK(l) - * - rwlock_init(x) - * - read_lock(x) - * - read_unlock(x) - * - write_lock(x) - * - write_unlock(x) + * - cfs_rwlock_init(x) + * - cfs_read_lock(x) + * - cfs_read_unlock(x) + * - cfs_write_lock(x) + * - cfs_write_unlock(x) + * - cfs_write_lock_irqsave(x) + * - cfs_write_unlock_irqrestore(x) + * - cfs_read_lock_irqsave(x) + * - cfs_read_unlock_irqrestore(x) */ -typedef struct rw_semaphore rwlock_t; +typedef cfs_rw_semaphore_t cfs_rwlock_t; +#define CFS_RW_LOCK_UNLOCKED (cfs_rwlock_t) { } -#define rwlock_init(pl) init_rwsem(pl) +#define cfs_rwlock_init(pl) cfs_init_rwsem(pl) -#define read_lock(l) down_read(l) -#define read_unlock(l) up_read(l) -#define write_lock(l) down_write(l) -#define write_unlock(l) up_write(l) +#define cfs_read_lock(l) cfs_down_read(l) +#define cfs_read_unlock(l) cfs_up_read(l) +#define cfs_write_lock(l) cfs_down_write(l) +#define cfs_write_unlock(l) cfs_up_write(l) static inline void -write_lock_irqsave(rwlock_t *l, unsigned long f) { write_lock(l); } +cfs_write_lock_irqsave(cfs_rwlock_t *l, unsigned long f) { cfs_write_lock(l); } static inline void -write_unlock_irqrestore(rwlock_t *l, unsigned long f) { write_unlock(l); } +cfs_write_unlock_irqrestore(cfs_rwlock_t *l, unsigned long f) { cfs_write_unlock(l); } -static inline void -read_lock_irqsave(rwlock_t *l, unsigned long f) { read_lock(l); } static inline void -read_unlock_irqrestore(rwlock_t *l, unsigned long f) { read_unlock(l); } +cfs_read_lock_irqsave(cfs_rwlock_t *l, unsigned long f) { cfs_read_lock(l); } +static inline void +cfs_read_unlock_irqrestore(cfs_rwlock_t *l, unsigned long f) { cfs_read_unlock(l); } /* - * Atomic for user-space - * Copied from liblustre + * Atomic for single-threaded user-space */ -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } -#define atomic_read(a) ((a)->counter) -#define atomic_set(a,b) do {(a)->counter = b; } while (0) -#define atomic_dec_and_test(a) ((--((a)->counter)) == 0) -#define atomic_inc(a) (((a)->counter)++) -#define atomic_dec(a) do { (a)->counter--; } while (0) -#define atomic_add(b,a) do {(a)->counter += b;} while (0) -#define atomic_add_return(n,a) ((a)->counter = n) -#define atomic_inc_return(a) atomic_add_return(1,a) -#define atomic_sub(b,a) do {(a)->counter -= b;} while (0) +typedef struct { volatile int counter; } cfs_atomic_t; -#endif +#define CFS_ATOMIC_INIT(i) { (i) } + +#define cfs_atomic_read(a) ((a)->counter) +#define cfs_atomic_set(a,b) do {(a)->counter = b; } while (0) +#define cfs_atomic_dec_and_test(a) ((--((a)->counter)) == 0) +#define cfs_atomic_dec_and_lock(a,b) ((--((a)->counter)) == 0) +#define cfs_atomic_inc(a) (((a)->counter)++) +#define cfs_atomic_dec(a) do { (a)->counter--; } while (0) +#define cfs_atomic_add(b,a) do {(a)->counter += b;} while (0) +#define cfs_atomic_add_return(n,a) ((a)->counter += n) +#define cfs_atomic_inc_return(a) cfs_atomic_add_return(1,a) +#define cfs_atomic_sub(b,a) do {(a)->counter -= b;} while (0) +#define cfs_atomic_sub_return(n,a) ((a)->counter -= n) +#define cfs_atomic_dec_return(a) cfs_atomic_sub_return(1,a) +#define cfs_atomic_add_unless(v, a, u) \ + ((v)->counter != u ? (v)->counter += a : 0) +#define cfs_atomic_inc_not_zero(v) cfs_atomic_add_unless((v), 1, 0) #ifdef HAVE_LIBPTHREAD #include /* - * Completion + * Multi-threaded user space completion APIs */ -struct cfs_completion { +typedef struct { int c_done; pthread_cond_t c_cond; pthread_mutex_t c_mut; -}; +} cfs_mt_completion_t; -void cfs_init_completion(struct cfs_completion *c); -void cfs_fini_completion(struct cfs_completion *c); -void cfs_complete(struct cfs_completion *c); -void cfs_wait_for_completion(struct cfs_completion *c); +void cfs_mt_init_completion(cfs_mt_completion_t *c); +void cfs_mt_fini_completion(cfs_mt_completion_t *c); +void cfs_mt_complete(cfs_mt_completion_t *c); +void cfs_mt_wait_for_completion(cfs_mt_completion_t *c); /* - * atomic.h + * Multi-threaded user space atomic APIs */ -typedef struct { volatile int counter; } cfs_atomic_t; +typedef struct { volatile int counter; } cfs_mt_atomic_t; -int cfs_atomic_read(cfs_atomic_t *a); -void cfs_atomic_set(cfs_atomic_t *a, int b); -int cfs_atomic_dec_and_test(cfs_atomic_t *a); -void cfs_atomic_inc(cfs_atomic_t *a); -void cfs_atomic_dec(cfs_atomic_t *a); -void cfs_atomic_add(int b, cfs_atomic_t *a); -void cfs_atomic_sub(int b, cfs_atomic_t *a); +int cfs_mt_atomic_read(cfs_mt_atomic_t *a); +void cfs_mt_atomic_set(cfs_mt_atomic_t *a, int b); +int cfs_mt_atomic_dec_and_test(cfs_mt_atomic_t *a); +void cfs_mt_atomic_inc(cfs_mt_atomic_t *a); +void cfs_mt_atomic_dec(cfs_mt_atomic_t *a); +void cfs_mt_atomic_add(int b, cfs_mt_atomic_t *a); +void cfs_mt_atomic_sub(int b, cfs_mt_atomic_t *a); #endif /* HAVE_LIBPTHREAD */ +/************************************************************************** + * + * Mutex interface. + * + **************************************************************************/ +#define CFS_DECLARE_MUTEX(name) \ + cfs_semaphore_t name = { 1 } + +#define cfs_mutex_up(s) __up(s) +#define cfs_up(s) cfs_mutex_up(s) +#define cfs_mutex_down(s) __down(s) +#define cfs_down(s) cfs_mutex_down(s) +#define cfs_mutex_down_interruptible(s) __down_interruptible(s) +#define cfs_down_interruptible(s) cfs_mutex_down_interruptible(s) + +#define cfs_init_mutex(x) cfs_sema_init(x, 1) +#define cfs_init_mutex_locked(x) cfs_sema_init(x, 0) + +typedef struct cfs_mutex { + cfs_semaphore_t m_sem; +} cfs_mutex_t; + +#define CFS_DEFINE_MUTEX(m) cfs_mutex_t m + +static inline void cfs_mutex_init(cfs_mutex_t *mutex) +{ + cfs_init_mutex(&mutex->m_sem); +} + +static inline void cfs_mutex_lock(cfs_mutex_t *mutex) +{ + cfs_mutex_down(&mutex->m_sem); +} + +static inline void cfs_mutex_unlock(cfs_mutex_t *mutex) +{ + cfs_mutex_up(&mutex->m_sem); +} + +/** + * Try-lock this mutex. + * + * + * \retval 0 try-lock succeeded (lock acquired). + * \retval errno indicates lock contention. + */ +static inline int cfs_mutex_down_trylock(cfs_mutex_t *mutex) +{ + return 0; +} + +/** + * Try-lock this mutex. + * + * Note, return values are negation of what is expected from down_trylock() or + * pthread_mutex_trylock(). + * + * \retval 1 try-lock succeeded (lock acquired). + * \retval 0 indicates lock contention. + */ +static inline int cfs_mutex_trylock(cfs_mutex_t *mutex) +{ + return !cfs_mutex_down_trylock(mutex); +} + +static inline void cfs_mutex_destroy(cfs_mutex_t *lock) +{ +} + +/* + * This is for use in assertions _only_, i.e., this function should always + * return 1. + * + * \retval 1 mutex is locked. + * + * \retval 0 mutex is not locked. This should never happen. + */ +static inline int cfs_mutex_is_locked(cfs_mutex_t *lock) +{ + return 1; +} + + +/************************************************************************** + * + * Lockdep "implementation". Also see lustre_compat25.h + * + **************************************************************************/ + +typedef struct cfs_lock_class_key { + int foo; +} cfs_lock_class_key_t; + +static inline void cfs_lockdep_set_class(void *lock, + cfs_lock_class_key_t *key) +{ +} + +static inline void cfs_lockdep_off(void) +{ +} + +static inline void cfs_lockdep_on(void) +{ +} + +#define cfs_mutex_lock_nested(mutex, subclass) cfs_mutex_lock(mutex) +#define cfs_spin_lock_nested(lock, subclass) cfs_spin_lock(lock) +#define cfs_down_read_nested(lock, subclass) cfs_down_read(lock) +#define cfs_down_write_nested(lock, subclass) cfs_down_write(lock) + + /* !__KERNEL__ */ #endif