0030-aarch64_arm64_qatomic_support.patch 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. From 294010b562c9846bb2bc4ee9c63ff78adc7c1f4f Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Lisandro=20Dami=C3=A1n=20Nicanor=20P=C3=A9rez=20Meyer?=
  3. <perezmeyer@gmail.com>
  4. Date: Sat, 15 Mar 2014 15:40:49 -0300
  5. Subject: [PATCH] Add qatomic support for AArch64 (aka arm64).
  6. Patch by Mark Salter <msalter@redhat.com>
  7. licensed under BSD:
  8. <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=735488#195>
  9. This patch is known to not be the most correct way
  10. to implement them, as it seems to be possible to do it in a faster way,
  11. but should work non the less until we can provide something better.
  12. Change-Id: Ib392b27dc54691fd4c2ea9896240ad71fb8128cc
  13. Upstream-Status: Pending
  14. Signed-off-by: Kai Kang <kai.kang@windriver.com>
  15. ---
  16. src/corelib/arch/aarch64/arch.pri | 4 +
  17. src/corelib/arch/aarch64/qatomic_aarch64.cpp | 70 ++++++
  18. src/corelib/arch/arch.pri | 4 +-
  19. src/corelib/arch/qatomic_aarch64.h | 335 +++++++++++++++++++++++++++
  20. src/corelib/arch/qatomic_arch.h | 2 +
  21. 5 files changed, 414 insertions(+), 1 deletion(-)
  22. create mode 100644 src/corelib/arch/aarch64/arch.pri
  23. create mode 100644 src/corelib/arch/aarch64/qatomic_aarch64.cpp
  24. create mode 100644 src/corelib/arch/qatomic_aarch64.h
  25. diff --git a/src/corelib/arch/aarch64/arch.pri b/src/corelib/arch/aarch64/arch.pri
  26. new file mode 100644
  27. index 0000000..63523d9
  28. --- /dev/null
  29. +++ b/src/corelib/arch/aarch64/arch.pri
  30. @@ -0,0 +1,4 @@
  31. +#
  32. +# AArch64 architecture
  33. +#
  34. +SOURCES += $$QT_ARCH_CPP/qatomic_aarch64.cpp
  35. diff --git a/src/corelib/arch/aarch64/qatomic_aarch64.cpp b/src/corelib/arch/aarch64/qatomic_aarch64.cpp
  36. new file mode 100644
  37. index 0000000..fc851b9
  38. --- /dev/null
  39. +++ b/src/corelib/arch/aarch64/qatomic_aarch64.cpp
  40. @@ -0,0 +1,70 @@
  41. +/****************************************************************************
  42. +**
  43. +** Copyright (C) 2012, 2013 Digia Plc and/or its subsidiary(-ies).
  44. +** Contact: http://www.qt-project.org/legal
  45. +**
  46. +** This file is part of the QtCore module of the Qt Toolkit.
  47. +**
  48. +** $QT_BEGIN_LICENSE:LGPL$
  49. +** Commercial License Usage
  50. +** Licensees holding valid commercial Qt licenses may use this file in
  51. +** accordance with the commercial license agreement provided with the
  52. +** Software or, alternatively, in accordance with the terms contained in
  53. +** a written agreement between you and Digia. For licensing terms and
  54. +** conditions see http://qt.digia.com/licensing. For further information
  55. +** use the contact form at http://qt.digia.com/contact-us.
  56. +**
  57. +** GNU Lesser General Public License Usage
  58. +** Alternatively, this file may be used under the terms of the GNU Lesser
  59. +** General Public License version 2.1 as published by the Free Software
  60. +** Foundation and appearing in the file LICENSE.LGPL included in the
  61. +** packaging of this file. Please review the following information to
  62. +** ensure the GNU Lesser General Public License version 2.1 requirements
  63. +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  64. +**
  65. +** In addition, as a special exception, Digia gives you certain additional
  66. +** rights. These rights are described in the Digia Qt LGPL Exception
  67. +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  68. +**
  69. +** GNU General Public License Usage
  70. +** Alternatively, this file may be used under the terms of the GNU
  71. +** General Public License version 3.0 as published by the Free Software
  72. +** Foundation and appearing in the file LICENSE.GPL included in the
  73. +** packaging of this file. Please review the following information to
  74. +** ensure the GNU General Public License version 3.0 requirements will be
  75. +** met: http://www.gnu.org/copyleft/gpl.html.
  76. +**
  77. +**
  78. +** $QT_END_LICENSE$
  79. +**
  80. +****************************************************************************/
  81. +
  82. +#include <QtCore/qglobal.h>
  83. +
  84. +#include <unistd.h>
  85. +#ifdef _POSIX_PRIORITY_SCHEDULING
  86. +# include <sched.h>
  87. +#endif
  88. +#include <time.h>
  89. +
  90. +QT_BEGIN_NAMESPACE
  91. +
  92. +QT_USE_NAMESPACE
  93. +
  94. +Q_CORE_EXPORT void qt_atomic_yield(int *count)
  95. +{
  96. +#ifdef _POSIX_PRIORITY_SCHEDULING
  97. + if ((*count)++ < 50) {
  98. + sched_yield();
  99. + } else
  100. +#endif
  101. + {
  102. + struct timespec tm;
  103. + tm.tv_sec = 0;
  104. + tm.tv_nsec = 2000001;
  105. + nanosleep(&tm, NULL);
  106. + *count = 0;
  107. + }
  108. +}
  109. +
  110. +QT_END_NAMESPACE
  111. diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri
  112. index cd23e5e..f50fca7 100644
  113. --- a/src/corelib/arch/arch.pri
  114. +++ b/src/corelib/arch/arch.pri
  115. @@ -31,7 +31,9 @@ integrity:HEADERS += arch/qatomic_integrity.h
  116. arch/qatomic_s390.h \
  117. arch/qatomic_x86_64.h \
  118. arch/qatomic_sh.h \
  119. - arch/qatomic_sh4a.h
  120. + arch/qatomic_sh4a.h \
  121. + arch/qatomic_aarch64.h \
  122. +
  123. QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH
  124. DEPENDPATH += $$QT_ARCH_CPP
  125. diff --git a/src/corelib/arch/qatomic_aarch64.h b/src/corelib/arch/qatomic_aarch64.h
  126. new file mode 100644
  127. index 0000000..de61ca8
  128. --- /dev/null
  129. +++ b/src/corelib/arch/qatomic_aarch64.h
  130. @@ -0,0 +1,335 @@
  131. +/****************************************************************************
  132. +**
  133. +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
  134. +** Contact: http://www.qt-project.org/legal
  135. +**
  136. +** This file is part of the QtCore module of the Qt Toolkit.
  137. +**
  138. +** $QT_BEGIN_LICENSE:LGPL$
  139. +** Commercial License Usage
  140. +** Licensees holding valid commercial Qt licenses may use this file in
  141. +** accordance with the commercial license agreement provided with the
  142. +** Software or, alternatively, in accordance with the terms contained in
  143. +** a written agreement between you and Digia. For licensing terms and
  144. +** conditions see http://qt.digia.com/licensing. For further information
  145. +** use the contact form at http://qt.digia.com/contact-us.
  146. +**
  147. +** GNU Lesser General Public License Usage
  148. +** Alternatively, this file may be used under the terms of the GNU Lesser
  149. +** General Public License version 2.1 as published by the Free Software
  150. +** Foundation and appearing in the file LICENSE.LGPL included in the
  151. +** packaging of this file. Please review the following information to
  152. +** ensure the GNU Lesser General Public License version 2.1 requirements
  153. +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  154. +**
  155. +** In addition, as a special exception, Digia gives you certain additional
  156. +** rights. These rights are described in the Digia Qt LGPL Exception
  157. +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  158. +**
  159. +** GNU General Public License Usage
  160. +** Alternatively, this file may be used under the terms of the GNU
  161. +** General Public License version 3.0 as published by the Free Software
  162. +** Foundation and appearing in the file LICENSE.GPL included in the
  163. +** packaging of this file. Please review the following information to
  164. +** ensure the GNU General Public License version 3.0 requirements will be
  165. +** met: http://www.gnu.org/copyleft/gpl.html.
  166. +**
  167. +**
  168. +** $QT_END_LICENSE$
  169. +**
  170. +****************************************************************************/
  171. +
  172. +#ifndef QATOMIC_AARCH64_H
  173. +#define QATOMIC_AARCH64_H
  174. +
  175. +QT_BEGIN_HEADER
  176. +
  177. +QT_BEGIN_NAMESPACE
  178. +
  179. +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
  180. +
  181. +inline bool QBasicAtomicInt::isReferenceCountingNative()
  182. +{ return true; }
  183. +inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
  184. +{ return false; }
  185. +
  186. +#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
  187. +
  188. +inline bool QBasicAtomicInt::isTestAndSetNative()
  189. +{ return true; }
  190. +inline bool QBasicAtomicInt::isTestAndSetWaitFree()
  191. +{ return false; }
  192. +
  193. +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  194. +
  195. +inline bool QBasicAtomicInt::isFetchAndStoreNative()
  196. +{ return true; }
  197. +inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
  198. +{ return false; }
  199. +
  200. +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  201. +
  202. +inline bool QBasicAtomicInt::isFetchAndAddNative()
  203. +{ return true; }
  204. +inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
  205. +{ return false; }
  206. +
  207. +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
  208. +
  209. +template <typename T>
  210. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
  211. +{ return true; }
  212. +template <typename T>
  213. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
  214. +{ return false; }
  215. +
  216. +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  217. +
  218. +template <typename T>
  219. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
  220. +{ return true; }
  221. +template <typename T>
  222. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
  223. +{ return false; }
  224. +
  225. +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  226. +
  227. +template <typename T>
  228. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
  229. +{ return true; }
  230. +template <typename T>
  231. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
  232. +{ return false; }
  233. +
  234. +#ifndef Q_DATA_MEMORY_BARRIER
  235. +# define Q_DATA_MEMORY_BARRIER asm volatile("dmb sy\n":::"memory")
  236. +#endif
  237. +#ifndef Q_COMPILER_MEMORY_BARRIER
  238. +# define Q_COMPILER_MEMORY_BARRIER asm volatile("":::"memory")
  239. +#endif
  240. +
  241. +inline bool QBasicAtomicInt::ref()
  242. +{
  243. + int newValue;
  244. +
  245. + Q_COMPILER_MEMORY_BARRIER;
  246. + newValue = __atomic_add_fetch(&_q_value, 1, __ATOMIC_ACQ_REL);
  247. + Q_COMPILER_MEMORY_BARRIER;
  248. +
  249. + return newValue != 0;
  250. +}
  251. +
  252. +inline bool QBasicAtomicInt::deref()
  253. +{
  254. + int newValue;
  255. +
  256. + Q_COMPILER_MEMORY_BARRIER;
  257. + newValue = __atomic_sub_fetch(&_q_value, 1, __ATOMIC_ACQ_REL);
  258. + Q_COMPILER_MEMORY_BARRIER;
  259. +
  260. + return newValue != 0;
  261. +}
  262. +
  263. +inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
  264. +{
  265. + bool val;
  266. +
  267. + Q_COMPILER_MEMORY_BARRIER;
  268. + val = __atomic_compare_exchange_n (&_q_value, &expectedValue, newValue,
  269. + false, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
  270. + Q_COMPILER_MEMORY_BARRIER;
  271. + return val;
  272. +}
  273. +
  274. +inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
  275. +{
  276. + int val;
  277. + Q_COMPILER_MEMORY_BARRIER;
  278. + val = __atomic_exchange_n(&_q_value, newValue, __ATOMIC_RELAXED);
  279. + Q_COMPILER_MEMORY_BARRIER;
  280. + return val;
  281. +}
  282. +
  283. +inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
  284. +{
  285. + int val;
  286. + Q_COMPILER_MEMORY_BARRIER;
  287. + val = __atomic_fetch_add(&_q_value, valueToAdd, __ATOMIC_RELAXED);
  288. + Q_COMPILER_MEMORY_BARRIER;
  289. + return val;
  290. +}
  291. +
  292. +template <typename T>
  293. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
  294. +{
  295. + bool val;
  296. + Q_COMPILER_MEMORY_BARRIER;
  297. + val = __atomic_compare_exchange_n (&_q_value, &expectedValue, newValue,
  298. + false, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
  299. + Q_COMPILER_MEMORY_BARRIER;
  300. + return val;
  301. +}
  302. +
  303. +template <typename T>
  304. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
  305. +{
  306. + T *val;
  307. + Q_COMPILER_MEMORY_BARRIER;
  308. + val = __atomic_exchange_n(&_q_value, newValue, __ATOMIC_RELAXED);
  309. + Q_COMPILER_MEMORY_BARRIER;
  310. + return val;
  311. +}
  312. +
  313. +template <typename T>
  314. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
  315. +{
  316. + T *val;
  317. + Q_COMPILER_MEMORY_BARRIER;
  318. + val = __atomic_fetch_add(&_q_value, valueToAdd, __ATOMIC_RELAXED);
  319. + Q_COMPILER_MEMORY_BARRIER;
  320. + return val;
  321. +}
  322. +
  323. +inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  324. +{
  325. + bool returnValue = testAndSetRelaxed(expectedValue, newValue);
  326. + Q_DATA_MEMORY_BARRIER;
  327. + return returnValue;
  328. +}
  329. +
  330. +inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  331. +{
  332. + Q_DATA_MEMORY_BARRIER;
  333. + return testAndSetRelaxed(expectedValue, newValue);
  334. +}
  335. +
  336. +inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
  337. +{
  338. + Q_DATA_MEMORY_BARRIER;
  339. + bool returnValue = testAndSetRelaxed(expectedValue, newValue);
  340. + Q_COMPILER_MEMORY_BARRIER;
  341. + return returnValue;
  342. +}
  343. +
  344. +inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
  345. +{
  346. + int returnValue = fetchAndStoreRelaxed(newValue);
  347. + Q_DATA_MEMORY_BARRIER;
  348. + return returnValue;
  349. +}
  350. +
  351. +inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
  352. +{
  353. + Q_DATA_MEMORY_BARRIER;
  354. + return fetchAndStoreRelaxed(newValue);
  355. +}
  356. +
  357. +inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
  358. +{
  359. + Q_DATA_MEMORY_BARRIER;
  360. + int returnValue = fetchAndStoreRelaxed(newValue);
  361. + Q_COMPILER_MEMORY_BARRIER;
  362. + return returnValue;
  363. +}
  364. +
  365. +inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
  366. +{
  367. + int returnValue = fetchAndAddRelaxed(valueToAdd);
  368. + Q_DATA_MEMORY_BARRIER;
  369. + return returnValue;
  370. +}
  371. +
  372. +inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
  373. +{
  374. + Q_DATA_MEMORY_BARRIER;
  375. + return fetchAndAddRelaxed(valueToAdd);
  376. +}
  377. +
  378. +inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
  379. +{
  380. + Q_DATA_MEMORY_BARRIER;
  381. + int returnValue = fetchAndAddRelaxed(valueToAdd);
  382. + Q_COMPILER_MEMORY_BARRIER;
  383. + return returnValue;
  384. +}
  385. +
  386. +template <typename T>
  387. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  388. +{
  389. + bool returnValue = testAndSetRelaxed(expectedValue, newValue);
  390. + Q_DATA_MEMORY_BARRIER;
  391. + return returnValue;
  392. +}
  393. +
  394. +template <typename T>
  395. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  396. +{
  397. + Q_DATA_MEMORY_BARRIER;
  398. + return testAndSetRelaxed(expectedValue, newValue);
  399. +}
  400. +
  401. +template <typename T>
  402. +Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  403. +{
  404. + Q_DATA_MEMORY_BARRIER;
  405. + bool returnValue = testAndSetAcquire(expectedValue, newValue);
  406. + Q_COMPILER_MEMORY_BARRIER;
  407. + return returnValue;
  408. +}
  409. +
  410. +template <typename T>
  411. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
  412. +{
  413. + T *returnValue = fetchAndStoreRelaxed(newValue);
  414. + Q_DATA_MEMORY_BARRIER;
  415. + return returnValue;
  416. +}
  417. +
  418. +template <typename T>
  419. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
  420. +{
  421. + Q_DATA_MEMORY_BARRIER;
  422. + return fetchAndStoreRelaxed(newValue);
  423. +}
  424. +
  425. +template <typename T>
  426. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
  427. +{
  428. + Q_DATA_MEMORY_BARRIER;
  429. + T *returnValue = fetchAndStoreRelaxed(newValue);
  430. + Q_COMPILER_MEMORY_BARRIER;
  431. + return returnValue;
  432. +}
  433. +
  434. +template <typename T>
  435. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
  436. +{
  437. + T *returnValue = fetchAndAddRelaxed(valueToAdd);
  438. + Q_DATA_MEMORY_BARRIER;
  439. + return returnValue;
  440. +}
  441. +
  442. +template <typename T>
  443. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
  444. +{
  445. + Q_DATA_MEMORY_BARRIER;
  446. + return fetchAndAddRelaxed(valueToAdd);
  447. +}
  448. +
  449. +template <typename T>
  450. +Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
  451. +{
  452. + Q_DATA_MEMORY_BARRIER;
  453. + T *returnValue = fetchAndAddRelaxed(valueToAdd);
  454. + Q_COMPILER_MEMORY_BARRIER;
  455. + return returnValue;
  456. +}
  457. +
  458. +#undef Q_DATA_MEMORY_BARRIER
  459. +#undef Q_COMPILER_MEMORY_BARRIER
  460. +
  461. +QT_END_NAMESPACE
  462. +
  463. +QT_END_HEADER
  464. +
  465. +#endif // QATOMIC_AARCH64_H
  466. diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h
  467. index 141726c..3e96926 100644
  468. --- a/src/corelib/arch/qatomic_arch.h
  469. +++ b/src/corelib/arch/qatomic_arch.h
  470. @@ -94,6 +94,8 @@ QT_BEGIN_HEADER
  471. # include "QtCore/qatomic_sh4a.h"
  472. #elif defined(QT_ARCH_NACL)
  473. # include "QtCore/qatomic_generic.h"
  474. +#elif defined(QT_ARCH_AARCH64)
  475. +# include "QtCore/qatomic_aarch64.h"
  476. #else
  477. # error "Qt has not been ported to this architecture"
  478. #endif
  479. --
  480. 2.1.0