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);