Re: apr_atomic_casptr2() in apr-1.8.x ?

2022-06-24 Thread Eric Covener
On Fri, Jun 24, 2022 at 10:34 AM Yann Ylavic  wrote:
>
> Daniel proposed in [1] that we introduce apr_atomic_casptr2() to
> resolve the defect in the apr_atomic_casptr() API.
> Namely the correct:
> 1. APR_DECLARE(void*) apr_atomic_casptr(void *volatile *mem, ...);
> Versus the broken:
> 2. APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, ...);
>
> The problem with 2 is that it does not prevent the compiler from
> caching *mem into a local variable, which would break atomicity.
>
> This is fixed in trunk already where we could change the API to 1, but
> not in 1.x.
> Anyone opposed to the attached patch (for 1.8.x only then)?
>
> Regards;
> Yann.
>
> [1] https://bz.apache.org/bugzilla/show_bug.cgi?id=50731#c2

+1


apr_atomic_casptr2() in apr-1.8.x ?

2022-06-24 Thread Yann Ylavic
Daniel proposed in [1] that we introduce apr_atomic_casptr2() to
resolve the defect in the apr_atomic_casptr() API.
Namely the correct:
1. APR_DECLARE(void*) apr_atomic_casptr(void *volatile *mem, ...);
Versus the broken:
2. APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, ...);

The problem with 2 is that it does not prevent the compiler from
caching *mem into a local variable, which would break atomicity.

This is fixed in trunk already where we could change the API to 1, but
not in 1.x.
Anyone opposed to the attached patch (for 1.8.x only then)?

Regards;
Yann.

[1] https://bz.apache.org/bugzilla/show_bug.cgi?id=50731#c2
Index: atomic/netware/apr_atomic.c
===
--- atomic/netware/apr_atomic.c	(revision 1902233)
+++ atomic/netware/apr_atomic.c	(working copy)
@@ -72,6 +72,11 @@ APR_DECLARE(void *) apr_atomic_casptr(volatile voi
 return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
 }
 
+APR_DECLARE(void *) apr_atomic_casptr2(void *volatile *mem, void *with, const void *cmp)
+{
+return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
 {
 return (void*)atomic_xchg((unsigned long *)mem,(unsigned long)with);
Index: atomic/os390/atomic.c
===
--- atomic/os390/atomic.c	(revision 1902233)
+++ atomic/os390/atomic.c	(working copy)
@@ -94,6 +94,15 @@ void *apr_atomic_casptr(volatile void **mem_ptr,
_ptr);
  return (void *)cmp_ptr;
 }
+void *apr_atomic_casptr2(void *volatile *mem_ptr,
+ void *swap_ptr,
+ const void *cmp_ptr)
+{
+ __cs1(_ptr, /* automatically updated from mem on __cs1 failure  */
+   mem_ptr,  /* set from swap when __cs1 succeeds*/
+   _ptr);
+ return (void *)cmp_ptr;
+}
 #elif APR_SIZEOF_VOIDP == 8
 void *apr_atomic_casptr(volatile void **mem_ptr,
 void *swap_ptr,
@@ -104,6 +113,15 @@ void *apr_atomic_casptr(volatile void **mem_ptr,
_ptr);  
  return (void *)cmp_ptr;
 }
+void *apr_atomic_casptr2(void *volatile *mem_ptr,
+ void *swap_ptr,
+ const void *cmp_ptr)
+{
+ __csg(_ptr, /* automatically updated from mem on __csg failure  */
+   mem_ptr,  /* set from swap when __csg succeeds*/
+   _ptr);  
+ return (void *)cmp_ptr;
+}
 #else
 #error APR_SIZEOF_VOIDP value not supported
 #endif /* APR_SIZEOF_VOIDP */
Index: atomic/unix/builtins.c
===
--- atomic/unix/builtins.c	(revision 1902234)
+++ atomic/unix/builtins.c	(working copy)
@@ -121,6 +121,16 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void
 #endif
 }
 
