trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bri...@apache.org
Subject [1/2] trafficserver git commit: TS-3178: ProxyAllocator improvements
Date Tue, 11 Nov 2014 19:12:52 GMT
Repository: trafficserver
Updated Branches:
  refs/heads/master 0a8e3c965 -> b71a24e8b


TS-3178: ProxyAllocator improvements


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/0cdc3cb4
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/0cdc3cb4
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/0cdc3cb4

Branch: refs/heads/master
Commit: 0cdc3cb43e67f69041259a28bd3f592e5893da0e
Parents: 0a8e3c9
Author: Cynthia Gu <czhenggu@linkedin.com>
Authored: Tue Nov 11 11:12:06 2014 -0800
Committer: Brian Geffon <briang@apache.org>
Committed: Tue Nov 11 11:12:06 2014 -0800

----------------------------------------------------------------------
 iocore/eventsystem/EventSystem.cc     |  3 +-
 iocore/eventsystem/I_ProxyAllocator.h | 35 ++++++++++++-----
 iocore/eventsystem/ProxyAllocator.cc  | 29 ++++++++++----
 lib/ts/Allocator.h                    | 34 ++++++++++++++++
 lib/ts/ink_queue.cc                   | 62 ++++++++++++++++++++++++++++++
 lib/ts/ink_queue.h                    |  1 +
 6 files changed, 146 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0cdc3cb4/iocore/eventsystem/EventSystem.cc
----------------------------------------------------------------------
diff --git a/iocore/eventsystem/EventSystem.cc b/iocore/eventsystem/EventSystem.cc
index be6063a..d572a3e 100644
--- a/iocore/eventsystem/EventSystem.cc
+++ b/iocore/eventsystem/EventSystem.cc
@@ -36,7 +36,8 @@ ink_event_system_init(ModuleVersion v)
   ink_release_assert(!checkModuleVersion(v, EVENT_SYSTEM_MODULE_VERSION));
   int config_max_iobuffer_size = DEFAULT_MAX_BUFFER_SIZE;
 
-  REC_EstablishStaticConfigInt32(thread_freelist_size, "proxy.config.allocator.thread_freelist_size");
+  REC_EstablishStaticConfigInt32(thread_freelist_high_watermark, "proxy.config.allocator.thread_freelist_high_watermark");
+  REC_EstablishStaticConfigInt32(thread_freelist_low_watermark, "proxy.config.allocator.thread_freelist_low_watermark");
   REC_ReadConfigInteger(config_max_iobuffer_size, "proxy.config.io.max_buffer_size");
 
   max_iobuffer_size = buffer_size_to_index(config_max_iobuffer_size, DEFAULT_BUFFER_SIZES
- 1);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0cdc3cb4/iocore/eventsystem/I_ProxyAllocator.h
----------------------------------------------------------------------
diff --git a/iocore/eventsystem/I_ProxyAllocator.h b/iocore/eventsystem/I_ProxyAllocator.h
index 94415e0..59e2d91 100644
--- a/iocore/eventsystem/I_ProxyAllocator.h
+++ b/iocore/eventsystem/I_ProxyAllocator.h
@@ -35,7 +35,8 @@
 
 class EThread;
 
