00001
00030 #ifndef _LOCK_H
00031 #define _LOCK_H
00032
00033 #include "object.h"
00034
00035 #ifdef WIN32
00036 #include <intrin.h>
00037 #pragma intrinsic(_InterlockedCompareExchange)
00038 #define cmpxchg(dest, xchg, comp) ((unsigned long) _InterlockedCompareExchange((long *) dest, (long) xchg, (long) comp))
00039 #define HAVE_CMPXCHG
00040 #elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
00041 #include <libkern/OSAtomic.h>
00042 #define cmpxchg(dest, xchg, comp) (OSAtomicCompareAndSwapLong((long) comp, (long) xchg, (long *) dest) ? xchg : comp)
00043 #define HAVE_CMPXCHG
00044 #else
00045 #define cmpxchg(dest, xchg, comp) __sync_val_compare_and_swap(dest, comp, xchg)
00046 #define HAVE_CMPXCHG
00047 #endif
00048
00049 #ifndef HAVE_CMPXCHG
00050 #define NOLOCKS 1
00051 #endif
00052
00053 #ifdef NOLOCKS
00054 #define LOCK(flags)
00055 #define UNLOCK(flags)
00056 #define LOCK_OBJECT(obj)
00057 #define UNLOCK_OBJECT(obj)
00058 #define LOCKED(obj, command)
00059 #else
00060
00061 static __inline int lock(unsigned long *flags)
00062 {
00063 unsigned int f;
00064 register int spin=0;
00065 do {
00066 spin++;
00067 f = *flags;
00068 } while (f & OF_LOCKED || cmpxchg(flags, f | OF_LOCKED, f) & OF_LOCKED);
00069 return spin;
00070 }
00071
00072 static __inline void unlock(unsigned long *flags)
00073 {
00074 unsigned int f;
00075
00076 do {
00077 f = *flags;
00078 } while (f & OF_LOCKED && cmpxchg(flags, f ^ OF_LOCKED, f) != f);
00079 }
00080
00081 #define LOCK(flags) ((*(callback->lock_count))++, (*(callback->lock_spin))+=lock(flags))
00082 #define UNLOCK(flags) unlock(flags)
00083 #define LOCK_OBJECT(obj) ((*(callback->lock_count))++, (*(callback->lock_spin))+=lock(&((obj)->flags)))
00084 #define UNLOCK_OBJECT(obj) unlock(&((obj)->flags))
00085 #define LOCKED(obj,command) (LOCK_OBJECT(obj),(command),UNLOCK_OBJECT(obj))
00086
00087 #endif
00088
00089 #endif
00090