From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/6475 Path: news.gmane.org!not-for-mail From: Jens Gustedt Newsgroups: gmane.linux.lib.musl.general Subject: Re: [PATCH] Add stdatomic.h for clang>=3.1 and gcc>=4.1 Date: Sun, 09 Nov 2014 18:11:57 +0100 Message-ID: <1415553117.2457.1250.camel@eris.loria.fr> References: <386bdfe0.dNq.dMV.22.ce88IE@mailjet.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/signed; micalg="pgp-sha1"; protocol="application/pgp-signature"; boundary="=-9i3qSusCa5uYL7A7SndA" X-Trace: ger.gmane.org 1415553139 4843 80.91.229.3 (9 Nov 2014 17:12:19 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 9 Nov 2014 17:12:19 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-6488-gllmg-musl=m.gmane.org@lists.openwall.com Sun Nov 09 18:12:12 2014 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1XnW27-0003xx-Pr for gllmg-musl@m.gmane.org; Sun, 09 Nov 2014 18:12:11 +0100 Original-Received: (qmail 4026 invoked by uid 550); 9 Nov 2014 17:12:10 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 4012 invoked from network); 9 Nov 2014 17:12:09 -0000 X-IronPort-AV: E=Sophos;i="5.07,346,1413237600"; d="scan'";a="105841460" In-Reply-To: <386bdfe0.dNq.dMV.22.ce88IE@mailjet.com> Face: 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 X-Mailer: Evolution 3.4.4-3 Xref: news.gmane.org gmane.linux.lib.musl.general:6475 Archived-At: --=-9i3qSusCa5uYL7A7SndA Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: quoted-printable Hello, interesting idea! I am not at all sure how far we should go with such a support, because if the compiler is claiming to be C11 (which much of them do with -std=3Dc11) and we don't provide incomplete atomics support, the application programmer will have difficulties dealing with the cases and have to do feature tests which are not trivial at all. The __STD_NO_ATOMICS__ macro is the only feature test macro that is foreseen by the standard and it leaves no choice: either you have *all* atomics support (_Atomic qualifier, _Atomic type specifier, operations on atomic types, atomic type generic functions) or *none*. I would propose some rules that should be respected by such a header file: - all syntax that this supports should be correct C11 syntax, but it may be a restricted version, that is not all C11 might be supported. In such a case the compilation should fail. - all C11 syntax that was not in C99 and that compiles with this header should compile to correct executables with provable atomic sematic as defined by C11 - all produced object code must be ABI compatible with the newer versions of the same compiler Your file doesn't provide support for atomics for the non-basic types, but which the C11 standard requests? How to deal with them? Do you plan to implement libatomic.a ? I think that would be a good idea, because the gcc implementation is bogus and relies on pthread_mutex_t instead of atomic_flag. Would we'd have to mimic the different interfaces on a per compiler base? Generally, at least for a start, I think it would be a good idea to separate the support for different compilers, and in particular don't claim support for a compiler which you didn't even test :) Having something for earlier versions of clang would already be a good start. Some more comments in the text, but I didn't do a complete review, yet, less did I do tests. Jens Am Sonntag, den 09.11.2014, 13:53 +0100 schrieb Joakim Sindholt: > GCC and Clang ship their own stdatomic.h headers but not for all the > versions mentioned above. They ship many other standard headers too that > musl also ships (stdbool/def/int/...). >=20 > In the end musl should be a complete libc with all standard headers and > this is one of them. It is up to the individual programmer to ensure > that his or her compiler is properly supported by for example checking > __STD_NO_ATOMICS__ and __STDC_VERSION__ >=3D 201112L. As said above checking these would have to give the assertion that the platform supports all atomics, library and compiler, which we shouldn't give lighthearted > For clang the support is complete for versions >=3D 3.1. GCC added the > __atomic functions in 4.7 but not _Atomic until 4.9 so from 4.1 it will > work correctly so long as you don't use VLAs together with things like > the ++ operator in arguments and is subject to the same limitations as > 4.7. I don't follow here. Could you explain a bit more? I have the impression that your patch can't work at all with gcc, since it is missing _Atomic and you need the typedef's with _Atomic in them. Then, what is the connection with VLA? and the ++ operator? > From 4.7 it will work as inteded so long as you only use the > function-like-macros and from 4.9 it will have full support. I don't think the functionlike macros will work for arbitrary types > This patch has only been tested with clang. The __typeof__ magic is to > avoid changes to alltypes. It should be changed before committing this > to musl. This patch is only for people who want to test themselves. I would be easier to read if you would provide the changes in alltypes, as well. Since we are using git, it should not be a problem to keep all these changes to different files together in one patch. > This work is released to the Public Domain. > --- > include/stdatomic.h | 287 ++++++++++++++++++++++++++++++++++++++++++++++= ++++++ > 1 file changed, 287 insertions(+) > create mode 100644 include/stdatomic.h >=20 > diff --git a/include/stdatomic.h b/include/stdatomic.h > new file mode 100644 > index 0000000..3a61e47 > --- /dev/null > +++ b/include/stdatomic.h > @@ -0,0 +1,287 @@ > +#ifndef _STDATOMIC_H > +#define _STDATOMIC_H > + > +#ifndef __has_extension > +#define __has_extension(x) 0 > +#define __musl_has_extension 1 > +#endif > + > +#if defined(__clang__) && __has_extension(c_atomic) > + > +#define kill_dependency(y) (y) > + > +#define ATOMIC_VAR_INIT(value) (value) > +#define atomic_init(obj, value) __c11_atomic_init(obj, value) > + > +#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(obj)) > +#define __atomic_type_is_lock_free(type) \ > + __c11_atomic_is_lock_free(sizeof(type)) > + > +#define atomic_thread_fence(order) __c11_atomic_thread_fence(order) > +#define atomic_signal_fence(order) __c11_atomic_signal_fence(order) > + > +#define atomic_store_explicit(object, desired, order) \ > + __c11_atomic_store(object, desired, order) > +#define atomic_load_explicit(object, order) \ > + __c11_atomic_load(object, order) > + > +#define atomic_exchange_explicit(object, value, order) \ > + __c11_atomic_exchange(object, value, order) > +#define atomic_compare_exchange_strong_explicit(object, expected, desire= d, \ > + success, failure) \ > + __c11_atomic_compare_exchange_strong(object, expected, desired, \ > + success, failure) > +#define atomic_compare_exchange_weak_explicit(object, expected, desired,= \ > + success, failure) \ > + __c11_atomic_compare_exchange_weak(object, expected, desired, \ > + success, failure) > + > +#define atomic_fetch_add_explicit(object, operand, order) \ > + __c11_atomic_fetch_add(object, operand, order) > +#define atomic_fetch_sub_explicit(object, operand, order) \ > + __c11_atomic_fetch_sub(object, operand, order) > +#define atomic_fetch_or_explicit(object, operand, order) \ > + __c11_atomic_fetch_or(object, operand, order) > +#define atomic_fetch_xor_explicit(object, operand, order) \ > + __c11_atomic_fetch_xor(object, operand, order) > +#define atomic_fetch_and_explicit(object, operand, order) \ > + __c11_atomic_fetch_and(object, operand, order) > + > +#elif (__GNUC__ =3D=3D 4 && __GNUC_MINOR__ >=3D 7) || __GNUC__ > 4 > + > +#define ATOMIC_VAR_INIT(value) (value) > +#define atomic_init(obj, value) do { *(obj) =3D (value); } while (0) > + > +#if (__GNUC__ =3D=3D 4 && __GNUC_MINOR__ >=3D 9) || __GNUC__ > 4 > +#define kill_dependency(y) __extension__({__auto_type __y =3D (y); __y;}= ) > + > +#define atomic_is_lock_free(obj) \ > + __extension__({ \ > + __auto_type __obj =3D (obj); \ > + __atomic_is_lock_free(sizeof(*__obj), __obj); \ > + }) > +#else > +#define __NEED__Atomic > + > +#define kill_dependency(y) (y) > + > +#define atomic_is_lock_free(obj) \ > + __atomic_is_lock_free(sizeof(*(obj)), (void *)0) > +#endif > + > +#define __atomic_type_is_lock_free(type) \ > + __atomic_always_lock_free(sizeof(type), (void *)0) > + > +#define atomic_thread_fence(order) __atomic_thread_fence(order) > +#define atomic_signal_fence(order) __atomic_signal_fence(order) > + > +#define atomic_store_explicit(object, value, order) \ > + __atomic_store_n(object, value, order) > +#define atomic_load_explicit(object, order) \ > + __atomic_load_n(object, order) > + > +#define atomic_exchange_explicit(object, desired, order) \ > + __atomic_exchange_n(object, desired, order) > +#define atomic_compare_exchange_strong_explicit(object, expected, desire= d, \ > + success, failure) \ > + __atomic_compare_exchange_n(object, expected, desired, 0, success, f= ailure) > +#define atomic_compare_exchange_weak_explicit(object, expected, desired,= \ > + success, failure) \ > + __atomic_compare_exchange_n(object, expected, desired, 1, success, f= ailure) > + > +#define atomic_fetch_add_explicit(object, operand, order) \ > + __atomic_fetch_add(object, operand, order) > +#define atomic_fetch_sub_explicit(object, operand, order) \ > + __atomic_fetch_sub(object, operand, order) > +#define atomic_fetch_or_explicit(object, operand, order) \ > + __atomic_fetch_or(object, operand, order) > +#define atomic_fetch_xor_explicit(object, operand, order) \ > + __atomic_fetch_xor(object, operand, order) > +#define atomic_fetch_and_explicit(object, operand, order) \ > + __atomic_fetch_and(object, operand, order) > + > +#elif __GNUC__ =3D=3D 4 && __GNUC_MINOR__ >=3D 1 > + > +#define __NEED__Atomic > + > +#define kill_dependency(y) (y) > + > +#define ATOMIC_VAR_INIT(value) (value) > +#define atomic_init(obj, value) do { *(obj) =3D (value); } while (0) > + > +#define atomic_is_lock_free(obj) (sizeof(obj) <=3D sizeof(void *)) > +#define __atomic_type_is_lock_free(type) (sizeof(type) <=3D sizeof(void = *)) > + > +#define atomic_thread_fence(order) __sync_synchronize() > +#define atomic_signal_fence(order) __asm__ volatile ("" : : : "memory") > + > +/* for GCC < 4.7 some concessions are made. First off, ordering is ignor= ed and > + * always treated as a full seq_cst barrier. ok, this is consistent with the standard > Second, although these are > + * described as "generic functions" GCC < 4.7 cannot support uses such a= s: > + * int n =3D 4; > + * atomic_int arr[n]; > + * atomic_int *i =3D arr; > + * if (atomic_compare_exchange_strong(i++, ...)) {... > + * because of the liberal use of the __typeof__ extension. > + * Furthermore, GCC specified that test_and_set doesn't necessarily supp= ort > + * arbitrary values. It's used as both exchange and store here. Be caref= ul. */ lock_test_and_set is simply not the right tool for these operations, this should only be used for atomic_flag > +#define atomic_store_explicit(object, value, order) \ > + do { \ > + __sync_lock_test_and_set(object, value); \ > + __sync_synchronize(); \ > + while (0) A missing "}" ? > +#define atomic_load_explicit(object, order) \ > + __atomic_fetch_and_add(object, 0) > + > +#define atomic_exchange_explicit(object, desired, order) \ > + __extension__({ \ > + __typeof__(*(object)) __ret; \ > + __ret =3D __sync_lock_test_and_set(object, desired); \ > + __sync_synchronize(); \ > + __ret; \ > + }) > +#define atomic_compare_exchange_strong_explicit(object, expected, desire= d, \ > + success, failure) \ > + __extension__({ \ > + __typeof__(object) __expected =3D (expected); \ > + __typeof__(*__expected) __prev; \ > + _Bool __ret; \ > + __prev =3D __sync_val_compare_and_swap(object, *__expected, desi= red); \ > + __ret =3D (__prev =3D=3D *__expected); \ > + *__expected =3D __prev; \ > + __ret; \ > + }) > +#define atomic_compare_exchange_weak_explicit(object, expected, desired,= \ > + success, failure) \ > + atomic_compare_exchange_strong_explicit(object, expected, desired, \ > + success, failure) > + > +#define atomic_fetch_add_explicit(object, operand, order) \ > + __sync_fetch_and_add(object, operand) > +#define atomic_fetch_sub_explicit(object, operand, order) \ > + __sync_fetch_and_sub(object, operand) > +#define atomic_fetch_or_explicit(object, operand, order) \ > + __sync_fetch_and_or(object, operand) > +#define atomic_fetch_xor_explicit(object, operand, order) \ > + __sync_fetch_and_xor(object, operand) > +#define atomic_fetch_and_explicit(object, operand, order) \ > + __sync_fetch_and_and(object, operand) > + > +#else > + > +#error "Musl's stdatomic.h does not support your compiler" > + > +#endif > + > +#ifdef __musl_has_extension > +#undef __musl_has_extension > +#undef __has_extension > +#endif > + > +#ifdef __NEED__Atomic > +#undef __NEED__Atomic > +#define _Atomic volatile > +#define volatile(x) x volatile > +#endif argh, redefining volatile, no way this messes the syntax completely think of contexts where () can appear after volatile. E.g int volatile (*toto)[5]; is a valid array declaration. Probably there are other such uses of volatile that would mess up completely. I suppose that you want to ensure that your _Atomic macro works with both, the qualifier version and the type specifier. I don't think that any of this is possible. This is a language feature, and nothing the library can deal with. In P99 I made the choice to just support the specifier variant, definining _Atomic to be a function like macro. First, this is then still valid C99. Then, this avoids to give the false impression to the application programmer that _Atomic qualifiers with all the operations would be supported. E.g with your patch something like _Atomic unsigned counter =3D ATOMIC_VAR_INIT(0); ... if (counter++) { ... so something .. } else { ... we are the first ... } would compile and pass completely unnoticed, but wouldn't implement atomic semantics at all. With P99, the eqivalent line with type specifiers Atomic(unsigned) counter =3D ATOMIC_VAR_INIT(0); would compile, but the line if (counter++) { would fail. In contrast, with the line if (atomic_fetch_add(&counter, 1)) { which also is correct C11 would work. > +typedef enum { > + memory_order_relaxed =3D 0, > + memory_order_consume =3D 1, > + memory_order_acquire =3D 2, > + memory_order_release =3D 3, > + memory_order_acq_rel =3D 4, > + memory_order_seq_cst =3D 5 > +} memory_order; I'd prefer to provide the corresponding macros as gcc defines them with #ifdef and then just use these macros here > +typedef _Atomic _Bool atomic_bool; > +typedef _Atomic char atomic_char; > +typedef _Atomic signed char atomic_schar; > +typedef _Atomic short atomic_short; > +typedef _Atomic int atomic_int; > +typedef _Atomic long atomic_long; > +typedef _Atomic long long atomic_llong; > +typedef _Atomic unsigned char atomic_uchar; > +typedef _Atomic unsigned short atomic_ushort; > +typedef _Atomic unsigned int atomic_uint; > +typedef _Atomic unsigned long atomic_ulong; > +typedef _Atomic unsigned long long atomic_ullong; > +typedef _Atomic unsigned short atomic_char16_t; > +typedef _Atomic unsigned atomic_char32_t; > +typedef _Atomic __typeof__(L'\0') atomic_wchar_t; > +typedef _Atomic signed char atomic_int_least8_t; > +typedef _Atomic short atomic_int_least16_t; > +typedef _Atomic int atomic_int_least32_t; > +typedef _Atomic __typeof__(0x100000000) atomic_int_least64_t; > +typedef _Atomic signed char atomic_int_fast8_t; > +typedef _Atomic int atomic_int_fast16_t; > +typedef _Atomic int atomic_int_fast32_t; > +typedef _Atomic __typeof__(0x100000000) atomic_int_fast64_t; > +typedef _Atomic unsigned char atomic_uint_least8_t; > +typedef _Atomic unsigned short atomic_uint_least16_t; > +typedef _Atomic unsigned int atomic_uint_least32_t; > +typedef _Atomic __typeof__(0x100000000U) atomic_uint_least64_t; > +typedef _Atomic unsigned char atomic_uint_fast8_t; > +typedef _Atomic unsigned atomic_uint_fast16_t; > +typedef _Atomic unsigned atomic_uint_fast32_t; > +typedef _Atomic __typeof__(0x100000000U) atomic_uint_fast64_t; > +typedef _Atomic __typeof__((char *)0 - (char *)0) atomic_intptr_t; > +typedef _Atomic __typeof__(sizeof(0)) atomic_uintptr_t; > +typedef _Atomic __typeof__(sizeof(0)) atomic_size_t_t; > +typedef _Atomic __typeof__((char *)0 - (char *)0) atomic_ptrdiff_t; > +typedef _Atomic __typeof__((char *)0 - (char *)0) atomic_intmax_t; > +typedef _Atomic __typeof__(sizeof(0)) atomic_uintmax_t; > + > +#define ATOMIC_BOOL_LOCK_FREE __atomic_type_is_lock_free(_Bool) > +#define ATOMIC_CHAR_LOCK_FREE __atomic_type_is_lock_free(char) > +#define ATOMIC_CHAR16_T_LOCK_FREE __atomic_type_is_lock_free(unsigned sh= ort) > +#define ATOMIC_CHAR32_T_LOCK_FREE __atomic_type_is_lock_free(unsigned) > +#define ATOMIC_WCHAR_T_LOCK_FREE __atomic_type_is_lock_free(__typeof__(L= '\0')) > +#define ATOMIC_SHORT_LOCK_FREE __atomic_type_is_lock_free(short) > +#define ATOMIC_INT_LOCK_FREE __atomic_type_is_lock_free(int) > +#define ATOMIC_LONG_LOCK_FREE __atomic_type_is_lock_free(long) > +#define ATOMIC_LLONG_LOCK_FREE __atomic_type_is_lock_free(long long) > +#define ATOMIC_POINTER_LOCK_FREE __atomic_type_is_lock_free(void *) > + > +#define atomic_store(object, desired) \ > + atomic_store_explicit(object, desired, memory_order_seq_cst) > +#define atomic_load(object) \ > + atomic_load_explicit(object, memory_order_seq_cst) > + > +#define atomic_exchange(object, desired) \ > + atomic_exchange_explicit(object, desired, memory_order_seq_cst) > +#define atomic_compare_exchange_strong(object, expected, desired) \ > + atomic_compare_exchange_strong_explicit(object, expected, desired, \ > + memory_order_seq_cst, \ > + memory_order_seq_cst) > +#define atomic_compare_exchange_weak(object, expected, desired) \ > + atomic_compare_exchange_weak_explicit(object, expected, desired, \ > + memory_order_seq_cst, \ > + memory_order_seq_cst) > + > +#define atomic_fetch_add(object, operand) \ > + atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) > +#define atomic_fetch_sub(object, operand) \ > + atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) > +#define atomic_fetch_or(object, operand) \ > + atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) > +#define atomic_fetch_xor(object, operand) \ > + atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) > +#define atomic_fetch_and(object, operand) \ > + atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) > + > +typedef _Atomic _Bool atomic_flag; that has chances to be wrong base type, probably this would be better typedef _Atomic int atomic_flag; at least you'd really have to be sure about the ABI that later versions of the corresponding compiler suppose > +#define ATOMIC_FLAG_INIT ATOMIC_VAR_INIT(0) > + > +#define atomic_flag_test_and_set(object) \ > + atomic_exchange(object, 1) > +#define atomic_flag_test_and_set_explicit(object, order) \ > + atomic_exchange_explicit(object, 1, order) here also this should definitively chose the ABI that is provided, namely the __sync_lock_test_and_set builtins. Operations on atomic_flag must be guaranteed to be lockfree, and the __sync_lock builtins are the only ones where gcc seem to give such a guarantee. > +#define atomic_flag_clear(object) \ > + atomic_store(object, 0) > +#define atomic_flag_clear_explicit(object, order) \ > + atomic_store_explicit(object, 0, order) > + > +#endif --=20 :: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS ::: :: ::::::::::::::: office Strasbourg : +33 368854536 :: :: :::::::::::::::::::::: gsm France : +33 651400183 :: :: ::::::::::::::: gsm international : +49 15737185122 :: :: http://icube-icps.unistra.fr/index.php/Jens_Gustedt :: --=-9i3qSusCa5uYL7A7SndA Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEABECAAYFAlRfoF0ACgkQD9PoadrVN+JtrQCfSl9yM7I82B6Rq3hWZ7/I1yKU iGoAnifRR9ZlnMFd6pWJDI3pGy5O0VLQ =1KIG -----END PGP SIGNATURE----- --=-9i3qSusCa5uYL7A7SndA--