-extern int thread_freelist_size;
+extern int thread_freelist_high_watermark;
+extern int thread_freelist_low_watermark;
 
 struct ProxyAllocator
 {
@@ -51,7 +52,7 @@ template<class C> inline C * thread_alloc(ClassAllocator<C>
&a, ProxyAllocator &
   if (l.freelist) {
     C *v = (C *) l.freelist;
     l.freelist = *(C **) l.freelist;
-    l.allocated--;
+    --(l.allocated);
     *(void **) v = *(void **) &a.proto.typeObject;
     return v;
   }
@@ -67,7 +68,7 @@ template<class C> inline C * thread_alloc_init(ClassAllocator<C>
&a, ProxyAlloca
   if (l.freelist) {
     C *v = (C *) l.freelist;
     l.freelist = *(C **) l.freelist;
-    l.allocated--;
+    --(l.allocated);
     memcpy((void *) v, (void *) &a.proto.typeObject, sizeof(C));
     return v;
   }
@@ -92,13 +93,27 @@ thread_free(Allocator &a, void *p)
 template<class C> inline void
 thread_freeup(ClassAllocator<C> &a, ProxyAllocator & l)
 {
-  while (l.freelist) {
-    C *v = (C *) l.freelist;
-    l.freelist = *(C **) l.freelist;
-    l.allocated--;
-    a.free(v);                  // we could use a bulk free here
+  C *head = (C *) l.freelist;
+  C *tail = (C *) l.freelist;
+  size_t count = 0;
+  while(l.freelist && l.allocated > thread_freelist_low_watermark){
+	  tail = (C *) l.freelist;
+	  l.freelist = *(C **) l.freelist;
+	  --(l.allocated);
+	  ++count;
+#ifdef TS_USE_RECLAIMABLE_FREELIST
+	  a.free(tail);
+#endif
   }
-  ink_assert(!l.allocated);
+#if !defined(TS_USE_RECLAIMABLE_FREELIST)
+  if (unlikely(count == 1)) {
+    a.free(head);
+  } else if (count > 0) {
+    a.free_bulk(head, tail, count);
+  }
+
+  ink_assert(l.allocated >= thread_freelist_low_watermark);
+#endif
 }
 
 void* thread_alloc(Allocator &a, ProxyAllocator &l);
@@ -111,7 +126,7 @@ void thread_freeup(Allocator &a, ProxyAllocator &l);
   *(char **)_p = (char*)_t->_a.freelist;        \
   _t->_a.freelist = _p;                         \
   _t->_a.allocated++;                           \
-  if (_t->_a.allocated > thread_freelist_size)  \
+  if (_t->_a.allocated > thread_freelist_high_watermark)  \
     thread_freeup(::_a, _t->_a);                \
 } while (0)
 #else /* !TS_USE_FREELIST || TS_USE_RECLAIMABLE_FREELIST */

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0cdc3cb4/iocore/eventsystem/ProxyAllocator.cc
----------------------------------------------------------------------
diff --git a/iocore/eventsystem/ProxyAllocator.cc b/iocore/eventsystem/ProxyAllocator.cc
index 327b49b..c843bef 100644
--- a/iocore/eventsystem/ProxyAllocator.cc
+++ b/iocore/eventsystem/ProxyAllocator.cc
@@ -22,7 +22,8 @@
 */
 #include "I_EventSystem.h"
 
-int thread_freelist_size = 512;
+int thread_freelist_high_watermark = 512;
+int thread_freelist_low_watermark = 256;
 
 void*
 thread_alloc(Allocator &a, ProxyAllocator &l)
@@ -31,7 +32,7 @@ thread_alloc(Allocator &a, ProxyAllocator &l)
   if (l.freelist) {
     void *v = (void *) l.freelist;
     l.freelist = *(void **) l.freelist;
-    l.allocated--;
+    --(l.allocated);
     return v;
   }
 #else
@@ -43,11 +44,25 @@ thread_alloc(Allocator &a, ProxyAllocator &l)
 void
 thread_freeup(Allocator &a, ProxyAllocator &l)
 {
-  while (l.freelist) {
-    void *v = (void *) l.freelist;
+  void *head = (void *) l.freelist;
+  void *tail = (void *) l.freelist;
+  size_t count = 0;
+  while(l.freelist && l.allocated > thread_freelist_low_watermark){
+    tail = l.freelist;
     l.freelist = *(void **) l.freelist;
-    l.allocated--;
-    a.free_void(v);                  // we could use a bulk free here
+    --(l.allocated);
+    ++count;
+#ifdef TS_USE_RECLAIMABLE_FREELIST
+    a.free_void(tail);
+#endif
+  }
+#if !defined(TS_USE_RECLAIMABLE_FREELIST)
+  if (unlikely(count == 1)) {
+    a.free_void(head);
+  } else if(count > 0) {
+    a.free_void_bulk(head, tail, count);
   }
-  ink_assert(!l.allocated);
+
+  ink_assert(l.allocated >= thread_freelist_low_watermark);
+#endif
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0cdc3cb4/lib/ts/Allocator.h
----------------------------------------------------------------------
diff --git a/lib/ts/Allocator.h b/lib/ts/Allocator.h
index 710dc68..1e8bba6 100644
--- a/lib/ts/Allocator.h
+++ b/lib/ts/Allocator.h
@@ -68,6 +68,13 @@ public:
     ink_freelist_free(this->fl, ptr);
   }
 
+  /** Deallocate blocks of memory allocated by the Allocator. */
+  void
+  free_void_bulk(void *head, void *tail, size_t num_item)
+  {
+    ink_freelist_free_bulk(this->fl, head, tail, num_item);
+  }
+
   Allocator()
   {
     fl = NULL;
@@ -132,6 +139,19 @@ public:
   }
 
   /**
+     Deallocates objects of the templated type.
+
+     @param head pointer to be freed.
+     @param tail pointer to be freed.
+     @param count of blocks to be freed.
+   */
+  void
+  free_bulk(C *head, C *tail, size_t num_item)
+  {
+    ink_freelist_free_bulk(this->fl, head, tail, num_item);
+  }
+
+  /**
     Allocate objects of the templated type via the inherited interface
     using void pointers.
   */
@@ -154,6 +174,20 @@ public:
   }
 
   /**
+      Deallocate objects of the templated type via the inherited
+      interface using void pointers.
+
+      @param head pointer to be freed.
+      @param tail pointer to be freed.
+      @param count of blocks
+    */
+  void
+  free_void_bulk(void *head, void *tail, size_t num_item)
+  {
+    free_bulk((C *) head, (C *) tail, num_item);
+  }
+
+  /**
     Create a new class specific ClassAllocator.
 
     @param name some identifying name, used for mem tracking purposes.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0cdc3cb4/lib/ts/ink_queue.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_queue.cc b/lib/ts/ink_queue.cc
index f856b97..6203ecd 100644
--- a/lib/ts/ink_queue.cc
+++ b/lib/ts/ink_queue.cc
@@ -296,6 +296,68 @@ ink_freelist_free(InkFreeList * f, void *item)
 }
 
 void
+ink_freelist_free_bulk(InkFreeList *f, void *head, void *tail, size_t num_item)
+{
+
+#if TS_USE_FREELIST
+  volatile_void_p *adr_of_next = (volatile_void_p *) ADDRESS_OF_NEXT(tail, 0);
+  head_p h;
+  head_p item_pair;
+  int result = 0;
+
+  // ink_assert(!((long)item&(f->alignment-1))); XXX - why is this no longer working?
-bcall
+
+#ifdef DEADBEEF
+  {
+    static const char str[4] = { (char) 0xde, (char) 0xad, (char) 0xbe, (char) 0xef };
+
+    // set the entire item to DEADBEEF;
+    void * temp = head;
+    for(size_t i = 0; i<num_item; i++){
+      for (int j = 0; j < (int)f->type_size; j++)
+        ((char*)temp)[j] = str[j % 4];
+      temp = *(void **) temp;
+    }
+  }
+#endif
+
+  while (!result) {
+    INK_QUEUE_LD(h, f->head);
+#ifdef SANITY
+    if (TO_PTR(FREELIST_POINTER(h)) == head)
+      ink_fatal(1, "ink_freelist_free: trying to free item twice");
+    if (((uintptr_t) (TO_PTR(FREELIST_POINTER(h)))) & 3)
+      ink_fatal(1, "ink_freelist_free: bad list");
+    if (TO_PTR(FREELIST_POINTER(h)))
+      fake_global_for_ink_queue = *(int *) TO_PTR(FREELIST_POINTER(h));
+#endif
+    *adr_of_next = FREELIST_POINTER(h);
+    SET_FREELIST_POINTER_VERSION(item_pair, FROM_PTR(head), FREELIST_VERSION(h));
+    INK_MEMORY_BARRIER;
+#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
+  }
+
+  ink_atomic_increment((int *) &f->used, -1 * num_item);
+  ink_atomic_increment(&fastalloc_mem_in_use, -(int64_t) f->type_size * num_item);
+#else
+  void * item = head;
+  if (f->alignment) {
+    for (size_t i = 0; i < num_item && item; ++i, item = *(void **)item) {
+      ats_memalign_free(item);
+    }
+  } else {
+    for (size_t i = 0; i < num_item && item; ++i, item = *(void **)item) {
+      ats_free(item);
+    }
+  }
+#endif
+}
+
+void
 ink_freelists_snap_baseline()
 {
 #if TS_USE_FREELIST

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0cdc3cb4/lib/ts/ink_queue.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_queue.h b/lib/ts/ink_queue.h
index ec64603..4c8562b 100644
--- a/lib/ts/ink_queue.h
+++ b/lib/ts/ink_queue.h
@@ -184,6 +184,7 @@ extern "C"
                                     uint32_t alignment);
   inkcoreapi void *ink_freelist_new(InkFreeList * f);
   inkcoreapi void ink_freelist_free(InkFreeList * f, void *item);
+  inkcoreapi void ink_freelist_free_bulk(InkFreeList * f, void *head, void *tail, size_t
num_item);
   void ink_freelists_dump(FILE * f);
   void ink_freelists_dump_baselinerel(FILE * f);
   void ink_freelists_snap_baseline();


Mime
View raw message