00001
00011 #ifndef _ATOMIC_H_
00012 #define _ATOMIC_H_
00013
00014
00021 struct atomic {
00023 volatile int value;
00024 };
00025
00027 typedef struct atomic atomic_t;
00028
00029
00034 #define AV_INIT(val) { .value = (val) }
00035
00036
00047 static inline int
00048 av_get (atomic_t * av)
00049 {
00050 return av->value;
00051 }
00052
00053
00060 static inline void
00061 av_set (atomic_t * av, int val)
00062 {
00063 av->value = val;
00064 }
00065
00066
00074 static inline void
00075 av_add (atomic_t * av, int num)
00076 {
00077 int temp;
00078
00079 __asm__ __volatile__ (
00080
00081 " .set push \n"
00082 " .set noreorder \n"
00083 " \n"
00084 "1: ll %[temp], %[value] \n"
00085 " addu %[temp], %[num] \n"
00086 " sc %[temp], %[value] \n"
00087 " beqz %[temp], 1b \n"
00088 " \n"
00089 " .set pop \n"
00090
00091 : [temp] "=&r" (temp),
00092 [value] "+m" ((av)->value)
00093 : [num] "Ir" (num)
00094 );
00095 }
00096
00097
00104 static inline void
00105 av_sub (atomic_t * av, int num)
00106 {
00107 int temp;
00108
00109 __asm__ __volatile__ (
00110
00111 " .set push \n"
00112 " .set noreorder \n"
00113 " \n"
00114 "1: ll %[temp], %[value] \n"
00115 " subu %[temp], %[num] \n"
00116 " sc %[temp], %[value] \n"
00117 " beqz %[temp], 1b \n"
00118 " \n"
00119 " .set pop \n"
00120
00121 : [temp] "=&r" (temp),
00122 [value] "+m" ((av)->value)
00123 : [num] "Ir" (num)
00124 );
00125 }
00126
00127
00132 static inline int
00133 av_add_result (atomic_t * av, int num)
00134 {
00135 int temp, result;
00136
00137 __asm__ __volatile__ (
00138
00139 " .set push \n"
00140 " .set noreorder \n"
00141 " \n"
00142 "1: ll %[temp], %[value] \n"
00143 " addu %[result], %[temp], %[num] \n"
00144 " sc %[result], %[value] \n"
00145 " beqz %[result], 1b \n"
00146 " \n"
00147 " addu %[result], %[temp], %[num] \n"
00148 " sync \n"
00149 " \n"
00150 " .set pop \n"
00151
00152 : [temp] "=&r" (temp),
00153 [result] "=&r" (result),
00154 [value] "+m" ((av)->value)
00155 : [num] "Ir" (num)
00156 : "memory"
00157 );
00158
00159 return result;
00160 }
00161
00162
00169 static inline int
00170 av_sub_result (atomic_t * av, int num)
00171 {
00172 int temp, result;
00173
00174 __asm__ __volatile__ (
00175
00176 " .set push \n"
00177 " .set noreorder \n"
00178 " \n"
00179 "1: ll %[temp], %[value] \n"
00180 " subu %[result], %[temp], %[num] \n"
00181 " sc %[result], %[value] \n"
00182 " beqz %[result], 1b \n"
00183 " \n"
00184 " subu %[result], %[temp], %[num] \n"
00185 " sync \n"
00186 " \n"
00187 " .set pop \n"
00188
00189 : [temp] "=&r" (temp),
00190 [result] "=&r" (result),
00191 [value] "+m" ((av)->value)
00192 : [num] "Ir" (num)
00193 : "memory"
00194 );
00195
00196 return result;
00197 }
00198
00199
00200 #endif