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