From 430484c92ab5a6234958d1143e0bb14aeb0cd1c0 Mon Sep 17 00:00:00 2001 From: Mohit Agrawal Date: Fri, 20 Oct 2017 12:39:29 +0530 Subject: glusterfs: Use gcc builtin ATOMIC operator to increase/decreate refcount. Problem: In glusterfs code base we call mutex_lock/unlock to take reference/dereference for a object.Sometime it could be reason for lock contention also. Solution: There is no need to use mutex to increase/decrease ref counter, instead of using mutex use gcc builtin ATOMIC operation. Test: I have not observed yet how much performance gain after apply this patch specific to glusterfs but i have tested same with below small program(mutex and atomic both) and get good difference. static int numOuterLoops; static void * threadFunc(void *arg) { int j; for (j = 0; j < numOuterLoops; j++) { __atomic_add_fetch (&glob, 1,__ATOMIC_ACQ_REL); } return NULL; } int main(int argc, char *argv[]) { int opt, s, j; int numThreads; pthread_t *thread; int verbose; int64_t n = 0; if (argc < 2 ) { printf(" Please provide 2 args Num of threads && Outer Loop\n"); exit (-1); } numThreads = atoi(argv[1]); numOuterLoops = atoi (argv[2]); if (1) { printf("\tthreads: %d; outer loops: %d;\n", numThreads, numOuterLoops); } thread = calloc(numThreads, sizeof(pthread_t)); if (thread == NULL) { printf ("calloc error so exit\n"); exit (-1); } __atomic_store (&glob, &n, __ATOMIC_RELEASE); for (j = 0; j < numThreads; j++) { s = pthread_create(&thread[j], NULL, threadFunc, NULL); if (s != 0) { printf ("pthread_create failed so exit\n"); exit (-1); } } for (j = 0; j < numThreads; j++) { s = pthread_join(thread[j], NULL); if (s != 0) { printf ("pthread_join failed so exit\n"); exit (-1); } } printf("glob value is %ld\n",__atomic_load_n (&glob,__ATOMIC_RELAXED)); exit(0); } time ./thr_count 800 800000 threads: 800; outer loops: 800000; glob value is 640000000 real 1m10.288s user 0m57.269s sys 3m31.565s time ./thr_count_atomic 800 800000 threads: 800; outer loops: 800000; glob value is 640000000 real 0m20.313s user 1m20.558s sys 0m0.028 Change-Id: Ie5030a52ea264875e002e108dd4b207b15ab7cc7 Signed-off-by: Mohit Agrawal --- .../features/changelog/src/changelog-ev-handle.h | 22 ++++++++-------------- xlators/features/changelog/src/changelog-rpc.c | 2 +- 2 files changed, 9 insertions(+), 15 deletions(-) (limited to 'xlators/features/changelog') diff --git a/xlators/features/changelog/src/changelog-ev-handle.h b/xlators/features/changelog/src/changelog-ev-handle.h index eef0492a9ee..e89af8793a8 100644 --- a/xlators/features/changelog/src/changelog-ev-handle.h +++ b/xlators/features/changelog/src/changelog-ev-handle.h @@ -24,7 +24,7 @@ typedef struct changelog_rpc_clnt { gf_lock_t lock; - unsigned long ref; + gf_atomic_t ref; gf_boolean_t disconnected; unsigned int filter; @@ -43,11 +43,7 @@ typedef struct changelog_rpc_clnt { static inline void changelog_rpc_clnt_ref (changelog_rpc_clnt_t *crpc) { - LOCK (&crpc->lock); - { - ++crpc->ref; - } - UNLOCK (&crpc->lock); + GF_ATOMIC_INC (crpc->ref); } static inline void @@ -66,16 +62,14 @@ static inline void changelog_rpc_clnt_unref (changelog_rpc_clnt_t *crpc) { gf_boolean_t gone = _gf_false; + uint64_t ref = 0; + + ref = GF_ATOMIC_DEC (crpc->ref); - LOCK (&crpc->lock); - { - if (!(--crpc->ref) - && changelog_rpc_clnt_is_disconnected (crpc)) { - list_del (&crpc->list); - gone = _gf_true; - } + if (!ref && changelog_rpc_clnt_is_disconnected (crpc)) { + list_del (&crpc->list); + gone = _gf_true; } - UNLOCK (&crpc->lock); if (gone) crpc->cleanup (crpc); diff --git a/xlators/features/changelog/src/changelog-rpc.c b/xlators/features/changelog/src/changelog-rpc.c index 5524e433cbb..72b5cdbc7cb 100644 --- a/xlators/features/changelog/src/changelog-rpc.c +++ b/xlators/features/changelog/src/changelog-rpc.c @@ -211,7 +211,7 @@ changelog_rpc_clnt_init (xlator_t *this, /* Take a ref, the last unref will be on RPC_CLNT_DESTROY * which comes as a result of last rpc_clnt_unref. */ - crpc->ref = 1; + GF_ATOMIC_INIT (crpc->ref, 1); changelog_set_disconnect_flag (crpc, _gf_false); crpc->filter = rpc_req->filter; -- cgit