[PATCH 2/4] Making the counter implementations safer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Palik, Imre" <imrep.amz@xxxxxxxxx>

Relevant parts of some of the counter implementations were prone to be optimised
out by an overly eager compiler/linker.

This patch makes the compiler's task easier, by declaring big parts of the
implementation inline.  Then proceeds to fix the issue.

Some barriers from the countertorture framework also got removed, as a proper
multithreaded implementation should provide its own ordering guarantees.

Signed-off-by: Imre Palik <imrep.amz@xxxxxxxxx>
---
 CodeSamples/count/Makefile              | 30 ++++++++++++++++--------------
 CodeSamples/count/count_atomic.c        |  6 +++---
 CodeSamples/count/count_end.c           |  9 +++++----
 CodeSamples/count/count_end_rcu.c       |  7 ++++---
 CodeSamples/count/count_nonatomic.c     |  8 ++++----
 CodeSamples/count/count_stack.c         |  9 +++++----
 CodeSamples/count/count_stat.c          |  6 +++---
 CodeSamples/count/count_stat_atomic.c   |  6 +++---
 CodeSamples/count/count_stat_eventual.c |  2 +-
 CodeSamples/count/count_tstat.c         |  3 ++-
 CodeSamples/count/counttorture.h        |  2 --
 11 files changed, 46 insertions(+), 42 deletions(-)

diff --git a/CodeSamples/count/Makefile b/CodeSamples/count/Makefile
index eacdb57..481eb3f 100644
--- a/CodeSamples/count/Makefile
+++ b/CodeSamples/count/Makefile
@@ -43,49 +43,51 @@ else
 all: $(PROGS)
 endif
 
+CC?=cc
+
 include $(top)/recipes.mk
 
 count_atomic: count_atomic.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_atomic count_atomic.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_atomic count_atomic.c -lpthread
 
 count_end: count_end.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_end count_end.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_end count_end.c -lpthread
 
 count_end_rcu: count_end_rcu.c ../api.h counttorture.h $(RCU_SRCS)
-	cc $(GCC_ARGS) $(CFLAGS) -o count_end_rcu count_end_rcu.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_end_rcu count_end_rcu.c -lpthread
 
 count_lim: count_lim.c ../api.h limtorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_lim count_lim.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_lim count_lim.c -lpthread
 
 count_lim_app: count_lim_app.c ../api.h limtorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_lim_app count_lim_app.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_lim_app count_lim_app.c -lpthread
 
 count_lim_atomic: count_lim_atomic.c ../api.h limtorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_lim_atomic count_lim_atomic.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_lim_atomic count_lim_atomic.c -lpthread
 
 count_lim_sig: count_lim_sig.c ../api.h limtorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_lim_sig count_lim_sig.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_lim_sig count_lim_sig.c -lpthread
 
 count_limd: count_limd.c ../api.h limtorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_limd count_limd.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_limd count_limd.c -lpthread
 
 count_nonatomic: count_nonatomic.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_nonatomic count_nonatomic.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_nonatomic count_nonatomic.c -lpthread
 
 count_stack: count_stack.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_stack count_stack.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_stack count_stack.c -lpthread
 
 count_stat: count_stat.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_stat count_stat.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_stat count_stat.c -lpthread
 
 count_stat_atomic: count_stat_atomic.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_stat_atomic count_stat_atomic.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_stat_atomic count_stat_atomic.c -lpthread
 
 count_stat_eventual: count_stat_eventual.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_stat_eventual count_stat_eventual.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_stat_eventual count_stat_eventual.c -lpthread
 
 count_tstat: count_tstat.c ../api.h counttorture.h
-	cc $(GCC_ARGS) $(CFLAGS) -o count_tstat count_tstat.c -lpthread
+	$(CC) $(GCC_ARGS) $(CFLAGS) -o count_tstat count_tstat.c -lpthread
 
 clean:
 	rm -f $(PROGS)
