From 87300be91cb9e1cd98ac5cba8998524d95c98d12 Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Sat, 23 Mar 2013 13:55:09 -0700 Subject: synctask: introduce synclocks for co-operative locking This patch introduces a synclocks - co-operative locks for synctasks. Synctasks yield themselves when a lock cannot be acquired at the time of the lock call, and the unlocker will wake the yielded locker at the time of unlock. The implementation is safe in a multi-threaded syncenv framework. It is also safe for sharing the lock between non-synctasks. i.e, the same lock can be used for synchronization between a synctask and a regular thread. In such a situation, waiting synctasks will yield themselves while non-synctasks will sleep on a cond variable. The unlocker (which could be either a synctask or a regular thread) will wake up any type of lock waiter (synctask or regular). Usage: Declaration and Initialization ------------------------------ synclock_t lock; ret = synclock_init (&lock); if (ret) { /* lock could not be allocated */ } Locking and non-blocking lock attempt ------------------------------------- ret = synclock_trylock (&lock); if (ret && (errno == EBUSY)) { /* lock is held by someone else */ return; } synclock_lock (&lock); { /* critical section */ } synclock_unlock (&lock); Change-Id: I081873edb536ddde69a20f4a7dc6558ebf19f5b2 BUG: 763820 Signed-off-by: Anand Avati Reviewed-on: http://review.gluster.org/4717 Reviewed-by: Krishnan Parthasarathi Tested-by: Gluster Build System Reviewed-by: Raghavendra G Reviewed-by: Jeff Darcy --- libglusterfs/src/syncop.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'libglusterfs/src/syncop.h') diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h index aec07f360..ee8a3277d 100644 --- a/libglusterfs/src/syncop.h +++ b/libglusterfs/src/syncop.h @@ -69,6 +69,8 @@ struct synctask { pthread_mutex_t mutex; /* for synchronous spawning of synctask */ pthread_cond_t cond; int done; + + struct list_head waitq; /* can wait only "once" at a time */ }; @@ -96,6 +98,15 @@ struct syncenv { }; +struct synclock { + pthread_mutex_t guard; /* guard the remaining members, pair @cond */ + pthread_cond_t cond; /* waiting non-synctasks */ + struct list_head waitq; /* waiting synctasks */ + gf_boolean_t lock; /* _gf_true or _gf_false, lock status */ + struct synctask *owner; /* NULL if current owner is not a synctask */ +}; +typedef struct synclock synclock_t; + struct syncargs { int op_ret; int op_errno; @@ -220,6 +231,13 @@ void synctask_waitfor (struct synctask *task, int count); int synctask_setid (struct synctask *task, uid_t uid, gid_t gid); #define SYNCTASK_SETID(uid, gid) synctask_setid (synctask_get(), uid, gid); + +int synclock_init (synclock_t *lock); +int synclock_destory (synclock_t *lock); +int synclock_lock (synclock_t *lock); +int synclock_trylock (synclock_t *lock); +int synclock_unlock (synclock_t *lock); + int syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req, /* out */ struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent); -- cgit