+APR_DECLARE(void*) apr_atomic_casptr2(void *volatile *mem, void *ptr, const void *cmp)
+{
+#if HAVE__ATOMIC_BUILTINS
+__atomic_compare_exchange_n(mem, (void *), ptr, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+return (void *)cmp;
+#else
+return (void *)__sync_val_compare_and_swap(mem, (void *)cmp, ptr);
+#endif
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *ptr)
 {
 #if HAVE__ATOMIC_BUILTINS
Index: atomic/unix/ia32.c
===
--- atomic/unix/ia32.c	(revision 1902233)
+++ atomic/unix/ia32.c	(working copy)
@@ -111,6 +111,24 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void
 return prev;
 }
 
+APR_DECLARE(void*) apr_atomic_casptr2(void *volatile *mem, void *with, const void *cmp)
+{
+void *prev;
+#if APR_SIZEOF_VOIDP == 4
+asm volatile ("lock; cmpxchgl %2, %1"
+  : "=a" (prev), "=m" (*mem)
+  : "r" (with), "m" (*mem), "0" (cmp));
+#elif APR_SIZEOF_VOIDP == 8
+asm volatile ("lock; cmpxchgq %q2, %1"
+  : "=a" (prev), "=m" (*mem)
+  : "r" ((unsigned long)with), "m" (*mem),
+"0" ((unsigned long)cmp));
+#else
+#error APR_SIZEOF_VOIDP value not supported
+#endif
+return prev;
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
 {
 void *prev;
Index: atomic/unix/mutex.c
===
--- atomic/unix/mutex.c	(revision 1902233)
+++ atomic/unix/mutex.c	(working copy)
@@ -190,6 +190,21 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void
 return prev;
 }
 
+APR_DECLARE(void*) apr_atomic_casptr(void *volatile *mem, void *with, const void *cmp)
+{
+void *prev;
+DECLARE_MUTEX_LOCKED(mutex, *mem);
+
+prev = *(void **)mem;
+if (prev == cmp) {
+*mem = with;
+}
+
+MUTEX_UNLOCK(mutex);
+
+return prev;
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
 {
 void *prev;

Re: GitHub Actions CI

2022-06-24 Thread Yann Ylavic
On Wed, Jun 22, 2022 at 2:26 PM Ivan Zhakov via dev  wrote:
>
> Suggestions and improvements are welcome.

I don't see any warning left in trunk and 1.8.x, possibly we'd have a
Windows /Werror build (or whatever appropriate msvc toggle is) to
better check the ones that would be introduced?

Regards;
Yann.


Re: svn commit: r1902206 - /apr/apr/trunk/encoding/apr_base64.c

2022-06-24 Thread Yann Ylavic
On Fri, Jun 24, 2022 at 11:56 AM Yann Ylavic  wrote:
>
> On Thu, Jun 23, 2022 at 8:50 PM Ruediger Pluem  wrote:
> >
> > On 6/23/22 5:12 PM, yla...@apache.org wrote:
> > >
> > > +/* Above APR_BASE64_ENCODE_MAX length the encoding can't fit in an int 
> > > >= 0 */
> > > +#define APR_BASE64_ENCODE_MAX 1610612733
> > > +
> > > +/* Above APR_BASE64_DECODE_MAX length the decoding can't fit in an int 
> > > >= 0 */
> > > +#define APR_BASE64_DECODE_MAX 2863311524u
> > > +
> >
> > Doesn't this depend on the storage size of int on the respective 
> > architecture and thus
> > should be derived from INT_MAX?
>
> There is no APR_INT_MAX unfortunately

By the way, I don't see much value in the
APR_{U,}INT{8,16,32,64}_{MIN,MAX} definitions we have, those values
have well known min/max (i.e. fixed).
I'd rather we define APR_{U,}{CHAR,SHORT,INT,LONG,LONGLONG}_MAX ones,
but without C99 (stdint.h, though most if not all platforms should
have this header now) it may be tricky (if not impossible) to define
them portably..

>
> Regards;
> Yann.


Re: svn commit: r1902206 - /apr/apr/trunk/encoding/apr_base64.c

2022-06-24 Thread Yann Ylavic
On Thu, Jun 23, 2022 at 8:50 PM Ruediger Pluem  wrote:
>
> On 6/23/22 5:12 PM, yla...@apache.org wrote:
> >
> > +/* Above APR_BASE64_ENCODE_MAX length the encoding can't fit in an int >= 
> > 0 */
> > +#define APR_BASE64_ENCODE_MAX 1610612733
> > +
> > +/* Above APR_BASE64_DECODE_MAX length the decoding can't fit in an int >= 
> > 0 */
> > +#define APR_BASE64_DECODE_MAX 2863311524u
> > +
>
> Doesn't this depend on the storage size of int on the respective architecture 
> and thus
> should be derived from INT_MAX?

There is no APR_INT_MAX unfortunately, I could do something like:

#if APR_HAVE_STDINT_H /* C99, but maintainer-mode is C89 */
#include 
#define APR_BASE64_LEN_MAX INT_MAX
#else
#define APR_BASE64_LEN_MAX APR_INT32_MAX
#endif

and use APR_BASE64_LEN_MAX instead of APR_INT32_MAX here and there,
but I doubt there are any architectures (we care about) where
sizeof(int) != 4.
I don't think we support < 32bit archs, do we?
For >= 32bit archs, of the 5 data models (LP32, ILP32, ILP64, LLP64
and LP64), only LP32 (i.e. WIN16 API, Apple Macintosh) and ILP64 ([1]
mentions HAL Computer Systems port of Solaris to the SPARC64) don't
have 32bit ints, and I don't think we care about those either.

So we should be safe assuming ints are 32bit?

Regards;
Yann.

[1] https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models