You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by br...@apache.org on 2013/03/12 00:15:22 UTC
git commit: TS-1742: Freelists to use 64bit version w/ Double Word
Compare and Swap
Updated Branches:
refs/heads/master bd5816b4b -> 9ddf58ba2
TS-1742: Freelists to use 64bit version w/ Double Word Compare and Swap
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/9ddf58ba
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/9ddf58ba
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/9ddf58ba
Branch: refs/heads/master
Commit: 9ddf58ba29288b5315c2effe62de2d0c22d7b1d3
Parents: bd5816b
Author: Brian Geffon <br...@apache.org>
Authored: Mon Mar 11 16:15:11 2013 -0700
Committer: Brian Geffon <br...@apache.org>
Committed: Mon Mar 11 16:15:11 2013 -0700
----------------------------------------------------------------------
CHANGES | 2 +
configure.ac | 26 +++++++++++++++++++
lib/ts/ink_config.h.in | 1 +
lib/ts/ink_queue.cc | 52 ++++++++++++++++++++++++++++----------
lib/ts/ink_queue.h | 29 ++++++++++++++++++---
proxy/logging/LogObject.cc | 24 +++++++++++++----
6 files changed, 110 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9ddf58ba/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 68485be..35cc93d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,7 @@
-*- coding: utf-8 -*-
Changes with Apache Traffic Server 3.3.2
+
+ *) [TS-1742] Freelists to use 64bit version w/ Double Word Compare and Swap
*) [TS-1744] ats run with 1 less event thread then it is supposed to, for
both auto and manual thread config
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9ddf58ba/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 2bef703..86476e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1105,6 +1105,32 @@ AC_MSG_RESULT([$msg])
AC_SUBST(need_union_semun)
+
+
+has_128bit_cas=0
+__saved_CFLAGS="${CFLAGS}"
+CFLAGS=-mcx16
+AC_MSG_CHECKING(for 128bit CAS support)
+AC_LANG_PUSH([C])
+AC_RUN_IFELSE(
+ [
+ int main() {
+ __int128_t x = 0;
+ __sync_bool_compare_and_swap(&x,0,10);
+ return 0;
+ }
+ ],
+ [ has_128bit_cas="1" ]
+ AC_MSG_RESULT(yes)
+ CXXFLAGS+=" -mcx16"
+ ,
+ [ has_128bit_cas="0" ]
+ AC_MSG_RESULT(no)
+ )
+AC_LANG_POP
+CFLAGS="${__saved_CFLAGS}"
+AC_SUBST([has_128bit_cas])
+
# Check for POSIX capabilities library.
# If we don't find it, disable checking for header.
use_posix_cap=0
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9ddf58ba/lib/ts/ink_config.h.in
----------------------------------------------------------------------
diff --git a/lib/ts/ink_config.h.in b/lib/ts/ink_config.h.in
index 274308c..6b0525c 100644
--- a/lib/ts/ink_config.h.in
+++ b/lib/ts/ink_config.h.in
@@ -129,6 +129,7 @@
#define NEED_UNION_SEMUN @need_union_semun@
#define SIZEOF_VOID_POINTER @ac_cv_sizeof_voidp@
#define TS_IP_TRANSPARENT @ip_transparent@
+#define TS_HAS_128BIT_CAS @has_128bit_cas@
/* API */
#define TS_IS_MICRO_BUILD @is_micro_build@
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9ddf58ba/lib/ts/ink_queue.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_queue.cc b/lib/ts/ink_queue.cc
index d62bd43..f467a63 100644
--- a/lib/ts/ink_queue.cc
+++ b/lib/ts/ink_queue.cc
@@ -132,7 +132,6 @@ int fake_global_for_ink_queue = 0;
#endif
int fastmemtotal = 0;
-
void *
ink_freelist_new(InkFreeList * f)
{
@@ -145,7 +144,7 @@ ink_freelist_new(InkFreeList * f)
int result = 0;
do {
- INK_QUEUE_LD64(item, f->head);
+ INK_QUEUE_LD(item, f->head);
if (TO_PTR(FREELIST_POINTER(item)) == NULL) {
uint32_t type_size = f->type_size;
uint32_t i;
@@ -202,7 +201,11 @@ ink_freelist_new(InkFreeList * f)
} else {
SET_FREELIST_POINTER_VERSION(next, *ADDRESS_OF_NEXT(TO_PTR(FREELIST_POINTER(item)), 0),
FREELIST_VERSION(item) + 1);
- result = ink_atomic_cas((int64_t *) & f->head.data, item.data, next.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*)&f->head.data, item.data, next.data);
+#else
+ result = ink_atomic_cas((int64_t *) & f->head.data, item.data, next.data);
+#endif
#ifdef SANITY
if (result) {
@@ -263,7 +266,7 @@ ink_freelist_free(InkFreeList * f, void *item)
result = 0;
do {
- INK_QUEUE_LD64(h, f->head);
+ INK_QUEUE_LD(h, f->head);
#ifdef SANITY
if (TO_PTR(FREELIST_POINTER(h)) == item)
ink_fatal(1, "ink_freelist_free: trying to free item twice");
@@ -275,7 +278,12 @@ ink_freelist_free(InkFreeList * f, void *item)
*adr_of_next = FREELIST_POINTER(h);
SET_FREELIST_POINTER_VERSION(item_pair, FROM_PTR(item), FREELIST_VERSION(h));
INK_MEMORY_BARRIER;
- result = ink_atomic_cas((int64_t *) & f->head, h.data, item_pair.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) & f->head, h.data, item_pair.data);
+#else
+ result = ink_atomic_cas((int64_t *) & f->head, h.data, item_pair.data);
+#endif
+
}
while (result == 0);
@@ -381,13 +389,17 @@ ink_atomiclist_pop(InkAtomicList * l)
head_p next;
int result = 0;
do {
- INK_QUEUE_LD64(item, l->head);
+ INK_QUEUE_LD(item, l->head);
if (TO_PTR(FREELIST_POINTER(item)) == NULL)
return NULL;
SET_FREELIST_POINTER_VERSION(next, *ADDRESS_OF_NEXT(TO_PTR(FREELIST_POINTER(item)), l->offset),
FREELIST_VERSION(item) + 1);
#if !defined(INK_USE_MUTEX_FOR_ATOMICLISTS)
- result = ink_atomic_cas((int64_t *) & l->head.data, item.data, next.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) & l->head.data, item.data, next.data);
+#else
+ result = ink_atomic_cas((int64_t *) & l->head.data, item.data, next.data);
+#endif
#else
l->head.data = next.data;
result = 1;
@@ -414,12 +426,16 @@ ink_atomiclist_popall(InkAtomicList * l)
head_p next;
int result = 0;
do {
- INK_QUEUE_LD64(item, l->head);
+ INK_QUEUE_LD(item, l->head);
if (TO_PTR(FREELIST_POINTER(item)) == NULL)
return NULL;
SET_FREELIST_POINTER_VERSION(next, FROM_PTR(NULL), FREELIST_VERSION(item) + 1);
#if !defined(INK_USE_MUTEX_FOR_ATOMICLISTS)
- result = ink_atomic_cas((int64_t *) & l->head.data, item.data, next.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) & l->head.data, item.data, next.data);
+#else
+ result = ink_atomic_cas((int64_t *) & l->head.data, item.data, next.data);
+#endif
#else
l->head.data = next.data;
result = 1;
@@ -454,14 +470,18 @@ ink_atomiclist_push(InkAtomicList * l, void *item)
int result = 0;
volatile void *h = NULL;
do {
- INK_QUEUE_LD64(head, l->head);
+ INK_QUEUE_LD(head, l->head);
h = FREELIST_POINTER(head);
*adr_of_next = h;
ink_assert(item != TO_PTR(h));
SET_FREELIST_POINTER_VERSION(item_pair, FROM_PTR(item), FREELIST_VERSION(head));
INK_MEMORY_BARRIER;
#if !defined(INK_USE_MUTEX_FOR_ATOMICLISTS)
- result = ink_atomic_cas((int64_t *) & l->head, head.data, item_pair.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) & l->head, head.data, item_pair.data);
+#else
+ result = ink_atomic_cas((int64_t *) & l->head, head.data, item_pair.data);
+#endif
#else
l->head.data = item_pair.data;
result = 1;
@@ -490,12 +510,16 @@ ink_atomiclist_remove(InkAtomicList * l, void *item)
/*
* first, try to pop it if it is first
*/
- INK_QUEUE_LD64(head, l->head);
+ INK_QUEUE_LD(head, l->head);
while (TO_PTR(FREELIST_POINTER(head)) == item) {
head_p next;
SET_FREELIST_POINTER_VERSION(next, item_next, FREELIST_VERSION(head) + 1);
#if !defined(INK_USE_MUTEX_FOR_ATOMICLISTS)
- result = ink_atomic_cas((int64_t *) & l->head.data, head.data, next.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) & l->head.data, head.data, next.data);
+#else
+ result = ink_atomic_cas((int64_t *) & l->head.data, head.data, next.data);
+#endif
#else
l->head.data = next.data;
result = 1;
@@ -504,7 +528,7 @@ ink_atomiclist_remove(InkAtomicList * l, void *item)
*addr_next = NULL;
return item;
}
- INK_QUEUE_LD64(head, l->head);
+ INK_QUEUE_LD(head, l->head);
}
/*
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9ddf58ba/lib/ts/ink_queue.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_queue.h b/lib/ts/ink_queue.h
index af04656..6ac9945 100644
--- a/lib/ts/ink_queue.h
+++ b/lib/ts/ink_queue.h
@@ -71,20 +71,36 @@ extern "C"
#define INK_QUEUE_LD64(dst,src) (ink_queue_load_64((void *)&(dst), (void *)&(src)))
#endif
+#if TS_HAS_128BIT_CAS
+#define INK_QUEUE_LD(dst,src) *((__int128_t*)&(dst)) = *((__int128_t*)&(src))
+#else
+#define INK_QUEUE_LD(dst,src) INK_QUEUE_LD64(dst,src)
+#endif
+
/*
* Generic Free List Manager
*/
-
+ // Warning: head_p is read and written in multiple threads without a
+ // lock, use INK_QUEUE_LD to read safely.
typedef union
{
#if (defined(__i386__) || defined(__arm__)) && (SIZEOF_VOIDP == 4)
struct
{
- volatile void *pointer;
- volatile int32_t version;
+ void *pointer;
+ int32_t version;
+ } s;
+ int64_t data;
+#elif TS_HAS_128BIT_CAS
+ struct
+ {
+ void *pointer;
+ int64_t version;
} s;
+ __int128_t data;
+#else
+ int64_t data;
#endif
- volatile int64_t data;
} head_p;
/*
@@ -112,6 +128,11 @@ extern "C"
#define FREELIST_VERSION(_x) (_x).s.version
#define SET_FREELIST_POINTER_VERSION(_x,_p,_v) \
(_x).s.pointer = _p; (_x).s.version = _v
+#elif TS_HAS_128BIT_CAS
+#define FREELIST_POINTER(_x) (_x).s.pointer
+#define FREELIST_VERSION(_x) (_x).s.version
+#define SET_FREELIST_POINTER_VERSION(_x,_p,_v) \
+(_x).s.pointer = _p; (_x).s.version = _v
#elif defined(__x86_64__) || defined(__ia64__)
#define FREELIST_POINTER(_x) ((void*)(((((intptr_t)(_x).data)<<16)>>16) | \
(((~((((intptr_t)(_x).data)<<16>>63)-1))>>48)<<48))) // sign extend
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9ddf58ba/proxy/logging/LogObject.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/LogObject.cc b/proxy/logging/LogObject.cc
index e2e6aec..7089725 100644
--- a/proxy/logging/LogObject.cc
+++ b/proxy/logging/LogObject.cc
@@ -415,10 +415,14 @@ LogObject::_checkout_write(size_t * write_offset, size_t bytes_needed) {
head_p h;
int result = 0;
do {
- INK_QUEUE_LD64(h, m_log_buffer);
+ INK_QUEUE_LD(h, m_log_buffer);
head_p new_h;
SET_FREELIST_POINTER_VERSION(new_h, FREELIST_POINTER(h), FREELIST_VERSION(h) + 1);
- result = ink_atomic_cas((int64_t*)&m_log_buffer.data, h.data, new_h.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) &m_log_buffer.data, h.data, new_h.data);
+#else
+ result = ink_atomic_cas((int64_t *) &m_log_buffer.data, h.data, new_h.data);
+#endif
} while (!result);
buffer = (LogBuffer*)FREELIST_POINTER(h);
result_code = buffer->checkout_write(write_offset, bytes_needed);
@@ -440,10 +444,14 @@ LogObject::_checkout_write(size_t * write_offset, size_t bytes_needed) {
INK_WRITE_MEMORY_BARRIER;
head_p old_h;
do {
- INK_QUEUE_LD64(old_h, m_log_buffer);
+ INK_QUEUE_LD(old_h, m_log_buffer);
head_p tmp_h;
SET_FREELIST_POINTER_VERSION(tmp_h, new_buffer, 0);
- result = ink_atomic_cas((int64_t*)&m_log_buffer.data, old_h.data, tmp_h.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) &m_log_buffer.data, old_h.data, tmp_h.data);
+#else
+ result = ink_atomic_cas((int64_t *) &m_log_buffer.data, old_h.data, tmp_h.data);
+#endif
} while (!result);
if (FREELIST_POINTER(old_h) == FREELIST_POINTER(h))
ink_atomic_increment(&buffer->m_references, FREELIST_VERSION(old_h) - 1);
@@ -478,12 +486,16 @@ LogObject::_checkout_write(size_t * write_offset, size_t bytes_needed) {
if (!decremented) {
head_p old_h;
do {
- INK_QUEUE_LD64(old_h, m_log_buffer);
+ INK_QUEUE_LD(old_h, m_log_buffer);
if (FREELIST_POINTER(old_h) != FREELIST_POINTER(h))
break;
head_p tmp_h;
SET_FREELIST_POINTER_VERSION(tmp_h, FREELIST_POINTER(h), FREELIST_VERSION(old_h) - 1);
- result = ink_atomic_cas((int64_t*)&m_log_buffer.data, old_h.data, tmp_h.data);
+#if TS_HAS_128BIT_CAS
+ result = ink_atomic_cas((__int128_t*) &m_log_buffer.data, old_h.data, tmp_h.data);
+#else
+ result = ink_atomic_cas((int64_t *) &m_log_buffer.data, old_h.data, tmp_h.data);
+#endif
} while (!result);
if (FREELIST_POINTER(old_h) != FREELIST_POINTER(h))
ink_atomic_increment(&buffer->m_references, -1);