CodeSamples: Cleanups and fixes
cover CodeSamples: Cleanups and fixes
From fd5fb9afb6b99b15370a9823b42fa2a92342b92a Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 06:52:40 +0900
Subject: [RFC PATCH 0/4] CodeSamples: Cleanups and fixes
Hi Paul,
While I was looking around CodeSamples, I encountered several warnings in build and an infinite loop in one of sample codes. Also, I found that CodeSamples/api.h and CodeSamples/Makefile.arch can be removed from repository if their recipe are properly written in Makefiles.
Patch 1 adds rules to generate Makefile.arch and api.h that suit the architecture of you host. As I don't have ppc64 or arm host environment, I tested it only on x86_32 and x86_64. I'd like to know if it works on ppc64 and arm.
Patch 2 removes the redundant files.
Patch 3 and 4 are fixes of warnings and infinite loops.
Thoughts?
Thanks, Akira
Signature · 35 lines
Akira Yokosawa (4): CodeSamples: Add rule to generate Makefile.arch and api.h CodeSamples: Remove generated files from repository CodeSamples: Use 'intptr_t' to be compatible with 'void *' CodeSamples/defer: Add compiler barriers in gettimestampmp.c CodeSamples/.gitignore | 4 +- CodeSamples/Makefile | 18 + CodeSamples/Makefile.arch | 6 - CodeSamples/SMPdesign/Makefile | 3 + CodeSamples/SMPdesign/matmul.c | 13 +- CodeSamples/SMPdesign/smpalloc.c | 11 +- CodeSamples/advsync/Makefile | 3 + CodeSamples/api.h | 808 ------------------------- CodeSamples/count/Makefile | 3 + CodeSamples/datastruct/Issaquah/Makefile | 3 + CodeSamples/datastruct/Issaquah/existence_test | Bin 26359 -> 0 bytes CodeSamples/datastruct/hash/Makefile | 3 + CodeSamples/datastruct/log/Makefile | 3 + CodeSamples/datastruct/skiplist/Makefile | 3 + CodeSamples/defer/Makefile | 3 + CodeSamples/defer/gettimestampmp.c | 5 +- CodeSamples/depends.mk | 43 ++ CodeSamples/intro/Makefile | 3 + CodeSamples/intro/threadcreate.c | 7 +- CodeSamples/locking/Makefile | 3 + CodeSamples/toolsoftrade/Makefile | 3 + 21 files changed, 117 insertions(+), 831 deletions(-) delete mode 100644 CodeSamples/Makefile.arch delete mode 100644 CodeSamples/api.h delete mode 100755 CodeSamples/datastruct/Issaquah/existence_test create mode 100644 CodeSamples/depends.mk -- 2.7.4
RFC PATCH 1/4 CodeSamples: Add rule to generate Makefile.arch and api.h
From b4845ac3b17aaade7258528fa114def5f6554242 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Sun, 28 May 2017 09:29:44 +0900
Subject: [RFC PATCH 1/4] CodeSamples: Add rule to generate Makefile.arch and api.h
To generate suitable Makefile.arch and api.h for host arch, describe the dependency in depends.mk and include it in Makefiles.
--- CodeSamples/Makefile | 18 +++++++++++++ CodeSamples/SMPdesign/Makefile | 3 +++ CodeSamples/advsync/Makefile | 3 +++ CodeSamples/count/Makefile | 3 +++ CodeSamples/datastruct/Issaquah/Makefile | 3 +++ CodeSamples/datastruct/hash/Makefile | 3 +++ CodeSamples/datastruct/log/Makefile | 3 +++ CodeSamples/datastruct/skiplist/Makefile | 3 +++ CodeSamples/defer/Makefile | 3 +++ CodeSamples/depends.mk | 43 ++++++++++++++++++++++++++++++++ CodeSamples/intro/Makefile | 3 +++ CodeSamples/locking/Makefile | 3 +++ CodeSamples/toolsoftrade/Makefile | 3 +++ 13 files changed, 94 insertions(+) create mode 100644 CodeSamples/depends.mk
CodeSamples/Makefile +18 -0
@@ -1,3 +1,7 @@ +.PHONY: all clean pthreads pthreads-x86 pthreads-ppc64 pthreads-arm + +top := . + all: (cd SMPdesign; make) (cd advsync; make)
@@ -6,6 +10,17 @@ all: (cd intro; make) (cd toolsoftrade; make) +include depends.mk + +api.h Makefile.arch: +ifeq ($(strip $(target)),) + make pthreads + $(warning "Could not figure out which target to use (arch:$(arch)).\ + Used 'make pthreads' in CodeSamples/Makefile.") +else + make pthreads-$(target) +endif + pthreads: echo "#ifndef __PERFBOOK_API_H__" > api.h echo "#define __PERFBOOK_API_H__" >> api.h
@@ -125,3 +140,6 @@ pthreads-arm: echo "#endif /* #ifndef __PERFBOOK_API_H__ */" >> api.h echo "# MECHANICALLY GENERATED, DO NOT EDIT!!!" > Makefile.arch cat arch-arm/Makefile.arch >> Makefile.arch + +clean: + rm -f Makefile.arch api.h
CodeSamples/SMPdesign/Makefile +3 -0
@@ -25,6 +25,9 @@ include ../Makefile.arch # http://www.ibm.com/developerworks/wikis/display/hpccentral/Tuning+options+to+consider+with+gcc#Tuningoptionstoconsiderwithgcc-mcpuandmtune # GCC_ARGS=-g -O3 -m64 -mcpu=power5 -mtune=power5 +top := .. +include $(top)/depends.mk + smpalloc: smpalloc.c ../api.h cc $(GCC_ARGS) -g -o smpalloc -DTEST smpalloc.c -lpthread
CodeSamples/advsync/Makefile +3 -0
@@ -20,6 +20,9 @@ PROGS = q singleq wfenqueue all: $(PROGS) +top := .. +include $(top)/depends.mk + q: q.c q.h queuetorture.h ../api.h cc $(GCC_ARGS) -o q -DTEST q.c -lpthread
CodeSamples/count/Makefile +3 -0
@@ -35,6 +35,9 @@ RCU_SRCS = ../defer/rcu_nest32.h ../defer/rcu_nest32.c all: $(PROGS) +top := .. +include $(top)/depends.mk + count_atomic: count_atomic.c ../api.h counttorture.h cc $(GCC_ARGS) $(CFLAGS) -o count_atomic count_atomic.c -lpthread
CodeSamples/datastruct/Issaquah/Makefile +3 -0
@@ -21,6 +21,9 @@ LIB = ../../lib all: $(PROGS) +top := ../.. +include $(top)/depends.mk + # NOTE: For decent scalability on update-side tests as of early 2015, # use something like jemalloc() instead of glibc malloc(). # If you install jemalloc at /home/paulmck/jemalloc, you will
CodeSamples/datastruct/hash/Makefile +3 -0
@@ -20,6 +20,9 @@ PROGS = hash_bkt hash_bkt_hazptr hash_bkt_rcu hash_global hash_resize all: $(PROGS) +top := ../.. +include $(top)/depends.mk + hash_bkt: hash_bkt.c ../../api.h hashtorture.h cc $(GCC_ARGS) -DTEST_HASH -o hash_bkt hash_bkt.c -lpthread
CodeSamples/datastruct/log/Makefile +3 -0
@@ -21,6 +21,9 @@ LIB = ../../lib all: $(PROGS) +top := ../.. +include $(top)/depends.mk + log_glock: log_glock.c ../../api.h logtorture.h log.h cc $(GCC_ARGS) -DTEST_LOG -I $(LIB) -g -o log_glock log_glock.c $(LIB)/random.c -lpthread
CodeSamples/datastruct/skiplist/Makefile +3 -0
@@ -21,6 +21,9 @@ LIB = ../../lib all: $(PROGS) +top := ../.. +include $(top)/depends.mk + skiplist: skiplist.c ../../api.h skiplisttorture.h skiplist.h cc $(GCC_ARGS) -DTEST_SKIPLIST -I $(LIB) -g -o skiplist skiplist.c $(LIB)/random.c -lpthread -lurcu -lurcu-signal
CodeSamples/defer/Makefile +3 -0
@@ -46,6 +46,9 @@ PROGS = bug_rcu_dp \ all: $(PROGS) +top := .. +include $(top)/depends.mk + # Note that bug_srcu_a is disabled until completed. bug_srcu_a: bug_srcu_a.c srcu.c ../api.h cc $(GCC_ARGS) -o bug_srcu_a -DTEST bug_srcu_a.c -lurcu -lpthread
CodeSamples/depends.mk new file +43 -0
43 lines not on this page · raw message
CodeSamples/intro/Makefile +3 -0
@@ -2,6 +2,9 @@ PROGS = initrace initraceperf lockinc nakedinc perthreadinc threadcreate all: $(PROGS) +top := .. +include $(top)/depends.mk + initrace: initrace.c ../api.h cc -g -Wall -o initrace initrace.c -lpthread
CodeSamples/locking/Makefile +3 -0
@@ -2,6 +2,9 @@ PROGS = locked_list xchglock all: $(PROGS) +top := .. +include $(top)/depends.mk + locked_list: locked_list.c ../api.h cc -g -Wall -o locked_list locked_list.c
CodeSamples/toolsoftrade/Makefile +3 -0
@@ -26,6 +26,9 @@ PROGS = forkjoin \ all: $(PROGS) +top := .. +include $(top)/depends.mk + forkjoin: forkjoin.c ../api.h cc $(GCC_ARGS) -o forkjoin forkjoin.c
Signature · 1 line
2.7.4
RFC PATCH 2/4 CodeSamples: Remove generated files from repository
In reply to Akira YokosawaFrom 10024f2b41c129e5e7e892c60946c8dd5dd58007 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Sun, 28 May 2017 09:40:21 +0900
Subject: [RFC PATCH 2/4] CodeSamples: Remove generated files from repository
Now, as Makefile.arch and api.h are generated when necessary, they are no longer necessary in the repository.
Also fix entry for gprof-helper.c in .gitignore and remove an executable file sneaked into repository under datastruct/Issaquah/.
--- CodeSamples/.gitignore | 4 +- CodeSamples/Makefile.arch | 6 - CodeSamples/api.h | 808 ------------------------- CodeSamples/datastruct/Issaquah/existence_test | Bin 26359 -> 0 bytes 4 files changed, 3 insertions(+), 815 deletions(-) delete mode 100644 CodeSamples/Makefile.arch delete mode 100644 CodeSamples/api.h delete mode 100755 CodeSamples/datastruct/Issaquah/existence_test
CodeSamples/.gitignore +3 -1
@@ -1 +1,3 @@ -./gprof-helper.c +/gprof-helper.c +/Makefile.arch +/api.h
CodeSamples/Makefile.arch deleted +0 -6
@@ -1,6 +0,0 @@ -# MECHANICALLY GENERATED, DO NOT EDIT!!! - -# For use on 64-bit systems, add -m32. You might also need to install -# g++-multilib (thanks to [email protected]). - -GCC_ARGS=-g -O3 -Wall
CodeSamples/api.h deleted +0 -808
808 lines not on this page · raw message
CodeSamples/datastruct/Issaquah/existence_test deleted binary +0 -0
Signature · 1 line
2.7.4
RFC PATCH 3/4 CodeSamples: Use 'intptr_t' to be compatible with 'void *'
In reply to Akira YokosawaFrom e325a5ff132d8e4a79dfe465b18f573b97da75db Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Sun, 28 May 2017 12:38:27 +0900
Subject: [RFC PATCH 3/4] CodeSamples: Use 'intptr_t' to be compatible with 'void *'
On x86_64, casting between "int" and "void *" in threadcreate.c causes GCC to emit warnings such as:
warning: cast from pointer to integer of different size
warning: cast from integer to pointer of different size
Let's adopt C99 way of writing portable code.
Also do the same changes where appropriate. (Other than threadcreate.c, no warnings were observed on x86_64, but we can remove a few casts to "long".)
--- CodeSamples/SMPdesign/matmul.c | 13 +++++++------ CodeSamples/SMPdesign/smpalloc.c | 11 ++++++----- CodeSamples/defer/gettimestampmp.c | 2 +- CodeSamples/intro/threadcreate.c | 7 ++++--- 4 files changed, 18 insertions(+), 15 deletions(-)
CodeSamples/SMPdesign/matmul.c +7 -6
@@ -18,12 +18,13 @@* Copyright (c) 2009 Paul E. McKenney, IBM Corporation. */ +#include <inttypes.h> #include "../api.h" float *a;float *b;float *c; -long dim =1000 ; +intptr_t dim =1000 ;int nthread =1 ;#define GOFLAG_INIT 0
@@ -38,8 +39,8 @@ atomic_t nstarted;void *matmul_thread (void *me_in) { -long me = (long )me_in; -int i, j, k; +intptr_t me = (intptr_t )me_in; +intptr_t i, j, k;atomic_inc (&nstarted);while (goflag ==GOFLAG_INIT )
@@ -58,7 +59,7 @@ void *matmul_thread(void *me_in)int main (int argc,char *argv[]) { -int i, j; +intptr_t i, j;long long startcreatetime;long long starttime;long long endtime;
@@ -87,7 +88,7 @@ int main(int argc, char *argv[]) goflag =GOFLAG_INIT ; startcreatetime =get_microseconds ();for (i =0 ; i < nthread; i++) -create_thread (matmul_thread, (void *)(long )i); +create_thread (matmul_thread, (void *)i);while (atomic_read (&nstarted) != nthread)barrier (); starttime =get_microseconds ();
@@ -95,7 +96,7 @@ int main(int argc, char *argv[])while (atomic_read (&ndone) != nthread)poll (NULL ,0 ,1 ); endtime =get_microseconds (); -printf ("dim = %ld, nthread = %d, duration = %lld : %lld us\n" , +printf ("dim = %" PRIdPTR", nthread = %d, duration = %lld : %lld us\n" , dim, nthread, endtime - startcreatetime, endtime - starttime);return 0 ; }
CodeSamples/SMPdesign/smpalloc.c +6 -5
@@ -19,6 +19,7 @@* Copyright (c) 2006 Paul E. McKenney, IBM Corporation. */ +#include <inttypes.h> #include "../api.h" #define TARGET_POOL_SIZE 3
@@ -123,7 +124,7 @@ void *memblock_test(void *arg)long cnt =0 ;long cntfail =0 ;int i; -int runlength = (int )(long )arg; +intptr_t runlength = (intptr_t )arg;struct memblock *p[MAX_RUN ];if (runlength >MAX_RUN )
@@ -159,7 +160,7 @@ int main(int argc, char *argv[])long long nc;long long nf;int nkids =1 ; -int runlength =1 ; +intptr_t runlength =1 ;int totbefore;smp_init ();
@@ -176,12 +177,12 @@ int main(int argc, char *argv[])if (argc >2 ) { runlength =strtoul (argv[2 ],NULL ,0 );if (runlength >MAX_RUN ) { -fprintf (stderr,"nkids = %d too large, max = %d\n" , +fprintf (stderr,"nkids = %" PRIdPTR" too large, max = %d\n" , runlength,MAX_RUN );usage (argv[0 ]); } } -printf ("%d %d " , nkids, runlength); +printf ("%d %" PRIdPTR, nkids, runlength);init_per_thread (results,0L );init_per_thread (failures,0L );
@@ -189,7 +190,7 @@ int main(int argc, char *argv[]) goflag =1 ;for (i =0 ; i < nkids; i++) -create_thread (memblock_test, (void *)(long )runlength); +create_thread (memblock_test, (void *)runlength);sleep (1 ); goflag =0 ;
CodeSamples/defer/gettimestampmp.c +1 -1
@@ -29,7 +29,7 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) { -long mask = (long )mask_in; +intptr_t mask = (intptr_t )mask_in;while (curtimestamp <MAX_TIMESTAMPS ) {while ((curtimestamp &CURTIMESTAMP_MASK ) != mask)
CodeSamples/intro/threadcreate.c +4 -3
@@ -18,13 +18,14 @@* Copyright (c) 2006 Paul E. McKenney, IBM Corporation. */ +#include <inttypes.h> #include "../api.h" void *thread_test (void *arg) { -int myarg = (int )arg; +intptr_t myarg = (intptr_t )arg; -printf ("child thread %d: smp_thread_id() = %d\n" , +printf ("child thread %" PRIdPTR": smp_thread_id() = %d\n" , myarg,smp_thread_id ());return NULL ; }
@@ -38,7 +39,7 @@ void usage(char *progname)int main (int argc,char *argv[]) { -int i; +intptr_t i;int nkids =1 ;smp_init ();
Signature · 1 line
2.7.4
Re: [RFC PATCH 3/4] CodeSamples: Use 'intptr_t' to be compatible with 'void *'
Quoted 31 lines · Akira Yokosawa
Quoted 1 line
From
e325a5ff132d8e4a79dfe465b18f573b97da75dbMon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Sun, 28 May 2017 12:38:27 +0900
Subject: [RFC PATCH 3/4] CodeSamples: Use 'intptr_t' to be compatible with 'void *'On
x86_64, casting between "int" and "void *" inthreadcreate.ccauses GCC to emit warnings such as:warning: cast from pointer to integer of different size
warning: cast from integer to pointer of different sizeLet's adopt C99 way of writing portable code.
Also do the same changes where appropriate. (Other than
threadcreate.c, no warnings were observed onx86_64, but we can remove a few casts to "long".)Signed-off-by Akira Yokosawa <[email protected]>--- CodeSamples/SMPdesign/matmul.c | 13 +++++++------ CodeSamples/SMPdesign/smpalloc.c | 11 ++++++----- CodeSamples/defer/gettimestampmp.c | 2 +- CodeSamples/intro/threadcreate.c | 7 ++++--- 4 files changed, 18 insertions(+), 15 deletions(-)CodeSamples/SMPdesign/matmul.c +0
-0@@ -18,12 +18,13 @@* Copyright (c) 2009 Paul E. McKenney, IBM Corporation.
CodeSamples/SMPdesign/matmul.c line 27
Quoted 10 lines
CodeSamples/SMPdesign/matmul.c +2
-1*/ +#include <inttypes.h> #include "../api.h" float *a;float *b;float *c; -long dim =1000 ; +intptr_t dim =1000 ;
This really is an int, used only for array index calculations. I don't see how it helps to make it be an intptr_t. What am I missing?
CodeSamples/SMPdesign/matmul.c atomic_t nstarted; · line 43
Quoted 11 lines
CodeSamples/SMPdesign/matmul.c +2
-2int nthread =1 ;#define GOFLAG_INIT 0@@ -38,8 +39,8 @@ atomic_t nstarted;void *matmul_thread (void *me_in) { -long me = (long )me_in; -int i, j, k; +intptr_t me = (intptr_t )me_in; +intptr_t i, j, k;
Hmmm... Now "me" is a long and used as such, but the conversion from a pointer on 32-bit systems could get warnings on some systems. But it is guaranteed to be a small integer. Would something like this work?
int me = (int)(long)me_in;
Or this?
int me = (intptr_t)me_in;
Or even this?
int me = ((intptr_t)me_in) & 0xffffffff;
I suppose that the painfully correct way to do this would be to pass in a pointer to a structure containing a lone int. Any other approaches that work?
The variables i, j, and k, like dim, are used only as int to compute array indexes.
I have similar concerns about the remaining cases. I am not inalterably opposed, but it seems better to keep intptr_t usage more confined.
Thanx, Paul
Quoted 135 lines
CodeSamples/SMPdesign/matmul.c +3
-3atomic_inc (&nstarted);while (goflag ==GOFLAG_INIT )@@ -58,7 +59,7 @@ void *matmul_thread(void *me_in)int main (int argc,char *argv[]) { -int i, j; +intptr_t i, j;long long startcreatetime;long long starttime;long long endtime;@@ -87,7 +88,7 @@ int main(int argc, char *argv[]) goflag =GOFLAG_INIT ; startcreatetime =get_microseconds ();for (i =0 ; i < nthread; i++) -create_thread (matmul_thread, (void *)(long )i); +create_thread (matmul_thread, (void *)i);while (atomic_read (&nstarted) != nthread)barrier (); starttime =get_microseconds ();@@ -95,7 +96,7 @@ int main(int argc, char *argv[])while (atomic_read (&ndone) != nthread)poll (NULL ,0 ,1 ); endtime =get_microseconds (); -printf ("dim = %ld, nthread = %d, duration = %lld : %lld us\n" , +printf ("dim = %" PRIdPTR", nthread = %d, duration = %lld : %lld us\n" , dim, nthread, endtime - startcreatetime, endtime - starttime);return 0 ; }CodeSamples/SMPdesign/smpalloc.c +6
-5@@ -19,6 +19,7 @@* Copyright (c) 2006 Paul E. McKenney, IBM Corporation. */ +#include <inttypes.h> #include "../api.h" #define TARGET_POOL_SIZE 3@@ -123,7 +124,7 @@ void *memblock_test(void *arg)long cnt =0 ;long cntfail =0 ;int i; -int runlength = (int )(long )arg; +intptr_t runlength = (intptr_t )arg;struct memblock *p[MAX_RUN ];if (runlength >MAX_RUN )@@ -159,7 +160,7 @@ int main(int argc, char *argv[])long long nc;long long nf;int nkids =1 ; -int runlength =1 ; +intptr_t runlength =1 ;int totbefore;smp_init ();@@ -176,12 +177,12 @@ int main(int argc, char *argv[])if (argc >2 ) { runlength =strtoul (argv[2 ],NULL ,0 );if (runlength >MAX_RUN ) { -fprintf (stderr,"nkids = %d too large, max = %d\n" , +fprintf (stderr,"nkids = %" PRIdPTR" too large, max = %d\n" , runlength,MAX_RUN );usage (argv[0 ]); } } -printf ("%d %d " , nkids, runlength); +printf ("%d %" PRIdPTR, nkids, runlength);init_per_thread (results,0L );init_per_thread (failures,0L );@@ -189,7 +190,7 @@ int main(int argc, char *argv[]) goflag =1 ;for (i =0 ; i < nkids; i++) -create_thread (memblock_test, (void *)(long )runlength); +create_thread (memblock_test, (void *)runlength);sleep (1 ); goflag =0 ;CodeSamples/defer/gettimestampmp.c +1
-1@@ -29,7 +29,7 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) { -long mask = (long )mask_in; +intptr_t mask = (intptr_t )mask_in;while (curtimestamp <MAX_TIMESTAMPS ) {while ((curtimestamp &CURTIMESTAMP_MASK ) != mask)CodeSamples/intro/threadcreate.c +4
-3@@ -18,13 +18,14 @@* Copyright (c) 2006 Paul E. McKenney, IBM Corporation. */ +#include <inttypes.h> #include "../api.h" void *thread_test (void *arg) { -int myarg = (int )arg; +intptr_t myarg = (intptr_t )arg; -printf ("child thread %d: smp_thread_id() = %d\n" , +printf ("child thread %" PRIdPTR": smp_thread_id() = %d\n" , myarg,smp_thread_id ());return NULL ; }@@ -38,7 +39,7 @@ void usage(char *progname)int main (int argc,char *argv[]) { -int i; +intptr_t i;int nkids =1 ;smp_init ();Signature · 7 lines
2.7.4 -- To unsubscribe from this list: send the line "unsubscribe perfbook" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH 4/4 CodeSamples/defer: Add compiler barriers in gettimestampmp.c
In reply to Akira YokosawaFrom fd5fb9afb6b99b15370a9823b42fa2a92342b92a Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Sun, 28 May 2017 15:42:45 +0900
Subject: [RFC PATCH 4/4] CodeSamples/defer: Add compiler barriers in gettimestampmp.c
They ensure curtimestamp is read and written once in every iteration.
--- CodeSamples/defer/gettimestampmp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
CodeSamples/defer/gettimestampmp.c +2 -1
@@ -32,7 +32,7 @@ void *collect_timestamps(void *mask_in)intptr_t mask = (intptr_t )mask_in;while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) +while ((READ_ONCE (curtimestamp) &CURTIMESTAMP_MASK ) != mask)continue ;if (curtimestamp >=MAX_TIMESTAMPS )break ;
@@ -40,6 +40,7 @@ void *collect_timestamps(void *mask_in)/* Don't need memory barrier -- no other shared vars!!! */ ts[curtimestamp++] =get_timestamp (); +barrier (); }smp_mb ();return (NULL );
Signature · 1 line
2.7.4
Re: [RFC PATCH 4/4] CodeSamples/defer: Add compiler barriers in gettimestampmp.c
Quoted 9 lines · Akira Yokosawa
Quoted 1 line
From
fd5fb9afb6b99b15370a9823b42fa2a92342b92aMon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Sun, 28 May 2017 15:42:45 +0900
Subject: [RFC PATCH 4/4] CodeSamples/defer: Add compiler barriers ingettimestampmp.cThey ensure curtimestamp is read and written once in every iteration.
Signed-off-by Akira Yokosawa <[email protected]>
I was actually more or less OK with this one, but it does not apply cleanly without 3/4.
Nevertheless, given that it needs change anyway, would it be better to replace the ++ with a WRITE_ONCE and capture the value in the "while" expression?
Thanx, Paul
Quoted 29 lines
--- CodeSamples/defer/gettimestampmp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)CodeSamples/defer/gettimestampmp.c +2
-1@@ -32,7 +32,7 @@ void *collect_timestamps(void *mask_in)intptr_t mask = (intptr_t )mask_in;while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) +while ((READ_ONCE (curtimestamp) &CURTIMESTAMP_MASK ) != mask)continue ;if (curtimestamp >=MAX_TIMESTAMPS )break ;@@ -40,6 +40,7 @@ void *collect_timestamps(void *mask_in)/* Don't need memory barrier -- no other shared vars!!! */ ts[curtimestamp++] =get_timestamp (); +barrier (); }smp_mb ();return (NULL );Signature · 1 line
2.7.4
Quoted 13 lines · Akira Yokosawa
Quoted 1 line
From
fd5fb9afb6b99b15370a9823b42fa2a92342b92aMon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 06:52:40 +0900
Subject: [RFC PATCH 0/4] CodeSamples: Cleanups and fixesHi Paul,
While I was looking around CodeSamples, I encountered several warnings in build and an infinite loop in one of sample codes. Also, I found that
CodeSamples/api.hand CodeSamples/Makefile.arch can be removed from repository if their recipe are properly written in Makefiles.
Quoted 6 lines
Patch 1 adds rules to generate Makefile.arch and
api.hthat suit the architecture of you host. As I don't have ppc64 or arm host environment, I tested it only onx86_32andx86_64. I'd like to know if it works on ppc64 and arm.Patch 2 removes the redundant files.
I took the first two, and it is nice to just be able to type "make" in the CodeSamples directory! ;-)
Quoted 1 line
Patch 3 and 4 are fixes of warnings and infinite loops.
I have some concerns here, and will reply to the patches.
Thanx, Paul
Quoted 40 lines
Thoughts?
Thanks, Akira
Signature · 35 lines
Akira Yokosawa (4): CodeSamples: Add rule to generate Makefile.arch and api.h CodeSamples: Remove generated files from repository CodeSamples: Use 'intptr_t' to be compatible with 'void *' CodeSamples/defer: Add compiler barriers in gettimestampmp.c CodeSamples/.gitignore | 4 +- CodeSamples/Makefile | 18 + CodeSamples/Makefile.arch | 6 - CodeSamples/SMPdesign/Makefile | 3 + CodeSamples/SMPdesign/matmul.c | 13 +- CodeSamples/SMPdesign/smpalloc.c | 11 +- CodeSamples/advsync/Makefile | 3 + CodeSamples/api.h | 808 ------------------------- CodeSamples/count/Makefile | 3 + CodeSamples/datastruct/Issaquah/Makefile | 3 + CodeSamples/datastruct/Issaquah/existence_test | Bin 26359 -> 0 bytes CodeSamples/datastruct/hash/Makefile | 3 + CodeSamples/datastruct/log/Makefile | 3 + CodeSamples/datastruct/skiplist/Makefile | 3 + CodeSamples/defer/Makefile | 3 + CodeSamples/defer/gettimestampmp.c | 5 +- CodeSamples/depends.mk | 43 ++ CodeSamples/intro/Makefile | 3 + CodeSamples/intro/threadcreate.c | 7 +- CodeSamples/locking/Makefile | 3 + CodeSamples/toolsoftrade/Makefile | 3 + 21 files changed, 117 insertions(+), 831 deletions(-) delete mode 100644 CodeSamples/Makefile.arch delete mode 100644 CodeSamples/api.h delete mode 100755 CodeSamples/datastruct/Issaquah/existence_test create mode 100644 CodeSamples/depends.mk -- 2.7.4
2017/05/30 9:02、Paul E. McKenney <[email protected]> のメッセージ:
Quoted 19 lines · Akira Yokosawa
Quoted 18 lines
Quoted 1 line
From
fd5fb9afb6b99b15370a9823b42fa2a92342b92aMon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 06:52:40 +0900
Subject: [RFC PATCH 0/4] CodeSamples: Cleanups and fixesHi Paul,
While I was looking around CodeSamples, I encountered several warnings in build and an infinite loop in one of sample codes. Also, I found that
CodeSamples/api.hand CodeSamples/Makefile.arch can be removed from repository if their recipe are properly written in Makefiles.Patch 1 adds rules to generate Makefile.arch and
api.hthat suit the architecture of you host. As I don't have ppc64 or arm host environment, I tested it only onx86_32andx86_64. I'd like to know if it works on ppc64 and arm.
Quoted 4 lines
Quoted 1 line
Patch 2 removes the redundant files.
I took the first two, and it is nice to just be able to type "make" in the CodeSamples directory! ;-)
Does this work on ppc64 and arm (whatever arm
platform you have access to)?
Quoted 5 lines
Quoted 2 lines
Patch 3 and 4 are fixes of warnings and infinite loops.
I have some concerns here, and will reply to the patches.
I see your points. I'll respin.
Thanks, Akira
(from mobile, might be QP encoded)
Quoted 43 lines
Thanx, Paul
Quoted 40 lines
Thoughts?
Thanks, Akira
Signature · 35 lines
Akira Yokosawa (4): CodeSamples: Add rule to generate Makefile.arch and api.h CodeSamples: Remove generated files from repository CodeSamples: Use 'intptr_t' to be compatible with 'void *' CodeSamples/defer: Add compiler barriers in gettimestampmp.c CodeSamples/.gitignore | 4 +- CodeSamples/Makefile | 18 + CodeSamples/Makefile.arch | 6 - CodeSamples/SMPdesign/Makefile | 3 + CodeSamples/SMPdesign/matmul.c | 13 +- CodeSamples/SMPdesign/smpalloc.c | 11 +- CodeSamples/advsync/Makefile | 3 + CodeSamples/api.h | 808 ------------------------- CodeSamples/count/Makefile | 3 + CodeSamples/datastruct/Issaquah/Makefile | 3 + CodeSamples/datastruct/Issaquah/existence_test | Bin 26359 -> 0 bytes CodeSamples/datastruct/hash/Makefile | 3 + CodeSamples/datastruct/log/Makefile | 3 + CodeSamples/datastruct/skiplist/Makefile | 3 + CodeSamples/defer/Makefile | 3 + CodeSamples/defer/gettimestampmp.c | 5 +- CodeSamples/depends.mk | 43 ++ CodeSamples/intro/Makefile | 3 + CodeSamples/intro/threadcreate.c | 7 +- CodeSamples/locking/Makefile | 3 + CodeSamples/toolsoftrade/Makefile | 3 + 21 files changed, 117 insertions(+), 831 deletions(-) delete mode 100644 CodeSamples/Makefile.arch delete mode 100644 CodeSamples/api.h delete mode 100755 CodeSamples/datastruct/Issaquah/existence_test create mode 100644 CodeSamples/depends.mk -- 2.7.4
v2 cover CodeSamples: Cleanups and fixes
In reply to Akira YokosawaFrom 489b5e3bdeba2f9b733dbe3d85390368dd159174 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:44:52 +0900
Subject: [RFC PATCH v2 0/2] CodeSamples: Cleanups and fixes
Hi Paul,
This is the respin of the latter two patches of v1. I'm keeping RFC because of some questions.
"long" -> "intptr_t" changes in Patch 1 have no effect on a platform where "long" and "intptr_t" have the same width, but I think they are good in portability POV.
WRITE_ONCE() in Patch 2 is placed under the assignment to the array because I could not translate post increment in any other way. Does the WRITE_ONCE() ensure the outer "while" capture the value?
Thanks, Akira
Signature · 12 lines
Akira Yokosawa (2): CodeSamples: Use 'intptr_t' to be compatible with 'void *' CodeSamples/defer: Add compiler barriers in gettimestampmp.c CodeSamples/SMPdesign/matmul.c | 4 ++-- CodeSamples/SMPdesign/smpalloc.c | 4 ++-- CodeSamples/defer/gettimestampmp.c | 7 ++++--- CodeSamples/intro/threadcreate.c | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) -- 2.7.4
RFC PATCH v2 1/2 CodeSamples: Use 'intptr_t' to be compatible with 'void *'
From 177ee2891184f0a97b66d748763dbc7af75033ff Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:21:41 +0900
Subject: [RFC PATCH v2 1/2] CodeSamples: Use 'intptr_t' to be compatible with 'void *'
On x86_64, casting between "int" and "void *" in threadcreate.c causes GCC to emit warnings such as:
warning: cast from pointer to integer of different size
warning: cast from integer to pointer of different size
Let's adopt C99 way of writing portable code.
Also do the same changes where appropriate. (Other than threadcreate.c, no warnings were observed on x86_64.)
[Revised according to Paul's suggestion to keep intptr_t usage
confined.]
--- CodeSamples/SMPdesign/matmul.c | 4 ++-- CodeSamples/SMPdesign/smpalloc.c | 4 ++-- CodeSamples/defer/gettimestampmp.c | 2 +- CodeSamples/intro/threadcreate.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-)
CodeSamples/SMPdesign/matmul.c +2 -2
@@ -38,7 +38,7 @@ atomic_t nstarted;void *matmul_thread (void *me_in) { -long me = (long )me_in; +long me = (intptr_t )me_in;int i, j, k;atomic_inc (&nstarted);
@@ -87,7 +87,7 @@ int main(int argc, char *argv[]) goflag =GOFLAG_INIT ; startcreatetime =get_microseconds ();for (i =0 ; i < nthread; i++) -create_thread (matmul_thread, (void *)(long )i); +create_thread (matmul_thread, (void *)(intptr_t )i);while (atomic_read (&nstarted) != nthread)barrier (); starttime =get_microseconds ();
CodeSamples/SMPdesign/smpalloc.c +2 -2
@@ -123,7 +123,7 @@ void *memblock_test(void *arg)long cnt =0 ;long cntfail =0 ;int i; -int runlength = (int )(long )arg; +int runlength = (intptr_t )arg;struct memblock *p[MAX_RUN ];if (runlength >MAX_RUN )
@@ -189,7 +189,7 @@ int main(int argc, char *argv[]) goflag =1 ;for (i =0 ; i < nkids; i++) -create_thread (memblock_test, (void *)(long )runlength); +create_thread (memblock_test, (void *)(intptr_t )runlength);sleep (1 ); goflag =0 ;
CodeSamples/defer/gettimestampmp.c +1 -1
@@ -29,7 +29,7 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) { -long mask = (long )mask_in; +long mask = (intptr_t )mask_in;while (curtimestamp <MAX_TIMESTAMPS ) {while ((curtimestamp &CURTIMESTAMP_MASK ) != mask)
CodeSamples/intro/threadcreate.c +2 -2
@@ -22,7 +22,7 @@void *thread_test (void *arg) { -int myarg = (int )arg; +int myarg = (intptr_t )arg;printf ("child thread %d: smp_thread_id() = %d\n" , myarg,smp_thread_id ());
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])printf ("Parent thread spawning %d threads.\n" , nkids);for (i =0 ; i < nkids; i++) -create_thread (thread_test, (void *)i); +create_thread (thread_test, (void *)(intptr_t )i);wait_all_threads ();
Signature · 1 line
2.7.4
RFC PATCH v2 2/2 CodeSamples/defer: Add compiler barriers in gettimestampmp.c
In reply to Akira YokosawaFrom 489b5e3bdeba2f9b733dbe3d85390368dd159174 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:40:04 +0900
Subject: [RFC PATCH v2 2/2] CodeSamples/defer: Add compiler barriers in gettimestampmp.c
They ensure curtimestamp is read and written once in every iteration.
[Revised according to Paul's suggestion to use WRITE_ONCE()]
--- CodeSamples/defer/gettimestampmp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
CodeSamples/defer/gettimestampmp.c +3 -2
@@ -32,14 +32,15 @@ void *collect_timestamps(void *mask_in)long mask = (intptr_t )mask_in;while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) +while ((READ_ONCE (curtimestamp) &CURTIMESTAMP_MASK ) != mask)continue ;if (curtimestamp >=MAX_TIMESTAMPS )break ;/* Don't need memory barrier -- no other shared vars!!! */ - ts[curtimestamp++] =get_timestamp (); + ts[curtimestamp] =get_timestamp (); +WRITE_ONCE (curtimestamp, curtimestamp +1 ); }smp_mb ();return (NULL );
Signature · 1 line
2.7.4
Quoted 10 lines · Akira Yokosawa
Quoted 1 line
From
489b5e3bdeba2f9b733dbe3d85390368dd159174Mon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:44:52 +0900
Subject: [RFC PATCH v2 0/2] CodeSamples: Cleanups and fixesHi Paul,
This is the respin of the latter two patches of v1. I'm keeping RFC because of some questions.
Quoted 7 lines
"long" -> "
intptr_t" changes in Patch 1 have no effect on a platform where "long" and "intptr_t" have the same width, but I think they are good in portability POV.
WRITE_ONCE()in Patch 2 is placed under the assignment to the array because I could not translate post increment in any other way. Does theWRITE_ONCE()ensure the outer "while" capture the value?
Wow, that loop is old code!!! My current compiler creates an infinite
loop for it, so yes, there is more required. Plus there are confusing
and redundant comparisons, so that it is not entirely clear to me that the loop is guaranteed to terminate properly.
So I took both patches, but rewrote the loop in the second patch as shown below.
If you are OK with this rewrite, I will push them.
Thanx, Paul
------------------------------------------------------------------------
commit 8a54d9aeeeefa1909db062dc893705ff8fefd702
Author: Akira Yokosawa <[email protected]> Date: Tue May 30 20:40:04 2017 +0900
CodeSamples/defer: Rework loop in gettimestampmp.c
Add READ_ONCE() and WRITE_ONCE() ensure curtimestamp is read and written once in every iteration. The READ_ONCE() is not optional, as modern compilers can (and do) emit an infinite loop for the earlier code.
CodeSamples/defer/gettimestampmp.c +8 -5
@@ -30,16 +30,19 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) {long mask = (intptr_t )mask_in; +long cts; -while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) -continue ; -if (curtimestamp >=MAX_TIMESTAMPS ) +for (;;) { + cts =READ_ONCE (curtimestamp); +if (cts >=MAX_TIMESTAMPS )break ; +if ((cts &CURTIMESTAMP_MASK ) != mask) +continue ;/* Don't need memory barrier -- no other shared vars!!! */ - ts[curtimestamp++] =get_timestamp (); + ts[cts] =get_timestamp (); +WRITE_ONCE (curtimestamp, cts +1 ); }smp_mb ();return (NULL );
Quoted 15 lines · Paul E. McKenney
Quoted 14 lines · Akira Yokosawa
Quoted 1 line
From
489b5e3bdeba2f9b733dbe3d85390368dd159174Mon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:44:52 +0900
Subject: [RFC PATCH v2 0/2] CodeSamples: Cleanups and fixesHi Paul,
This is the respin of the latter two patches of v1. I'm keeping RFC because of some questions.
"long" -> "
intptr_t" changes in Patch 1 have no effect on a platform where "long" and "intptr_t" have the same width, but I think they are good in portability POV.
Quoted 6 lines
Quoted 3 lines
WRITE_ONCE()in Patch 2 is placed under the assignment to the array because I could not translate post increment in any other way. Does theWRITE_ONCE()ensure the outer "while" capture the value?Wow, that loop is old code!!! My current compiler creates an infinite loop for it, so yes, there is more required.
You mean on GCC for ppc64?
Quoted 8 lines
Plus there are confusing
and redundant comparisons, so that it is not entirely clear to me that the loop is guaranteed to terminate properlySo I took both patches, but rewrote the loop in the second patch as shown below.
If you are OK with this rewrite, I will push them.
I'm OK with this, but it is a whole rewrite of the code, so
looks appropriate in this case.
It's up to you which tag to use.
Thanks, Akira
Quoted 50 lines
Thanx, Paul
------------------------------------------------------------------------
commit
8a54d9aeeeefa1909db062dc893705ff8fefd702Author: Akira Yokosawa <[email protected]> Date: Tue May 30 20:40:04 2017 +0900CodeSamples/defer: Rework loop in
gettimestampmp.cAdd
READ_ONCE()andWRITE_ONCE()ensure curtimestamp is read and written once in every iteration. TheREAD_ONCE()is not optional, as modern compilers can (and do) emit an infinite loop for the earlier code.Signed-off-by Akira Yokosawa <[email protected]>[ paulmck: Rework loop to eliminate redundant fetches and comparisons. ]Signed-off-by Paul E. McKenney <[email protected]>CodeSamples/defer/gettimestampmp.c +8
-5@@ -30,16 +30,19 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) {long mask = (intptr_t )mask_in; +long cts; -while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) -continue ; -if (curtimestamp >=MAX_TIMESTAMPS ) +for (;;) { + cts =READ_ONCE (curtimestamp); +if (cts >=MAX_TIMESTAMPS )break ; +if ((cts &CURTIMESTAMP_MASK ) != mask) +continue ;/* Don't need memory barrier -- no other shared vars!!! */ - ts[curtimestamp++] =get_timestamp (); + ts[cts] =get_timestamp (); +WRITE_ONCE (curtimestamp, cts +1 ); }smp_mb ();return (NULL );
Quoted 16 lines · Akira Yokosawa
Quoted 15 lines · Paul E. McKenney
Quoted 14 lines · Akira Yokosawa
Quoted 1 line
From
489b5e3bdeba2f9b733dbe3d85390368dd159174Mon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:44:52 +0900
Subject: [RFC PATCH v2 0/2] CodeSamples: Cleanups and fixesHi Paul,
This is the respin of the latter two patches of v1. I'm keeping RFC because of some questions.
"long" -> "
intptr_t" changes in Patch 1 have no effect on a platform where "long" and "intptr_t" have the same width, but I think they are good in portability POV.
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
WRITE_ONCE()in Patch 2 is placed under the assignment to the array because I could not translate post increment in any other way. Does theWRITE_ONCE()ensure the outer "while" capture the value?Wow, that loop is old code!!! My current compiler creates an infinite loop for it, so yes, there is more required.
You mean on GCC for ppc64?
No, x86 GCC on the code before you changed it. ;-)
Which reminds me... How about if I get you direct access to some ppc64 machines? If you are at all interested, please let me know and also please sign up here:
http://osuosl.org/services/powerdev/request_hosting/
I believe that there is also similar access to ARM systems, so please let me know if you are interested.
Quoted 7 lines
Quoted 7 lines
Plus there are confusing
and redundant comparisons, so that it is not entirely clear to me that the loop is guaranteed to terminate properlySo I took both patches, but rewrote the loop in the second patch as shown below.
Quoted 8 lines
Quoted 1 line
If you are OK with this rewrite, I will push them.
I'm OK with this, but it is a whole rewrite of the code, so
Reported-by Akira Yokosawa <[email protected]>looks appropriate in this case.
It's up to you which tag to use.
I will stick with what I have. Lazy and all that. ;-)
Thanx, Paul
Quoted 53 lines
Thanks, Akira
Quoted 50 lines
Thanx, Paul
------------------------------------------------------------------------
commit
8a54d9aeeeefa1909db062dc893705ff8fefd702Author: Akira Yokosawa <[email protected]> Date: Tue May 30 20:40:04 2017 +0900CodeSamples/defer: Rework loop in
gettimestampmp.cAdd
READ_ONCE()andWRITE_ONCE()ensure curtimestamp is read and written once in every iteration. TheREAD_ONCE()is not optional, as modern compilers can (and do) emit an infinite loop for the earlier code.Signed-off-by Akira Yokosawa <[email protected]>[ paulmck: Rework loop to eliminate redundant fetches and comparisons. ]Signed-off-by Paul E. McKenney <[email protected]>CodeSamples/defer/gettimestampmp.c +8
-5@@ -30,16 +30,19 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) {long mask = (intptr_t )mask_in; +long cts; -while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) -continue ; -if (curtimestamp >=MAX_TIMESTAMPS ) +for (;;) { + cts =READ_ONCE (curtimestamp); +if (cts >=MAX_TIMESTAMPS )break ; +if ((cts &CURTIMESTAMP_MASK ) != mask) +continue ;/* Don't need memory barrier -- no other shared vars!!! */ - ts[curtimestamp++] =get_timestamp (); + ts[cts] =get_timestamp (); +WRITE_ONCE (curtimestamp, cts +1 ); }smp_mb ();return (NULL );
Hi Paul and Akira,
The code looks clear and easy to understand now :-).
While checking the patch, I have one question. Are there any technical reason that we prefer for(;;) instead of while(1) in CodeSamples? Just out of curiosity :-)
Thanks
Quoted 81 lines · Paul E. McKenney
Quoted 10 lines · Akira Yokosawa
Quoted 1 line
From
489b5e3bdeba2f9b733dbe3d85390368dd159174Mon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:44:52 +0900
Subject: [RFC PATCH v2 0/2] CodeSamples: Cleanups and fixesHi Paul,
This is the respin of the latter two patches of v1. I'm keeping RFC because of some questions.
Quoted 7 lines
"long" -> "
intptr_t" changes in Patch 1 have no effect on a platform where "long" and "intptr_t" have the same width, but I think they are good in portability POV.
WRITE_ONCE()in Patch 2 is placed under the assignment to the array because I could not translate post increment in any other way. Does theWRITE_ONCE()ensure the outer "while" capture the value?Wow, that loop is old code!!! My current compiler creates an infinite
loop for it, so yes, there is more required. Plus there are confusing
and redundant comparisons, so that it is not entirely clear to me that the loop is guaranteed to terminate properly.So I took both patches, but rewrote the loop in the second patch as shown below.
If you are OK with this rewrite, I will push them.
Thanx, Paul
------------------------------------------------------------------------
commit
8a54d9aeeeefa1909db062dc893705ff8fefd702Author: Akira Yokosawa <[email protected]> Date: Tue May 30 20:40:04 2017 +0900CodeSamples/defer: Rework loop in
gettimestampmp.cAdd
READ_ONCE()andWRITE_ONCE()ensure curtimestamp is read and written once in every iteration. TheREAD_ONCE()is not optional, as modern compilers can (and do) emit an infinite loop for the earlier code.Signed-off-by Akira Yokosawa <[email protected]>[ paulmck: Rework loop to eliminate redundant fetches and comparisons. ]Signed-off-by Paul E. McKenney <[email protected]>CodeSamples/defer/gettimestampmp.c +8
-6@@ -30,16 +30,19 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) {long mask = (intptr_t )mask_in; +long cts; -while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) -continue ; -if (curtimestamp >=MAX_TIMESTAMPS ) +for (;;) { + cts =READ_ONCE (curtimestamp); +if (cts >=MAX_TIMESTAMPS )break ; +if ((cts &CURTIMESTAMP_MASK ) != mask) +continue ;/* Don't need memory barrier -- no other shared vars!!! */ - ts[curtimestamp++] =get_timestamp (); + ts[cts] =get_timestamp (); +WRITE_ONCE (curtimestamp, cts +1 ); }smp_mb ();return (NULL ); --To unsubscribe from this list: send the line "unsubscribe perfbook" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 3 lines · Junchang Wang
Hi Paul and Akira,
The code looks clear and easy to understand now :-).
Glad you like it! I am sure that other code in there could use similar help.
Quoted 3 lines
While checking the patch, I have one question. Are there any technical reason that we prefer for(;;) instead of while(1) in CodeSamples? Just out of curiosity :-)
No. Just thirty-five years of habit plus the preferences of the Linux kernel community. And the latter are probably because "while (1)" has one more character than does "for (;;)". ;-)
Thanx, Paul
Quoted 86 lines
Thanks
Quoted 81 lines · Paul E. McKenney
Quoted 10 lines · Akira Yokosawa
Quoted 1 line
From
489b5e3bdeba2f9b733dbe3d85390368dd159174Mon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:44:52 +0900
Subject: [RFC PATCH v2 0/2] CodeSamples: Cleanups and fixesHi Paul,
This is the respin of the latter two patches of v1. I'm keeping RFC because of some questions.
Quoted 7 lines
"long" -> "
intptr_t" changes in Patch 1 have no effect on a platform where "long" and "intptr_t" have the same width, but I think they are good in portability POV.
WRITE_ONCE()in Patch 2 is placed under the assignment to the array because I could not translate post increment in any other way. Does theWRITE_ONCE()ensure the outer "while" capture the value?Wow, that loop is old code!!! My current compiler creates an infinite
loop for it, so yes, there is more required. Plus there are confusing
and redundant comparisons, so that it is not entirely clear to me that the loop is guaranteed to terminate properly.So I took both patches, but rewrote the loop in the second patch as shown below.
If you are OK with this rewrite, I will push them.
Thanx, Paul
------------------------------------------------------------------------
commit
8a54d9aeeeefa1909db062dc893705ff8fefd702Author: Akira Yokosawa <[email protected]> Date: Tue May 30 20:40:04 2017 +0900CodeSamples/defer: Rework loop in
gettimestampmp.cAdd
READ_ONCE()andWRITE_ONCE()ensure curtimestamp is read and written once in every iteration. TheREAD_ONCE()is not optional, as modern compilers can (and do) emit an infinite loop for the earlier code.Signed-off-by Akira Yokosawa <[email protected]>[ paulmck: Rework loop to eliminate redundant fetches and comparisons. ]Signed-off-by Paul E. McKenney <[email protected]>CodeSamples/defer/gettimestampmp.c +8
-6@@ -30,16 +30,19 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) {long mask = (intptr_t )mask_in; +long cts; -while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) -continue ; -if (curtimestamp >=MAX_TIMESTAMPS ) +for (;;) { + cts =READ_ONCE (curtimestamp); +if (cts >=MAX_TIMESTAMPS )break ; +if ((cts &CURTIMESTAMP_MASK ) != mask) +continue ;/* Don't need memory barrier -- no other shared vars!!! */ - ts[curtimestamp++] =get_timestamp (); + ts[cts] =get_timestamp (); +WRITE_ONCE (curtimestamp, cts +1 ); }smp_mb ();return (NULL ); --To unsubscribe from this list: send the line "unsubscribe perfbook" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 7 lines · Paul E. McKenney
Quoted 3 lines · Junchang Wang
Hi Paul and Akira,
The code looks clear and easy to understand now :-).
Glad you like it! I am sure that other code in there could use similar help.
I would be very happy to gradually go through these sections this summer. :-)
Quoted 9 lines
Quoted 4 lines
While checking the patch, I have one question. Are there any technical reason that we prefer for(;;) instead of while(1) in CodeSamples? Just out of curiosity :-)
No. Just thirty-five years of habit plus the preferences of the Linux kernel community. And the latter are probably because "while (1)" has one more character than does "for (;;)". ;-)
Got you :-) Thanks.
--Jason
Quoted 89 lines
Thanx, Paul
Quoted 86 lines
Thanks
Quoted 81 lines · Paul E. McKenney
Quoted 10 lines · Akira Yokosawa
Quoted 1 line
From
489b5e3bdeba2f9b733dbe3d85390368dd159174Mon Sep 17 00:00:00 2001From: Akira Yokosawa <[email protected]>
Date: Tue, 30 May 2017 20:44:52 +0900
Subject: [RFC PATCH v2 0/2] CodeSamples: Cleanups and fixesHi Paul,
This is the respin of the latter two patches of v1. I'm keeping RFC because of some questions.
Quoted 7 lines
"long" -> "
intptr_t" changes in Patch 1 have no effect on a platform where "long" and "intptr_t" have the same width, but I think they are good in portability POV.
WRITE_ONCE()in Patch 2 is placed under the assignment to the array because I could not translate post increment in any other way. Does theWRITE_ONCE()ensure the outer "while" capture the value?Wow, that loop is old code!!! My current compiler creates an infinite
loop for it, so yes, there is more required. Plus there are confusing
and redundant comparisons, so that it is not entirely clear to me that the loop is guaranteed to terminate properly.So I took both patches, but rewrote the loop in the second patch as shown below.
If you are OK with this rewrite, I will push them.
Thanx, Paul
------------------------------------------------------------------------
commit
8a54d9aeeeefa1909db062dc893705ff8fefd702Author: Akira Yokosawa <[email protected]> Date: Tue May 30 20:40:04 2017 +0900CodeSamples/defer: Rework loop in
gettimestampmp.cAdd
READ_ONCE()andWRITE_ONCE()ensure curtimestamp is read and written once in every iteration. TheREAD_ONCE()is not optional, as modern compilers can (and do) emit an infinite loop for the earlier code.Signed-off-by Akira Yokosawa <[email protected]>[ paulmck: Rework loop to eliminate redundant fetches and comparisons. ]Signed-off-by Paul E. McKenney <[email protected]>CodeSamples/defer/gettimestampmp.c +8
-6@@ -30,16 +30,19 @@ long curtimestamp = 0;void *collect_timestamps (void *mask_in) {long mask = (intptr_t )mask_in; +long cts; -while (curtimestamp <MAX_TIMESTAMPS ) { -while ((curtimestamp &CURTIMESTAMP_MASK ) != mask) -continue ; -if (curtimestamp >=MAX_TIMESTAMPS ) +for (;;) { + cts =READ_ONCE (curtimestamp); +if (cts >=MAX_TIMESTAMPS )break ; +if ((cts &CURTIMESTAMP_MASK ) != mask) +continue ;/* Don't need memory barrier -- no other shared vars!!! */ - ts[curtimestamp++] =get_timestamp (); + ts[cts] =get_timestamp (); +WRITE_ONCE (curtimestamp, cts +1 ); }smp_mb ();return (NULL ); --To unsubscribe from this list: send the line "unsubscribe perfbook" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html