latomic.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*
  2. * Copyright (c) 2018 Agustina Arzille.
  3. * Copyright (c) 2018 Richard Braun.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. *
  19. * Architecture-specific code may override any of the type-specific
  20. * functions by defining a macro of the same name.
  21. */
  22. #include <kern/atomic_types.h>
  23. #include <kern/latomic.h>
  24. #include <kern/latomic_i.h>
  25. #include <kern/macros.h>
  26. #include <machine/cpu.h>
  27. #include <machine/latomic.h>
  28. #define latomic_swap_n(ptr, val) \
  29. MACRO_BEGIN \
  30. unsigned long flags_; \
  31. typeof(val) ret_; \
  32. \
  33. cpu_intr_save(&flags_); \
  34. ret_ = *(ptr); \
  35. *(ptr) = (val); \
  36. cpu_intr_restore(flags_); \
  37. \
  38. ret_; \
  39. MACRO_END
  40. #define latomic_cas_n(ptr, oval, nval) \
  41. MACRO_BEGIN \
  42. unsigned long flags_; \
  43. typeof(oval) ret_; \
  44. \
  45. cpu_intr_save(&flags_); \
  46. \
  47. ret_ = *(ptr); \
  48. \
  49. if (ret_ == (oval)) { \
  50. *(ptr) = (nval); \
  51. } \
  52. \
  53. cpu_intr_restore(flags_); \
  54. \
  55. ret_; \
  56. MACRO_END
  57. #define latomic_fetch_op_n(ptr, val, op) \
  58. MACRO_BEGIN \
  59. unsigned long flags_; \
  60. typeof(val) ret_; \
  61. \
  62. cpu_intr_save(&flags_); \
  63. ret_ = *(ptr); \
  64. *(ptr) = ret_ op (val); \
  65. cpu_intr_restore(flags_); \
  66. \
  67. ret_; \
  68. MACRO_END
  69. #define latomic_fetch_add_n(ptr, val) latomic_fetch_op_n(ptr, val, +)
  70. #define latomic_fetch_sub_n(ptr, val) latomic_fetch_op_n(ptr, val, -)
  71. #define latomic_fetch_and_n(ptr, val) latomic_fetch_op_n(ptr, val, &)
  72. #define latomic_fetch_or_n(ptr, val) latomic_fetch_op_n(ptr, val, |)
  73. #define latomic_fetch_xor_n(ptr, val) latomic_fetch_op_n(ptr, val, ^)
  74. /* latomic_load */
  75. #ifndef latomic_load_32
  76. unsigned int
  77. latomic_load_32(union atomic_constptr_32 ptr, int memorder)
  78. {
  79. return __atomic_load_n(ptr.ui_ptr, memorder);
  80. }
  81. #endif /* latomic_load_32 */
  82. #ifndef latomic_load_64
  83. #ifdef __LP64__
  84. unsigned long long
  85. latomic_load_64(union atomic_constptr_64 ptr, int memorder)
  86. {
  87. return __atomic_load_n(ptr.ull_ptr, memorder);
  88. }
  89. #else /* __LP64__ */
  90. unsigned long long
  91. latomic_load_64(union atomic_constptr_64 ptr, int memorder)
  92. {
  93. unsigned long long ret;
  94. unsigned long flags;
  95. (void)memorder;
  96. cpu_intr_save(&flags);
  97. ret = *ptr.ull_ptr;
  98. cpu_intr_restore(flags);
  99. return ret;
  100. }
  101. #endif /* __LP64__ */
  102. #endif /* latomic_load_64 */
  103. /* latomic_store */
  104. #ifndef latomic_store_32
  105. void
  106. latomic_store_32(union atomic_ptr_32 ptr, union atomic_val_32 val, int memorder)
  107. {
  108. __atomic_store_n(ptr.ui_ptr, val.ui, memorder);
  109. }
  110. #endif /* latomic_store_32 */
  111. #ifndef latomic_store_64
  112. #ifdef __LP64__
  113. void
  114. latomic_store_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  115. {
  116. return __atomic_store_n(ptr.ull_ptr, val.ull, memorder);
  117. }
  118. #else /* __LP64__ */
  119. void
  120. latomic_store_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  121. {
  122. unsigned long flags;
  123. (void)memorder;
  124. cpu_intr_save(&flags);
  125. *ptr.ull_ptr = val.ull;
  126. cpu_intr_restore(flags);
  127. }
  128. #endif /* __LP64__ */
  129. #endif /* latomic_store_64 */
  130. /* latomic_swap */
  131. #ifndef latomic_swap_32
  132. unsigned int
  133. latomic_swap_32(union atomic_ptr_32 ptr, union atomic_val_32 val, int memorder)
  134. {
  135. (void)memorder;
  136. return latomic_swap_n(ptr.ui_ptr, val.ui);
  137. }
  138. #endif /* latomic_swap_32 */
  139. #ifndef latomic_swap_64
  140. unsigned long long
  141. latomic_swap_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  142. {
  143. (void)memorder;
  144. return latomic_swap_n(ptr.ull_ptr, val.ull);
  145. }
  146. #endif /* latomic_swap_64 */
  147. /* latomic_cas */
  148. #ifndef latomic_cas_32
  149. unsigned int
  150. latomic_cas_32(union atomic_ptr_32 ptr, union atomic_val_32 oval,
  151. union atomic_val_32 nval, int memorder)
  152. {
  153. (void)memorder;
  154. return latomic_cas_n(ptr.ui_ptr, oval.ui, nval.ui);
  155. }
  156. #endif /* latomic_cas_32 */
  157. #ifndef latomic_cas_64
  158. unsigned long long
  159. latomic_cas_64(union atomic_ptr_64 ptr, union atomic_val_64 oval,
  160. union atomic_val_64 nval, int memorder)
  161. {
  162. (void)memorder;
  163. return latomic_cas_n(ptr.ull_ptr, oval.ull, nval.ull);
  164. }
  165. #endif /* latomic_cas_64 */
  166. /* latomic_fetch_add */
  167. #ifndef latomic_fetch_add_32
  168. unsigned int
  169. latomic_fetch_add_32(union atomic_ptr_32 ptr, union atomic_val_32 val,
  170. int memorder)
  171. {
  172. (void)memorder;
  173. return latomic_fetch_add_n(ptr.ui_ptr, val.ui);
  174. }
  175. #endif /* latomic_fetch_add_32 */
  176. #ifndef latomic_fetch_add_64
  177. unsigned long long
  178. latomic_fetch_add_64(union atomic_ptr_64 ptr, union atomic_val_64 val,
  179. int memorder)
  180. {
  181. (void)memorder;
  182. return latomic_fetch_add_n(ptr.ull_ptr, val.ull);
  183. }
  184. #endif /* latomic_fetch_add_64 */
  185. /* latomic_fetch_sub */
  186. #ifndef latomic_fetch_sub_32
  187. unsigned int
  188. latomic_fetch_sub_32(union atomic_ptr_32 ptr, union atomic_val_32 val,
  189. int memorder)
  190. {
  191. (void)memorder;
  192. return latomic_fetch_sub_n(ptr.ui_ptr, val.ui);
  193. }
  194. #endif /* latomic_fetch_sub_32 */
  195. #ifndef latomic_fetch_sub_64
  196. unsigned long long
  197. latomic_fetch_sub_64(union atomic_ptr_64 ptr, union atomic_val_64 val,
  198. int memorder)
  199. {
  200. (void)memorder;
  201. return latomic_fetch_sub_n(ptr.ull_ptr, val.ull);
  202. }
  203. #endif /* latomic_fetch_sub_64 */
  204. /* latomic_fetch_and */
  205. #ifndef latomic_fetch_and_32
  206. unsigned int
  207. latomic_fetch_and_32(union atomic_ptr_32 ptr, union atomic_val_32 val,
  208. int memorder)
  209. {
  210. (void)memorder;
  211. return latomic_fetch_and_n(ptr.ui_ptr, val.ui);
  212. }
  213. #endif /* latomic_fetch_and_32 */
  214. #ifndef latomic_fetch_and_64
  215. unsigned long long
  216. latomic_fetch_and_64(union atomic_ptr_64 ptr, union atomic_val_64 val,
  217. int memorder)
  218. {
  219. (void)memorder;
  220. return latomic_fetch_and_n(ptr.ull_ptr, val.ull);
  221. }
  222. #endif /* latomic_fetch_and_64 */
  223. /* latomic_fetch_or */
  224. #ifndef latomic_fetch_or_32
  225. unsigned int
  226. latomic_fetch_or_32(union atomic_ptr_32 ptr, union atomic_val_32 val,
  227. int memorder)
  228. {
  229. (void)memorder;
  230. return latomic_fetch_or_n(ptr.ui_ptr, val.ui);
  231. }
  232. #endif /* latomic_fetch_or_32 */
  233. #ifndef latomic_fetch_or_64
  234. unsigned long long
  235. latomic_fetch_or_64(union atomic_ptr_64 ptr, union atomic_val_64 val,
  236. int memorder)
  237. {
  238. (void)memorder;
  239. return latomic_fetch_or_n(ptr.ull_ptr, val.ull);
  240. }
  241. #endif /* latomic_fetch_or_64 */
  242. /* latomic_fetch_xor */
  243. #ifndef latomic_fetch_xor_32
  244. unsigned int
  245. latomic_fetch_xor_32(union atomic_ptr_32 ptr, union atomic_val_32 val,
  246. int memorder)
  247. {
  248. (void)memorder;
  249. return latomic_fetch_xor_n(ptr.ui_ptr, val.ui);
  250. }
  251. #endif /* latomic_fetch_xor_32 */
  252. #ifndef latomic_fetch_xor_64
  253. unsigned long long
  254. latomic_fetch_xor_64(union atomic_ptr_64 ptr, union atomic_val_64 val,
  255. int memorder)
  256. {
  257. (void)memorder;
  258. return latomic_fetch_xor_n(ptr.ull_ptr, val.ull);
  259. }
  260. #endif /* latomic_fetch_xor_64 */
  261. /* latomic_add */
  262. #ifndef latomic_add_32
  263. void
  264. latomic_add_32(union atomic_ptr_32 ptr, union atomic_val_32 val, int memorder)
  265. {
  266. (void)memorder;
  267. latomic_fetch_add_n(ptr.ui_ptr, val.ui);
  268. }
  269. #endif /* latomic_add_32 */
  270. #ifndef latomic_add_64
  271. void
  272. latomic_add_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  273. {
  274. (void)memorder;
  275. latomic_fetch_add_n(ptr.ull_ptr, val.ull);
  276. }
  277. #endif /* latomic_add_64 */
  278. /* latomic_sub */
  279. #ifndef latomic_sub_32
  280. void
  281. latomic_sub_32(union atomic_ptr_32 ptr, union atomic_val_32 val, int memorder)
  282. {
  283. (void)memorder;
  284. latomic_fetch_sub_n(ptr.ui_ptr, val.ui);
  285. }
  286. #endif /* latomic_sub_32 */
  287. #ifndef latomic_sub_64
  288. void
  289. latomic_sub_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  290. {
  291. (void)memorder;
  292. latomic_fetch_sub_n(ptr.ull_ptr, val.ull);
  293. }
  294. #endif /* latomic_sub_64 */
  295. /* latomic_and */
  296. #ifndef latomic_and_32
  297. void
  298. latomic_and_32(union atomic_ptr_32 ptr, union atomic_val_32 val, int memorder)
  299. {
  300. (void)memorder;
  301. latomic_fetch_and_n(ptr.ui_ptr, val.ui);
  302. }
  303. #endif /* latomic_and_32 */
  304. #ifndef latomic_and_64
  305. void
  306. latomic_and_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  307. {
  308. (void)memorder;
  309. latomic_fetch_and_n(ptr.ull_ptr, val.ull);
  310. }
  311. #endif /* latomic_and_64 */
  312. /* latomic_or */
  313. #ifndef latomic_or_32
  314. void
  315. latomic_or_32(union atomic_ptr_32 ptr, union atomic_val_32 val, int memorder)
  316. {
  317. (void)memorder;
  318. latomic_fetch_or_n(ptr.ui_ptr, val.ui);
  319. }
  320. #endif /* latomic_or_32 */
  321. #ifndef latomic_or_64
  322. void
  323. latomic_or_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  324. {
  325. (void)memorder;
  326. latomic_fetch_or_n(ptr.ull_ptr, val.ull);
  327. }
  328. #endif /* latomic_or_64 */
  329. /* latomic_xor */
  330. #ifndef latomic_xor_32
  331. void
  332. latomic_xor_32(union atomic_ptr_32 ptr, union atomic_val_32 val, int memorder)
  333. {
  334. (void)memorder;
  335. latomic_fetch_xor_n(ptr.ui_ptr, val.ui);
  336. }
  337. #endif /* latomic_xor_32 */
  338. #ifndef latomic_xor_64
  339. void
  340. latomic_xor_64(union atomic_ptr_64 ptr, union atomic_val_64 val, int memorder)
  341. {
  342. (void)memorder;
  343. latomic_fetch_xor_n(ptr.ull_ptr, val.ull);
  344. }
  345. #endif /* latomic_xor_64 */