The current apr_atomic API has a couple of limitations: * The size of apr_atomic_t varies among platforms, which makes it hard to guarantee portability of applications that use this type to store large values. * The arithmetic functions use apr_atomic_t, while the compare-and-swap function uses a mix of apr_uint32_t and long int. Thus it's impossible to portably write code that uses, say, apr_atomic_dec() and apr_atomic_cas() on the same variable.
This patch presents a proposed new API in which the atomic functions explicitly operate on 32-bit ints. I'd like to add commit this new API (plus an implementation) next week. But if anyone has objections or suggested changes, please let me know... Thanks, Brian
Index: include/apr_atomic.h =================================================================== RCS file: /home/cvs/apr/include/apr_atomic.h,v retrieving revision 1.49 diff -u -r1.49 apr_atomic.h --- include/apr_atomic.h 13 Sep 2003 05:05:11 -0000 1.49 +++ include/apr_atomic.h 13 Sep 2003 05:28:42 -0000 @@ -104,24 +104,28 @@ * @param mem the pointer * @warning on certain platforms this number is not stored * directly in the pointer. in others it is + * @deprecated */ apr_uint32_t apr_atomic_read(volatile apr_atomic_t *mem); /** * set the value for atomic. * @param mem the pointer * @param val the value + * @deprecated */ void apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val); /** * Add 'val' to the atomic variable * @param mem pointer to the atomic value * @param val the addition + * @deprecated */ void apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val); /** * increment the atomic variable by 1 * @param mem pointer to the atomic value + * @deprecated */ void apr_atomic_inc(volatile apr_atomic_t *mem); @@ -129,6 +133,7 @@ * decrement the atomic variable by 1 * @param mem pointer to the atomic value * @return zero if the value is zero, otherwise non-zero + * @deprecated */ int apr_atomic_dec(volatile apr_atomic_t *mem); @@ -140,9 +145,60 @@ * @param cmp the value to compare it to * @return the old value of the atomic * @warning do not mix apr_atomic's with the CAS function. + * @deprecated * on some platforms they may be implemented by different mechanisms */ apr_uint32_t apr_atomic_cas(volatile apr_uint32_t *mem, long with, long cmp); + +/** + * atomically read an apr_uint32_t from memory + * @param mem the pointer + */ +apr_uint32_t apr_atomic_read32(volatile apr_uint32_t *mem); + +/** + * atomically set an apr_uint32_t in memory + * @param mem pointer to the object + */ +void apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val); + +/** + * atomically add 'val' to an apr_uint32_t + * @param mem pointer to the object + * @param val amount to add + */ +void apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val); + +/** + * atomically subtract 'val' from an apr_uint32_t + * @param mem pointer to the object + * @param val amount to subtract + */ +void apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val); + +/** + * atomically increment an apr_uint32_t by 1 + * @param mem pointer to the object + */ +void apr_atomic_inc32(volatile apr_uint32_t *mem); + +/** + * atomically decrement an apr_uint32_t by 1 + * @param mem pointer to the atomic value + * @return zero if the value becomes zero on decrement, otherwise non-zero + */ +int apr_atomic_inc32(volatile apr_uint32_t *mem); + +/** + * compare an apr_uint32_t's value with 'cmp'. + * If they are the same swap the value with 'with' + * @param mem pointer to the value + * @param with what to swap it with + * @param cmp the value to compare it to + * @return the old value of *mem + */ +apr_uint32_t apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with, + apr_uint32_t cmp); /** * compare the pointer's value with cmp.