csutil/threading/atomicops_gcc_arm.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

csutil/threading/atomicops_gcc_arm.h

    00001 /*
    00002   Copyright (C) 2010 by Stefano Angeleri
    00003                 2006 by Marten Svanfeldt
    00004
    00005   This library is free software; you can redistribute it and/or
    00006   modify it under the terms of the GNU Lesser General Public
    00007   License as published by the Free Software Foundation; either
    00008   version 2 of the License, or (at your option) any later version.
    00009
    00010   This library is distributed in the hope that it will be useful,
    00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013   Library General Public License for more details.
    00014
    00015   You should have received a copy of the GNU Library General Public
    00016   License along with this library; if not, write to the Free
    00017   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00018 */
    00019
    00020 #ifndef __CS_CSUTIL_ATOMICOPS_GCC_ARM_H__
    00021 #define __CS_CSUTIL_ATOMICOPS_GCC_ARM_H__
    00022
    00023 #ifndef DOXYGEN_RUN
    00024
    00025 namespace CS
    00026 {
    00027 namespace Threading
    00028 {
    00029   class CS_CRYSTALSPACE_EXPORT AtomicOperationsArmGCC
    00030   {
    00031
    00032     private:
    00033
    00034     //NOTE: This could be a big problem with static linking but
    00035     //      I couldn't find a better way to implement it.
    00036     //      (Each plugin will have his copy making the lock useless)
    00037     static char AtomicLock;
    00038
    00039     inline static char Swpb(volatile char *target, char value)
    00040     {
    00041        register char ret;
    00042        asm volatile("swpb %0 , %2, [%3]"
    00043                     : "=&r"(ret), "=m" (*target)
    00044                     : "r"(value), "r"(target)
    00045                     : "cc", "memory");
    00046        return ret;
    00047     }
    00048
    00049     public:
    00050
    00051     inline static int32 Set (int32* target, int32 value)
    00052     {
    00053        while(Swpb(&AtomicLock, ~0) != 0);
    00054        *target = value;
    00055        Swpb(&AtomicLock, 0);
    00056        return value;
    00057     }
    00058
    00059     inline static void* Set (void** target, void* value)
    00060     {
    00061        return (void*)Set ((int32*)target, (int32)value);
    00062     }
    00063
    00064     inline static int32 CompareAndSet (int32* target, int32 value,
    00065       int32 comparand)
    00066     {
    00067
    00068        while(Swpb(&AtomicLock, ~0) != 0);
    00069        int32 oldvalue = *target;
    00070        if(*target == comparand)
    00071          *target = value;
    00072        Swpb(&AtomicLock, 0);
    00073        return oldvalue;
    00074     }
    00075
    00076     inline static void* CompareAndSet (void** target, void* value,
    00077       void* comparand)
    00078     {
    00079        return (void*)CompareAndSet ((int32*)target, (int32)value,
    00080         (int32)comparand);
    00081     }
    00082
    00083     inline static int32 Increment (int32* target, register int32 incr = 1)
    00084     {
    00085        while(Swpb(&AtomicLock, ~0) != 0);
    00086        *target += incr;
    00087        int32 ret = *target;
    00088        Swpb(&AtomicLock, 0);
    00089        return ret;
    00090     }
    00091
    00092     inline static int32 Decrement (int32* target)
    00093     {
    00094        return (int32)Increment (target, -1);
    00095     }
    00096   };
    00097 }
    00098 }
    00099
    00100 #endif // DOXYGEN_RUN
    00101
    00102 #endif // __CS_CSUTIL_ATOMICOPS_GCC_ARM_H__