csutil/threading/atomicops_gcc_ppc.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_ppc.h

    00001 /*
    00002   Copyright (C) 2006 by Marten Svanfeldt
    00003
    00004   This library is free software; you can redistribute it and/or
    00005   modify it under the terms of the GNU Lesser General Public
    00006   License as published by the Free Software Foundation; either
    00007   version 2 of the License, or (at your option) any later version.
    00008
    00009   This library is distributed in the hope that it will be useful,
    00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012   Library General Public License for more details.
    00013
    00014   You should have received a copy of the GNU Library General Public
    00015   License along with this library; if not, write to the Free
    00016   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00017 */
    00018
    00019 #ifndef __CS_CSUTIL_ATOMICOPS_GCC_PPC_H__
    00020 #define __CS_CSUTIL_ATOMICOPS_GCC_PPC_H__
    00021
    00022 #ifndef DOXYGEN_RUN
    00023
    00024 namespace CS
    00025 {
    00026 namespace Threading
    00027 {
    00028   class AtomicOperationsPPCGCC
    00029   {
    00030   public:
    00031     inline static int32 Set (int32* target, int32 value)
    00032     {
    00033       __asm__ __volatile__
    00034         (
    00035         "       lwsync \n"
    00036         "1:     lwarx   %0,0,%2 \n"
    00037         "       dcbt     0,%2 \n"
    00038         "       stwcx.  %3,0,%2 \n"
    00039         "       bne-    1b\n"
    00040         "       isync \n"
    00041         : "=&r" (value), "=m" (*(unsigned int *)target)
    00042         : "r" (target), "r" (value), "m" (*(unsigned int *)target)
    00043         : "cc", "memory"
    00044         );
    00045       return value;
    00046     }
    00047
    00048     inline static void* Set (void** target, void* value)
    00049     {
    00050 #if CS_PROCESSOR_SIZE == 32
    00051       return (void*)Set ((int32*)target, (int32)value);
    00052 #elif CS_PROCESSOR_SIZE == 64
    00053       __asm__ __volatile__
    00054         (
    00055         "       lwsync \n"
    00056         "1:     ldarx   %0,0,%2 \n"
    00057         "       dcbt     0,%2 \n"
    00058         "       stdcx.  %3,0,%2 \n"
    00059         "       bne-    1b\n"
    00060         "       isync \n"
    00061         : "=&r" (value), "=m" (*(unsigned int *)target)
    00062         : "r" (target), "r" (value), "m" (*(unsigned int *)target)
    00063         : "cc", "memory"
    00064         );
    00065       return value;
    00066 #endif
    00067     }
    00068
    00069     inline static int32 CompareAndSet (int32* target, int32 value,
    00070       int32 comparand)
    00071     {
    00072       int32 prev;
    00073
    00074       __asm__ __volatile__ (
    00075       "       lwsync \n"
    00076       "1:     lwarx   %0,0,%2\n"
    00077       "       cmpw    0,%0,%3\n"
    00078       "       bne-    2f\n"
    00079       "       dcbt     0,%2 \n"
    00080       "       stwcx.  %4,0,%2\n"
    00081       "       bne-    1b\n"
    00082       "       isync     \n"
    00083       "2:"
    00084       : "=&r" (prev), "=m" (*target)
    00085       : "r" (target), "r" (comparand), "r" (value), "m" (*target)
    00086       : "cc", "memory");
    00087       return prev;
    00088     }
    00089
    00090     inline static void* CompareAndSet (void** target, void* value,
    00091       void* comparand)
    00092     {
    00093 #if CS_PROCESSOR_SIZE == 32
    00094       return (void*)CompareAndSet ((int32*)target, (int32)value,
    00095         (int32)comparand);
    00096 #elif CS_PROCESSOR_SIZE == 64
    00097       void* prev;
    00098
    00099       __asm__ __volatile__ (
    00100         "       lwsync \n"
    00101         "1:     ldarx   %0,0,%2\n"
    00102         "       cmpd    0,%0,%3\n"
    00103         "       bne-    2f\n"
    00104         "       dcbt     0,%2 \n"
    00105         "       stdcx.  %4,0,%2\n"
    00106         "       bne-    1b\n"
    00107         "       isync     \n"
    00108         "2:"
    00109         : "=&r" (prev), "=m" (*target)
    00110         : "r" (target), "r" (comparand), "r" (value), "m" (*target)
    00111         : "cc", "memory");
    00112       return prev;
    00113 #endif
    00114     }
    00115
    00116     inline static int32 Increment (int32* target, int32 incr = 1)
    00117     {
    00118       int32 prev;
    00119
    00120       __asm__ __volatile__ (
    00121         "       lwsync \n"
    00122         "1:     lwarx   %0,0,%1\n"
    00123         "       addc    %0,%0,%2\n"
    00124         "       stwcx.  %0,0,%1\n"
    00125         "       bne-    1b\n"
    00126         "       isync     \n"
    00127         : "=&r" (prev)
    00128         : "r" (target), "r" (incr)
    00129         : "cc", "memory");
    00130       return prev;
    00131     }
    00132
    00133     inline static int32 Decrement (int32* target)
    00134     {
    00135       return (int32)Increment (target, -1);
    00136     }
    00137   };
    00138 }
    00139 }
    00140
    00141 #endif // DOXYGEN_RUN
    00142
    00143 #endif // __CS_CSUTIL_ATOMICOPS_GCC_PPC_H__