strip added smb:// shares of their user/pass when adding, and instead store that...
[vuplus_xbmc] / lib / cmyth / include / refmem / atomic.h
1 #ifndef __MVP_ATOMIC_H
2 #define __MVP_ATOMIC_H
3
4 #ifdef __APPLE__
5 #pragma GCC optimization_level 0
6 #endif
7
8 #ifdef _MSC_VER
9 #include <windows.h>
10 #endif
11 /**
12  * Atomically incremente a reference count variable.
13  * \param valp address of atomic variable
14  * \return incremented reference count
15  */
16 typedef unsigned mvp_atomic_t;
17 static inline unsigned
18 __mvp_atomic_increment(mvp_atomic_t *valp)
19 {
20         mvp_atomic_t __val;
21 #if defined __i486__ || defined __i586__ || defined __i686__
22         __asm__ __volatile__(
23                 "lock xaddl %0, (%1);"
24                 "     inc   %0;"
25                 : "=r" (__val)
26                 : "r" (valp), "0" (0x1)
27                 : "cc", "memory"
28                 );
29 #elif defined __i386__
30         asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
31                       : "=a" (__val)
32                       : "0" (1), "m" (*valp), "d" (valp)
33                       : "memory");
34         /* on the x86 __val is the pre-increment value, so normalize it. */
35         ++__val;
36 #elif defined __powerpc__ || defined __ppc__
37         asm volatile ("1:       lwarx   %0,0,%1\n"
38                       " addic.   %0,%0,1\n"
39                       " dcbt    %0,%1\n"
40                       " stwcx.  %0,0,%1\n"
41                       " bne-    1b\n"
42                       " isync\n"
43                       : "=&r" (__val)
44                       : "r" (valp)
45                       : "cc", "memory");
46 #elif defined _MSC_VER
47   __val = InterlockedIncrement(valp);
48 #else
49         /*
50          * Don't know how to atomic increment for a generic architecture
51          * so punt and just increment the value.
52          */
53 #ifdef _WIN32
54   #pragma message("unknown architecture, atomic increment is not...");
55 #else
56   #warning unknown architecture, atomic increment is not...
57 #endif
58         __val = ++(*valp);
59 #endif
60         return __val;
61 }
62
63 /**
64  * Atomically decrement a reference count variable.
65  * \param valp address of atomic variable
66  * \return decremented reference count
67  */
68 static inline unsigned
69 __mvp_atomic_decrement(mvp_atomic_t *valp)
70 {
71         mvp_atomic_t __val;
72 #if defined __i486__ || defined __i586__ || defined __i686__
73         __asm__ __volatile__(
74                 "lock xaddl %0, (%1);"
75                 "     dec   %0;"
76                 : "=r" (__val)
77                 : "r" (valp), "0" (0x1)
78                 : "cc", "memory"
79                 );
80 #elif defined __i386__
81         asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
82                       : "=a" (__val)
83                       : "0" (-1), "m" (*valp), "d" (valp)
84                       : "memory");
85         /* __val is the pre-decrement value, so normalize it */
86         --__val;
87 #elif defined __powerpc__ || defined __ppc__
88         asm volatile ("1:       lwarx   %0,0,%1\n"
89                       " addic.   %0,%0,-1\n"
90                       " dcbt    %0,%1\n"
91                       " stwcx.  %0,0,%1\n"
92                       " bne-    1b\n"
93                       " isync\n"
94                       : "=&r" (__val)
95                       : "r" (valp)
96                       : "cc", "memory");
97 #elif defined __sparcv9__
98         mvp_atomic_t __newval, __oldval = (*valp);
99         do
100                 {
101                         __newval = __oldval - 1;
102                         __asm__ ("cas   [%4], %2, %0"
103                                  : "=r" (__oldval), "=m" (*valp)
104                                  : "r" (__oldval), "m" (*valp), "r"((valp)), "0" (__newval));
105                 }
106         while (__newval != __oldval);
107         /*  The value for __val is in '__oldval' */
108         __val = __oldval;
109 #elif defined _MSC_VER
110   __val = InterlockedDecrement(valp);
111 #else
112         /*
113          * Don't know how to atomic decrement for a generic architecture
114          * so punt and just decrement the value.
115          */
116 //#warning unknown architecture, atomic decrement is not...
117         __val = --(*valp);
118 #endif
119         return __val;
120 }
121 #define mvp_atomic_inc __mvp_atomic_inc
122 static inline int mvp_atomic_inc(mvp_atomic_t *a) {
123         return __mvp_atomic_increment(a);
124 };
125
126 #define mvp_atomic_dec __mvp_atomic_dec
127 static inline int mvp_atomic_dec(mvp_atomic_t *a) {
128         return __mvp_atomic_decrement(a);
129 };
130
131 #define mvp_atomic_dec_and_test __mvp_atomic_dec_and_test
132 static inline int mvp_atomic_dec_and_test(mvp_atomic_t *a) {
133         return (__mvp_atomic_decrement(a) == 0);
134 };
135
136 #define mvp_atomic_set __mvp_atomic_set
137 static inline void mvp_atomic_set(mvp_atomic_t *a, unsigned val) {
138         *a = val;
139 };
140
141 #ifdef __APPLE__
142 #pragma GCC optimization_level reset
143 #endif
144
145 #endif  /* __MVP_ATOMIC_H */