This is an automated email from the ASF dual-hosted git repository.
oknet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 95a535b Fix FREELIST macros for AArch64
95a535b is described below
commit 95a535b6b8bf459dfe95e3bfebc4cc8896ff42a1
Author: Oknet Xu <[email protected]>
AuthorDate: Thu May 9 17:07:04 2019 +0800
Fix FREELIST macros for AArch64
This revert the commit 8563409 and fix a bug of FREELIST_VERSION(_x).
The layout of FREELIST_POINTER:
- 0 ~ 47 bit : 48 bits, Virtual Address
(1+47 bits for AMD64 and 48 bits for AArch64)
- 48 ~ 62 bit : 15 bits, Freelist Version
- 63 bit : 1 bits, The type of Virtual Address
(0 = user space, 1 = kernel space)
The valid Virtual Address range for AMD64 is:
- 0000000000000000 ~ 00007fffffffffff for user space
- ffff800000000000 ~ ffffffffffffffff for kernel space
The 47th bit can be used to indicate the type of VA.
And the one (64k page size) of the valid VA range for AArch64 is:
- 0000000000000000 ~ 0000ffffffffffff for user space
- ffff000000000000 ~ ffffffffffffffff for kernel space
We can see that the actual length of the Virtual Address is 48 bits on
AArch64 and 47 bits on AMD64. Therefore, we cannot use the 47th bit to
indicate the type of Virtual Address, which requires an extra bit.
The highest bit would be a good choice because we have done that before.
---
include/tscore/ink_queue.h | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/include/tscore/ink_queue.h b/include/tscore/ink_queue.h
index bc8a71e..5c6cc74 100644
--- a/include/tscore/ink_queue.h
+++ b/include/tscore/ink_queue.h
@@ -137,10 +137,29 @@ union head_p {
(_x).s.pointer = _p; \
(_x).s.version = _v
#elif defined(__x86_64__) || defined(__ia64__) || defined(__powerpc64__) ||
defined(__aarch64__) || defined(__mips64)
+/* Layout of FREELIST_POINTER
+ *
+ * 0 ~ 47 bits : 48 bits, Virtual Address (47 bits for AMD64 and 48 bits for
AArch64)
+ * 48 ~ 62 bits : 15 bits, Freelist Version
+ * 63 bits : 1 bits, The type of Virtual Address (0 = user space, 1 =
kernel space)
+ */
+/* Detect which shift is implemented by the simple expression ((~0 >> 1) < 0):
+ *
+ * If the shift is `logical’ the highest order bit of the left side of the
comparison is 0 so the result is positive.
+ * If the shift is `arithmetic’ the highest order bit of the left side is 1 so
the result is negative.
+ */
+#if ((~0 >> 1) < 0)
+/* the shift is `arithmetic' */
+#define FREELIST_POINTER(_x) \
+ ((void *)((((intptr_t)(_x).data) & 0x0000FFFFFFFFFFFFLL) |
((((intptr_t)(_x).data) >> 63) << 48))) // sign extend
+#else
+/* the shift is `logical' */
#define FREELIST_POINTER(_x) \
- ((void *)(((((intptr_t)(_x).data) << 16) >> 16) |
(((~((((intptr_t)(_x).data) << 16 >> 63) - 1)) >> 48) << 48))) // sign extend
-#define FREELIST_VERSION(_x) (((intptr_t)(_x).data) >> 48)
-#define SET_FREELIST_POINTER_VERSION(_x, _p, _v) (_x).data =
((((intptr_t)(_p)) & 0x0000FFFFFFFFFFFFULL) | (((_v)&0xFFFFULL) << 48))
+ ((void *)((((intptr_t)(_x).data) & 0x0000FFFFFFFFFFFFLL) |
(((~((((intptr_t)(_x).data) >> 63) - 1)) >> 48) << 48)))
+#endif
+
+#define FREELIST_VERSION(_x) ((((intptr_t)(_x).data) & 0x7FFF000000000000LL)
>> 48)
+#define SET_FREELIST_POINTER_VERSION(_x, _p, _v) (_x).data =
((((intptr_t)(_p)) & 0x8000FFFFFFFFFFFFLL) | (((_v)&0x7FFFLL) << 48))
#else
#error "unsupported processor"
#endif