C11 atomic implementation
C11 specifies a number of language features for atomic support. Essentially, it implements the C++ template library with language features, and enhances them to include floating point and complex support for basic arithmetic operations. Please consult the C11 standard for all the nitty gritty details.
How It Oughta Work
The basic approach is
As far as the middle and back ends are concerned, the 'atomic type' flag is merely a mechanism which is used to map a variable to one of the 5 basic builtin types, if the size matches OK. The atomic patterns for __atomic operations are 'guaranteed' to work on types with that alignment and size. This sint much of an issue for most targets, sinze for instance an SImode type and atomicSImode are identical. If a target had different alignment requirements, then this type difference is important because the lock free routine may not work on the SImode type. This is orthogonal to the C11 changes, but are included as future ABI completeness.
The front ends set the atomic bit, and when in C11 mode only, any variable reference with the flag needs to be expanded to an atomic operation. If not in C11 mode, then the references should just be left as seen. This allows non-C11 code to make sure variables have proper atomic alignments without triggering the C11 expansion rules.
Current Status
A set of patches have been created and applied to the branch C11-atomic which provide most of the infrastructural changes required. This consists of
- middle/back end target support for native atomic operations which require non standard alignments on their atomic memory locations. (this is not C11 specific, but is included in the patch)
The recognition of the _Atomic keyword, as well an an equivalent extension __attribute__((atomic)). The attribute is provided so that the c++ template library may add the attribute to all their atomic variables, resulting in standardization across C++11 and C11 atomic variables.
- basic support for expanding variable references into assignment or load operations. This is incomplete as further parser work is required to find all the right places where loads need to be issued.
- an initial cstdatomic.h file is provided, although it is untested as yet.
- With the exception of the change to the libstdc++-v3 in p4.patch, everything compiles and works fine. The original patch sets from the mailing list had extra stuff in the front end files which treated 'atomic' just like volatile, setting volatile bits and everything. I do not think this is the correct approach, and atomic the atomic storage attribute in the middle/back end isnt actually volatile.. its the uses of it in atomic operations which is. The correct approach would be to teach the front ends that the atomic qualifier is compatible with a 'volatile *'. Ie, the compilation failure in libstdc++ rihght now is a result of a pedantic warnign that "atomic int *" is not compatable with 'volatile void *' of the atomic builtins. Any attempts I make with my limited front-end-fu will no doubt be wrong (as my first attempts were), so I leave it for proper investigation.
- Short of that one compilation caveat, when "tircked" to allow it to pass, all the testsuite runs are clean...
I do not plan to complete this work right now, and will consider picking it up again in 2014 if no one else gets to it first. Someone with front end experience would proabbly be able to do this much much quicker.
What Needs Doing
- Fix the atomic qualifier interfering with non-atomic casts.
- The current mechanism of expanding atomic references in the parser is insufficent. It works for simple cases, but falls down on any kind fo RHS complexity. It needs to be expanded such that atomic variables are carried around as lvalues until they are either committed to as lvalues, or converted to an rvalue. At this point, it needs to be determined whether this is an atomic assignment,load, or artihmetic op, and the approriate routine called to do the expansion. This is effectively all front end parser work.
- warnings and errors need to be issued when language rulers are violated. This requires going through identifying the various locations where an atomic variable is used inappropriately.
- I don't know if stdatomic.h is suppose to be in gcc/ginclude, or if there is something else that needs to be done besides just placing it there. It also needs testing.
testcases are needed, one could start by copying and converting all the __atomic builtin testcases in testsuite/gcc.dg/atomic* to the C11 form, and extending it to include the float and complex operations.
patches
There were a couple of threads where Joseph Myers reviewed these patches. I have adjusted them based on his comments, with a couple of un-addressed exceptions which I will list afterwards. The threads are found at:
Previous state plus I made some adjustments based on JSM's followup, but none of his broader comments, just typeos and simple things were addressed.
The patches which have been applied to the C11-atomic branch are as follows:
C11-atomic |
rev 202891 |
New Branch Sept 25 2013 |
||
rev 202916 |
Alignment target hook |
|||
rev 202917 |
Add ME/BE atomic type support |
|||
rev 202919 |
Add _Atomic and __attribute__((atomic)) |
|||
rev 202920 |
Add __attribute__((atomic)) to C++ atomic templates. Add tests. |
|||
rev 202959 |
Add functionality to expand atomic variable lval and rvals into calls. |
|||
rev 202960 |
Make typeof() an atomic variable return the main variant. |
|||
rev 202961 |
Add stdatomic.h header file. |
|||
Also provided here is an un-applied patch from the original patch set. It changes all the built in atomic functions to take 'volatile atomic *' as the first parameter rather than the current "volatile *". This solves the compilation problem in libstdc++-v3, but upon relfection I dont think the type should be changed. It possible to revert this decision again by adding this patch, and dealing with what happens when the types arent atomic. The cast from type to the atomic version of that type should be allowed as long as size and alignment match. Otherwise a warning should be issued. When we get around to changing the size of an atoic object someday (if ever), we'll have to decide what to do when the size of the non atomic DOESNT match the type being passed in.. we may need to issue wrapper code adn temps to make it work for existing code... anyway, can of worms to open later.
I supplied the patch her e so it doesn't get lost.
not applied |
Change __atomic first params to 'volatile atomic *'. |
|||
Any questions, please contact me Andrew MacLeod amacleod@redhat.com