diff --git a/CodeSamples/count/count_atomic.c b/CodeSamples/count/count_atomic.c
index 0457aa1..fc73717 100644
--- a/CodeSamples/count/count_atomic.c
+++ b/CodeSamples/count/count_atomic.c
@@ -27,16 +27,16 @@ void inc_count(void)
 	atomic_inc(&counter);
 }
 
-long read_count(void)
+__inline__ long read_count(void)
 {
 	return atomic_read(&counter);
 }
 
-void count_init(void)
+__inline__ void count_init(void)
 {
 }
 
-void count_cleanup(void)
+__inline__ void count_cleanup(void)
 {
 }
 
diff --git a/CodeSamples/count/count_end.c b/CodeSamples/count/count_end.c
index a39c0c9..00335f2 100644
--- a/CodeSamples/count/count_end.c
+++ b/CodeSamples/count/count_end.c
@@ -26,9 +26,10 @@ unsigned long *counterp[NR_THREADS] = { NULL };
 unsigned long finalcount = 0;
 DEFINE_SPINLOCK(final_mutex);
 
-void inc_count(void)
+__inline__ void inc_count(void)
 {
-	counter++;
+	WRITE_ONCE(counter,
+		   READ_ONCE(counter) + 1);
 }
 
 unsigned long read_count(void)
@@ -45,7 +46,7 @@ unsigned long read_count(void)
 	return sum;
 }
 
-void count_init(void)
+__inline__ void count_init(void)
 {
 }
 
@@ -68,7 +69,7 @@ void count_unregister_thread(int nthreadsexpected)
 	spin_unlock(&final_mutex);
 }
 
-void count_cleanup(void)
+__inline__ void count_cleanup(void)
 {
 }
 
diff --git a/CodeSamples/count/count_end_rcu.c b/CodeSamples/count/count_end_rcu.c
index e6614b9..ca0a392 100644
--- a/CodeSamples/count/count_end_rcu.c
+++ b/CodeSamples/count/count_end_rcu.c
@@ -32,9 +32,10 @@ unsigned long __thread counter = 0;
 struct countarray *countarrayp = NULL;
 DEFINE_SPINLOCK(final_mutex);
 
-void inc_count(void)
+__inline__ void inc_count(void)
 {
-	counter++;
+	WRITE_ONCE(counter,
+		   READ_ONCE(counter) + 1);
 }
 
 unsigned long read_count(void)
@@ -94,7 +95,7 @@ void count_unregister_thread(int nthreadsexpected)
 	free(capold);
 }
 
-void count_cleanup(void)
+__inline__ void count_cleanup(void)
 {
 }
 
diff --git a/CodeSamples/count/count_nonatomic.c b/CodeSamples/count/count_nonatomic.c
index 868b0fe..90979c5 100644
--- a/CodeSamples/count/count_nonatomic.c
+++ b/CodeSamples/count/count_nonatomic.c
@@ -23,21 +23,21 @@
 
 unsigned long counter = 0;
 
-void inc_count(void)
+__inline__ void inc_count(void)
 {
 	counter++;
 }
 
-unsigned long read_count(void)
+__inline__ unsigned long read_count(void)
 {
 	return counter;
 }
 
-void count_init(void)
+__inline__ void count_init(void)
 {
 }
 
-void count_cleanup(void)
+__inline__ void count_cleanup(void)
 {
 }
 
diff --git a/CodeSamples/count/count_stack.c b/CodeSamples/count/count_stack.c
index aa6185d..975db48 100644
--- a/CodeSamples/count/count_stack.c
+++ b/CodeSamples/count/count_stack.c
@@ -26,9 +26,10 @@ unsigned long *counterp[NR_THREADS] = { NULL };
 unsigned long finalcount = 0;
 DEFINE_SPINLOCK(final_mutex);
 
-void inc_count(void)
+__inline__ void inc_count(void)
 {
-	(*counter)++;
+	WRITE_ONCE(*counter,
+		   READ_ONCE(*counter) + 1);
 }
 
 unsigned long read_count(void)
@@ -45,7 +46,7 @@ unsigned long read_count(void)
 	return sum;
 }
 
