diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2015-02-26 20:43:59 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-04-24 11:35:17 -0500 |
commit | 598385f7a41daf08999fd8ff2051aa7b176c3ff4 (patch) | |
tree | a0103534a976fc8cfedbe2fe1839ac6261274558 /src/usr/trace | |
parent | fd19d6a67096de27c5b417dceb5fbb89a3833590 (diff) | |
download | talos-hostboot-598385f7a41daf08999fd8ff2051aa7b176c3ff4.tar.gz talos-hostboot-598385f7a41daf08999fd8ff2051aa7b176c3ff4.zip |
Implement a lockfree ABA-safe smart pointer.
* Use algorithm from lockfree stack as basis.
* Convert lockfree stack to use new ABA-safe pointer.
* Convert trace service to use ABA-safe pointers on client
buffer pages to resolve futex hang due to page reuse.
Change-Id: Ib6645f2281db8fa5d81103c1753e548976615797
CQ: FW633818
Backport: release-fips830
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16042
Tested-by: Jenkins Server
Reviewed-by: Brian Silver <bsilver@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/trace')
-rw-r--r-- | src/usr/trace/buffer.C | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/usr/trace/buffer.C b/src/usr/trace/buffer.C index c7bc52a93..5367d93ec 100644 --- a/src/usr/trace/buffer.C +++ b/src/usr/trace/buffer.C @@ -32,6 +32,7 @@ #include <limits.h> #include <string.h> #include <util/align.H> +#include <util/lockfree/abaptr.H> namespace TRACE { @@ -204,7 +205,9 @@ namespace TRACE // No we begin the search for an entry. do { - BufferPage* first = iv_firstPage; + Util::Lockfree::AbaPtr<BufferPage> original_first = + Util::Lockfree::AbaPtr<BufferPage>(iv_firstPage); + BufferPage* first = original_first.get(); // Attempt to claim from the current page first. if (first) @@ -234,7 +237,7 @@ namespace TRACE iv_daemon->signal(); futex_wait(reinterpret_cast<uint64_t*>( const_cast<BufferPage**>(&iv_firstPage)), - reinterpret_cast<uint64_t>(first)); + reinterpret_cast<uint64_t>(original_first.value())); _producerEnter(); // A page might be allocated now, start over. continue; @@ -255,14 +258,13 @@ namespace TRACE // Successfully updated the count so allocate the new page. BufferPage* newPage = BufferPage::allocate(); newPage->prev = first; + original_first.set(newPage); // Now we have a page allocated, claim our entry first and then // hook it up to master list. l_entry = newPage->claimEntry(i_size); - if (!__sync_bool_compare_and_swap(&iv_firstPage, - first, - newPage)) + if (!original_first.update(&iv_firstPage)) { // We got beat adding page to the master list, so release it // and use that page. @@ -333,7 +335,8 @@ namespace TRACE _consumerEnter(); // Take page(s) from buffer. - BufferPage* page = iv_firstPage; + BufferPage* page = + Util::Lockfree::AbaPtr<BufferPage>(iv_firstPage).get(); iv_firstPage = NULL; iv_pagesAlloc = 0; |