core/lock.h

Go to the documentation of this file.
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 /* defined(WIN32) */
00042 
00043 #ifndef HAVE_CMPXCHG
00044     #define NOLOCKS 1
00045 #endif /* !defined(CMPXCHG) */
00046 
00047 #ifdef NOLOCKS
00048     #define LOCK(flags)
00049     #define UNLOCK(flags)
00050     #define LOCK_OBJECT(obj)
00051     #define UNLOCK_OBJECT(obj)
00052 #else /* !defined(NOLOCKS) */
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 /* defined(NOLOCKS) */
00080 
00081 #endif /* _LOCK_H */
00082 

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy