diff options
author | Mohit Agrawal <moagrawa@redhat.com> | 2017-10-20 12:39:29 +0530 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2017-12-12 09:05:56 +0000 |
commit | 430484c92ab5a6234958d1143e0bb14aeb0cd1c0 (patch) | |
tree | 0fb39e2a1c9be94396736d76b9aaababf232821b /libglusterfs/src/dict.c | |
parent | 8483ed87165c1695b513e223549d33d2d63891d9 (diff) |
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 <moagrawa@redhat.com>
Diffstat (limited to 'libglusterfs/src/dict.c')
-rw-r--r-- | libglusterfs/src/dict.c | 31 |
1 files changed, 6 insertions, 25 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index a47c8529709..d0be267d2ee 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -579,8 +579,8 @@ dict_destroy (dict_t *this) data_pair_t *pair = this->members_list; data_pair_t *prev = this->members_list; glusterfs_ctx_t *ctx = NULL; - uint32_t total_pairs = 0; uint64_t current_max = 0; + uint32_t total_pairs = 0; LOCK_DESTROY (&this->lock); @@ -629,7 +629,7 @@ dict_destroy (dict_t *this) void dict_unref (dict_t *this) { - int32_t ref; + uint64_t ref = 0; if (!this) { gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL, @@ -637,12 +637,7 @@ dict_unref (dict_t *this) return; } - LOCK (&this->lock); - - this->refcount--; - ref = this->refcount; - - UNLOCK (&this->lock); + ref = GF_ATOMIC_DEC (this->refcount); if (!ref) dict_destroy (this); @@ -657,12 +652,7 @@ dict_ref (dict_t *this) return NULL; } - LOCK (&this->lock); - - this->refcount++; - - UNLOCK (&this->lock); - + GF_ATOMIC_INC (this->refcount); return this; } @@ -678,12 +668,7 @@ data_unref (data_t *this) return; } - LOCK (&this->lock); - - this->refcount--; - ref = this->refcount; - - UNLOCK (&this->lock); + ref = GF_ATOMIC_DEC (this->refcount); if (!ref) data_destroy (this); @@ -698,11 +683,7 @@ data_ref (data_t *this) return NULL; } - LOCK (&this->lock); - - this->refcount++; - - UNLOCK (&this->lock); + GF_ATOMIC_INC (this->refcount); return this; } |