Re: [AD] user-defined events

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On 2008-10-17, Elias Pschernig <elias.pschernig@xxxxxxxxxx> wrote:
> 
> That works just as good of course. I don't particulary like the malloc
> in al_emit_user_event, but it shouldn't really matter. And I wonder what
> to do about __sync_fetch_and_add and __sync_sub_and_fetch for MSVC..

Something like this.

Peter
#ifndef __al_included_aintern_atomic_ops_h
#define __al_included_aintern_atomic_ops_h

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)

   /* gcc 4.1 and above have builtin atomic operations. */

   typedef int _AL_ATOMIC;

   AL_INLINE(_AL_ATOMIC,
      _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr),
   {
      return __sync_fetch_and_add(ptr, 1);
   })

   AL_INLINE(_AL_ATOMIC,
      _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr),
   {
      return __sync_sub_and_fetch(ptr, 1);
   })

#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))

   /* gcc, x86 or x86-64 */

   typedef int _AL_ATOMIC;

   AL_INLINE(_AL_ATOMIC,
      __al_fetch_and_add, (volatile _AL_ATOMIC *ptr, _AL_ATOMIC value),
   {
      _AL_ATOMIC result;

      __asm__ __volatile__ (
         "lock; xaddl %0, %1"
         : "=r" (result), "=m" (*ptr)
         : "0" (value), "m" (*ptr)
         : "memory"
      );
      return result;
   })

   AL_INLINE(_AL_ATOMIC,
      _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr),
   {
      return __al_fetch_and_add(ptr, 1);
   })

   AL_INLINE(_AL_ATOMIC,
      _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr),
   {
      _AL_ATOMIC old = __al_fetch_and_add(ptr, -1);
      return old - 1;
   })

#elif defined(_MSC_VER) && _M_IX86 >= 400

   /* MSVC, x86 */
   /* MinGW supports these too, but we already have asm code above. */

   typedef LONG _AL_ATOMIC;

   AL_INLINE(_AL_ATOMIC,
      _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr),
   {
      return InterlockedIncrement(ptr) - 1;
   })

   AL_INLINE(_AL_ATOMIC,
      _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr),
   {
      return InterlockedDecrement(ptr);
   })

#else

   /* Hope for the best? */
   #warning Atomic operations undefined for your compiler/architecture.

   typedef int _AL_ATOMIC;

   AL_INLINE(_AL_ATOMIC,
      _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr),
   {
      return (*ptr)++;
   })

   AL_INLINE(_AL_ATOMIC,
      _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr),
   {
      return --(*ptr);
   })

#endif

#endif   /* __al_included_aintern_atomicops_h */

/* vim: set sts=3 sw=3 et: */


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/