-void count_init(void)
+__inline__ void count_init(void)
 {
 }
 
@@ -69,7 +70,7 @@ void count_unregister_thread(int nthreadsexpected)
 	spin_unlock(&final_mutex);
 }
 
-void count_cleanup(void)
+__inline__ void count_cleanup(void)
 {
 }
 
diff --git a/CodeSamples/count/count_stat.c b/CodeSamples/count/count_stat.c
index b483022..1d72f99 100644
--- a/CodeSamples/count/count_stat.c
+++ b/CodeSamples/count/count_stat.c
@@ -27,7 +27,7 @@ void inc_count(void)
 	__get_thread_var(counter)++;
 }
 
-unsigned long read_count(void)
+__inline__ unsigned long read_count(void)
 {
 	int t;
 	unsigned long sum = 0;
@@ -37,11 +37,11 @@ unsigned long read_count(void)
 	return sum;
 }
 
-void count_init(void)
+__inline__ void count_init(void)
 {
 }
 
-void count_cleanup(void)
+__inline__ void count_cleanup(void)
 {
 }
 
diff --git a/CodeSamples/count/count_stat_atomic.c b/CodeSamples/count/count_stat_atomic.c
index 732ab6d..d1ff10b 100644
--- a/CodeSamples/count/count_stat_atomic.c
+++ b/CodeSamples/count/count_stat_atomic.c
@@ -27,7 +27,7 @@ void inc_count(void)
 	atomic_inc(&__get_thread_var(counter));
 }
 
-unsigned long read_count(void)
+__inline__ unsigned long read_count(void)
 {
 	int t;
 	unsigned long sum = 0;
@@ -37,11 +37,11 @@ unsigned long read_count(void)
 	return sum;
 }
 
-void count_init(void)
+__inline__ void count_init(void)
 {
 }
 
-void count_cleanup(void)
+__inline__ void count_cleanup(void)
 {
 }
 
diff --git a/CodeSamples/count/count_stat_eventual.c b/CodeSamples/count/count_stat_eventual.c
index 2b23dbd..324bc24 100644
--- a/CodeSamples/count/count_stat_eventual.c
+++ b/CodeSamples/count/count_stat_eventual.c
@@ -31,7 +31,7 @@ void inc_count(void)
 		   READ_ONCE(__get_thread_var(counter)) + 1);
 }
 
-unsigned long read_count(void)
+__inline__ unsigned long read_count(void)
 {
 	return READ_ONCE(global_count);
 }
diff --git a/CodeSamples/count/count_tstat.c b/CodeSamples/count/count_tstat.c
index 1fa4e52..59e4025 100644
--- a/CodeSamples/count/count_tstat.c
+++ b/CodeSamples/count/count_tstat.c
@@ -29,7 +29,8 @@ DEFINE_SPINLOCK(final_mutex);
 
 void inc_count(void)
 {
-	counter++;
+	WRITE_ONCE(counter,
+		   READ_ONCE(counter) + 1);
 }
 
 unsigned long read_count(void)  /* known failure with counttorture! */
diff --git a/CodeSamples/count/counttorture.h b/CodeSamples/count/counttorture.h
index ff0dd72..bdfc7d4 100644
--- a/CodeSamples/count/counttorture.h
+++ b/CodeSamples/count/counttorture.h
@@ -86,7 +86,6 @@ void *count_read_perf_test(void *arg)
 	while (READ_ONCE(goflag) == GOFLAG_RUN) {
 		for (i = COUNT_READ_RUN; i > 0; i--) {
 			j += read_count();
-			barrier();
 		}
 		n_reads_local += COUNT_READ_RUN;
 	}
@@ -110,7 +109,6 @@ void *count_update_perf_test(void *arg)
 	while (READ_ONCE(goflag) == GOFLAG_RUN) {
 		for (i = COUNT_UPDATE_RUN; i > 0; i--) {
 			inc_count();
-			barrier();
 		}
 		n_updates_local += COUNT_UPDATE_RUN;
 	}
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe perfbook" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux