Locks.h

00001 //Thread Locking constructs
00002 //Luke Lenhart, 2007
00003 //See /docs/License.txt for details on how this code may be used.
00004 
00005 #pragma once
00006 
00007 namespace MPMA
00008 {
00009     //Atomically increments an integer
00010     inline void AtomicIntInc(volatile uint *pint)
00011     {
00012         asm( "lock incl (%0);"
00013             :
00014             :"r"(pint)
00015             :"%0", "memory");
00016     }
00017 
00018     //Atomically decrements an integer
00019     inline void AtomicIntDec(volatile uint *pint)
00020     {
00021         asm( "lock decl (%0);"
00022             :
00023             :"r"(pint)
00024             :"%0", "memory");
00025     }
00026     
00027     //Atomically adds one integer to another and returns the value of the original
00028     inline int AtomicIntAdd(volatile int *pint, int addValue)
00029     {
00030         int rval;
00031         asm volatile( "lock xaddl %2, (%1);"
00032                       "movl %2, %0"
00033                      :"=g"(rval)
00034                      :"r"(pint), "r"(addValue)
00035                      :"%0", "%1", "%2", "memory");
00036         return rval;
00037     }
00038 
00039     //Compares expectedValue with the value at pInt, and if they are the same, sets pInt to newValue and returns true with outResultValue set to newValue.  If they are different then pInt is unaffected, and returns false with outResultValue set to the value that was found at pInt.
00040     inline bool AtomicCompareExchange(volatile uint *pInt, uint expectedValue, uint newValue, volatile uint &outResultValue)
00041     {
00042         volatile uint changed=0; //why does this need volatile? it fixes the return bug...
00043         uint rval;
00044         asm(
00045              "lock cmpxchgl %4, (%2);"
00046              "jnz AtomCmpExch_Diff%=;"
00047              "movl %4, %%eax;"
00048              "incl %1;"
00049              "AtomCmpExch_Diff%=:;"
00050              "movl %%eax, %0;"
00051             :"=g"(rval), "=g"(changed)
00052             :"r"(pInt), "a"(expectedValue), "r"(newValue)
00053             :"memory", "cc");
00054 
00055         outResultValue=rval;
00056         return changed!=0;
00057     }
00058 
00059 }; //namespace MPMA

Generated on Wed Feb 13 20:57:04 2008 for MPMA Framework by  doxygen 1.5.4