<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Thread implementation in Linux in Intel® Moderncode for Parallel Architectures</title>
    <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988931#M5995</link>
    <description>ClayB writes:&lt;BR /&gt;One thing that I found to be curious: I can understand why there is a special return value for when a counter has been decremented down to zero, but why would you want to know if a counter has been incremented to zero? If this is a counter, would it not start at zero or some other positive number? &lt;BR /&gt;&lt;BR /&gt;I use this a lot. I set a variable to '-1' to mean 'queue empty'. Threads that queue work do an InterlockedIncrement to the count variable. If it returns zero, they know they need to dispatch a thread to serve the queue. The dispatch thread sets the variable back to '-1', checks one more time to make sure there's no work, and then returns.&lt;BR /&gt;&lt;BR /&gt;DS&lt;BR /&gt;</description>
    <pubDate>Fri, 20 Jun 2003 05:26:39 GMT</pubDate>
    <dc:creator>davids</dc:creator>
    <dc:date>2003-06-20T05:26:39Z</dc:date>
    <item>
      <title>Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988924#M5988</link>
      <description>A customer asks:&lt;BR /&gt;&lt;BR /&gt;"The implementation of the following threading functions, InterlockedIncrement()&amp;amp; InterlockedDecrement() are available for MS Windows. Are these, or counterparts, available for Linux?"&lt;BR /&gt;&lt;BR /&gt;The following article suggests that there is no such implementation. Has that changes since then? If not, what is a good solution. &lt;A href="http://www.cs.helsinki.fi/linux/linux-kernel/2002-10/0314.html" target="_blank"&gt;http://www.cs.helsinki.fi/linux/linux-kernel/2002-10/0314.html&lt;/A&gt; &lt;BR /&gt;&lt;BR /&gt;Thanks for your help.&lt;BR /&gt;</description>
      <pubDate>Sat, 31 May 2003 07:18:25 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988924#M5988</guid>
      <dc:creator>Yasaman_G_Intel</dc:creator>
      <dc:date>2003-05-31T07:18:25Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988925#M5989</link>
      <description>&amp;gt; A customer asks:&lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; "The implementation of the following threading&lt;BR /&gt;&amp;gt; functions, &lt;BR /&gt;[...MS-interlocked silliness...]&lt;BR /&gt;&amp;gt; are available for MS Windows.&lt;BR /&gt;&amp;gt; Are these, or counterparts, available for Linux?"&lt;BR /&gt;&lt;BR /&gt;Low level "atomic.h" aside, ``not yet.''&lt;BR /&gt;&lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; The following article suggests that there is no such&lt;BR /&gt;&amp;gt; implementation. Has that changes since then? If not,&lt;BR /&gt;&amp;gt; what is a good solution.&lt;BR /&gt;&amp;gt; &lt;A href="http://www.cs.helsinki.fi/linux/linux-kernel/2002-10/0" target="_blank"&gt;http://www.cs.helsinki.fi/linux/linux-kernel/2002-10/0&lt;/A&gt;&lt;BR /&gt;&amp;gt; 14.html &lt;BR /&gt;&lt;BR /&gt;&lt;QUOTE&gt;&lt;BR /&gt;&lt;BR /&gt;A second problem is implementing a use-count mechanism to&lt;BR /&gt;control object lifetimes in a multi-threaded environment.&lt;BR /&gt;The two alternatives are to use mutexes or other synchronization&lt;BR /&gt;mechanisms to protect all addRef/release calls (very, very&lt;BR /&gt;expensive) or to use interlocked increment/decrement mechanisms.&lt;BR /&gt;Unfortunately, while Microsoft provides intrinsic&lt;BR /&gt;InterlockedIncrement/InterlockedDecrement functions that perform&lt;BR /&gt;atomic multiprocessor interlocked operations that correctly&lt;BR /&gt;return the result of the operation. Unfortunately, there&lt;BR /&gt;are no such functions available on Linux. Atomic.h provides&lt;BR /&gt;interlocked increment/decrement, but they don't return values.&lt;BR /&gt;Interestingly enough, Google couldn't find any example of&lt;BR /&gt;the Intel instruction sequences required to implement the&lt;BR /&gt;necessary atomic operations using the GNU assembler dialect.&lt;BR /&gt;&lt;BR /&gt;&lt;/QUOTE&gt;&lt;BR /&gt;&lt;BR /&gt;For portable reference counting, you might want to take a look at "shared_ptr/weak_ptr and thread-safety" threads at &lt;&gt; and &lt;COMP.PROGRAMMING.THREADS&gt;. I've recently injected the following (to both threads): &lt;COPY&gt;&lt;BR /&gt;&lt;BR /&gt;Alexander Terekhov wrote:&lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; Russell Hind wrote:&lt;BR /&gt;&amp;gt; &amp;gt;&lt;BR /&gt;&amp;gt; &amp;gt; Trevor Taylor wrote:&lt;BR /&gt;&amp;gt; &amp;gt; &amp;gt;&lt;BR /&gt;&amp;gt; &amp;gt; &amp;gt; Who? Me?&lt;BR /&gt;&amp;gt; &amp;gt; &amp;gt;&lt;BR /&gt;&amp;gt; &amp;gt;&lt;BR /&gt;&amp;gt; &amp;gt; I think Peter meant Alexander&lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; I got the message. I'll post refcount&lt;THREAD_SAFETY&gt;&amp;gt; typename integer_t&amp;gt; once I'll have some time for it. It won't include&lt;BR /&gt;&amp;gt; atomic&amp;lt;&amp;gt; implementation(s), however. ;-)&lt;BR /&gt;&lt;BR /&gt;&lt;A href="http://terekhov.de/pthread_refcount_t/experimental/refcount.cpp" target="_blank"&gt;http://terekhov.de/pthread_refcount_t/experimental/refcount.cpp&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;regards,&lt;BR /&gt;alexander.&lt;BR /&gt;&lt;BR /&gt;--&lt;BR /&gt;&lt;A href="http://groups.google.com/groups?selm=3EC4F194.2DA8701C%40web.de" target="_blank"&gt;http://groups.google.com/groups?selm=3EC4F194.2DA8701C%40web.de&lt;/A&gt;&lt;BR /&gt;&lt;/THREAD_SAFETY&gt;&lt;/COPY&gt;&lt;/COMP.PROGRAMMING.THREADS&gt;&lt;/&gt;</description>
      <pubDate>Sun, 01 Jun 2003 03:32:35 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988925#M5989</guid>
      <dc:creator>Intel_C_Intel</dc:creator>
      <dc:date>2003-06-01T03:32:35Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988926#M5990</link>
      <description>Alexander -&lt;BR /&gt;&lt;BR /&gt;I looked at the code first and thought "How can this work and use atomic increment/decrement if there is no support from the operating system?"  The MS-interlocked functions must have this in order to ensure that the few assembly instructions needed to perform the operation are not swapped out of the processor.  Then I looked at your "man" pages for the operations and realized the code was just part of something larger being planned that would get support for atomicity from the OS.&lt;BR /&gt;&lt;BR /&gt;One thing that I found to be curious: I can understand why there is a special return value for when a counter has been decremented down to zero, but why would you want to know if a counter has been incremented to zero?  If this is a counter, would it not start at zero or some other positive number?  &lt;BR /&gt;&lt;BR /&gt;Also, perhaps I'm unclear about the intended use of pthread_refcount_increment_positive, but why would you not allow this operation to increment a zero value?  It seems clunky to make sure the first increment of a zero counter must be done with one function, but all the rest of the increments should be done with another.&lt;BR /&gt;&lt;BR /&gt;-- clay</description>
      <pubDate>Mon, 02 Jun 2003 22:47:24 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988926#M5990</guid>
      <dc:creator>ClayB</dc:creator>
      <dc:date>2003-06-02T22:47:24Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988927#M5991</link>
      <description>&amp;gt; Alexander -&lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; I looked at the code first and thought "How can this&lt;BR /&gt;&amp;gt; work and use atomic increment/decrement if there is&lt;BR /&gt;&amp;gt; no support from the operating system?"  &lt;BR /&gt;&lt;BR /&gt;Well, you don't really need "the operating system" for&lt;BR /&gt;thread-safe reference counting. All you need is LL/SC&lt;BR /&gt;or CAS things (plus memory barriers) meant to be &lt;BR /&gt;executed in the "user land"... AND *compilers* that &lt;BR /&gt;should also follow the rules with respect to memory&lt;BR /&gt;access reordering constraints.&lt;BR /&gt;&lt;BR /&gt;&amp;gt; The&lt;BR /&gt;&amp;gt; MS-interlocked functions must have this in order to&lt;BR /&gt;&amp;gt; ensure that the few assembly instructions needed to&lt;BR /&gt;&amp;gt; perform the operation are not swapped out of the&lt;BR /&gt;&amp;gt; processor.  &lt;BR /&gt;&lt;BR /&gt;Really? Well, it's even more brain-damaged than I &lt;BR /&gt;thought previously, then.&lt;BR /&gt;&lt;BR /&gt;&amp;gt; Then I looked at your "man" pages for the&lt;BR /&gt;&amp;gt; operations and realized the code was just part of&lt;BR /&gt;&amp;gt; something larger being planned that would get support&lt;BR /&gt;&amp;gt; for atomicity from the OS.&lt;BR /&gt;&lt;BR /&gt;Not really. It's just a specification of plain C &lt;BR /&gt;reference counting API with a "non-blocking" option&lt;BR /&gt;that doesn't allow to parameterize the refcount object&lt;BR /&gt;with "thread_safety" policy and/or integer type to be&lt;BR /&gt;used for the count. The C++ "experimental" stuff allows&lt;BR /&gt;both these things and is a much better/powerful approach&lt;BR /&gt;than a plain-C pthread_refcount_t API. The idea is that&lt;BR /&gt;non-blocking pthread_refcount_t can be fully implemented&lt;BR /&gt;using refcount&amp;lt;&amp;gt; template. &lt;BR /&gt;&lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; One thing that I found to be curious: I can&lt;BR /&gt;&amp;gt; understand why there is a special return value for&lt;BR /&gt;&amp;gt; when a counter has been decremented down to zero, but&lt;BR /&gt;&amp;gt; why would you want to know if a counter has been&lt;BR /&gt;&amp;gt; incremented to zero?  &lt;BR /&gt;&lt;BR /&gt;I don't know why. Neither increment nor add operations &lt;BR /&gt;do that. Are you sure that you're not confusing it with&lt;BR /&gt;pthread_refcount_increment_positive() (or refcount::&lt;BR /&gt;increment_if_not_min())?&lt;BR /&gt;&lt;BR /&gt;&amp;gt; If this is a counter, would it&lt;BR /&gt;&amp;gt; not start at zero or some other positive number?  &lt;BR /&gt;&lt;BR /&gt;The C++ version starts at std::numeric_limits&lt;NUMERIC&gt;::&lt;BR /&gt;min() by default. The "refs" thing [see below] starts&lt;BR /&gt;both counts at "min() + 1".&lt;BR /&gt;&lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; Also, perhaps I'm unclear about the intended use of&lt;BR /&gt;&amp;gt; pthread_refcount_increment_positive, but why would&lt;BR /&gt;&amp;gt; you not allow this operation to increment a zero&lt;BR /&gt;&amp;gt; value?  &lt;BR /&gt;&lt;BR /&gt;This is needed to support "weak" pointers. Take a look&lt;BR /&gt;at:&lt;BR /&gt;&lt;BR /&gt;&lt;A href="http://std.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1450.html" target="_blank"&gt;http://std.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1450.html&lt;/A&gt;&lt;BR /&gt;(A Proposal to Add General Purpose Smart Pointers to...)&lt;BR /&gt;&lt;BR /&gt;Here's the "refs" thing that illustrates the point.&lt;BR /&gt;&lt;BR /&gt;&lt;A href="http://lists.boost.org/MailArchives/boost/msg48041.php" target="_blank"&gt;http://lists.boost.org/MailArchives/boost/msg48041.php&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;PRE&gt;
template&lt;TYPENAME t=""&gt;
class refs /* noncopyable */ { 

  typedef refcount&lt;NUMERIC&gt; count;

  count m_strong_count, m_weak_count;

  T * m_p; // to do: no msync for strong counting needed for "T const"

  /* ... */ // to do: no msync for weak counting needed for immutable *this
            // (counts aside, of course)

  void destruct_object() {
    // deleter...
    delete m_p; 
  } 

  void destruct_self() {
    delete this;
  } 

public:

  refs(T * p) throw() : m_strong_count(count::min() + 1), 
                        m_weak_count(count::min() + 1),
                        m_p(p) {
  }

 ~refs() throw() {
    /* ... */
  }

  //*** Called by existing "strong_ptr".

  void acquire_strong() throw() {
  
  m_strong_count.increment();
  }

  void release_strong() throw() {
    if (!m_strong_count.decrement()) {
      destruct_object();
      if (!m_weak_count.decrement(msync::rel))
        destruct_self();
    }
  }

  void acquire_weak_from_strong() throw() {
    acquire_weak();
  }

  //*** Called by existing "weak_ref".

  void acquire_weak() throw() {
    m_weak_count.increment();
  }

  void release_weak() throw() {
    if (!m_weak_count.decrement(msync::acq))
      destruct_self();
  }

  bool acquire_strong_from_weak() throw() {
    return m_strong_count.increment_if_not_min();
  }

}; 

&lt;/NUMERIC&gt;&lt;/TYPENAME&gt;&lt;/PRE&gt;&lt;BR /&gt;&lt;BR /&gt;Here's the refcount.cpp:&lt;BR /&gt;&lt;BR /&gt;&lt;PRE&gt;
/* This is my experimental C++ take on &amp;gt;UNOFFICIAL&amp;lt; "pthread_refcount_t"-API
 ----------------------------------------------------------------------------

 File: refcount.cpp

 Originally written by Alexander Terekhov and released into the public domain.
 This may be used for any purposes whatsoever without acknowledgment. Thanks 
 for the assistance and support of Pavel Vasiliev, Mike Mowbray, c.p.t.-group
 participants and everyone contributing, testing, and using this code.

 &lt;A href="http://groups.google.com/groups?threadm=3E4820EE.6F408B25%40web.de" target="_blank"&gt;http://groups.google.com/groups?threadm=3E4820EE.6F408B25%40web.de&lt;/A&gt;
 (Subject: Re: threadsafe reference counting)

 ----------------------------------------------------------------------------
*/

#include &lt;LIMITS&gt;
#include &lt;CASSERT&gt;
#include &lt;STDEXCEPT&gt;

struct msync { 
  enum hlb_t   { hlb   }; // hoist-load barrier
  enum ddhlb_t { ddhlb }; // hoist-load barrier with data-dependency "hint"
  enum hsb_t   { hsb   }; // hoist-store barrier
  enum slb_t   { slb   }; // sink-load barrier
  enum ddslb_t { ddslb }; // sink-load barrier with data-dependency "hint"
  enum ssb_t   { ssb   }; // sink-store barrier
  enum acq_t   { acq   }; // hoist-load + hoist-store barrier
  enum rel_t   { rel   }; // sink-load + sink-store barrier
  enum none_t  { none  }; // naked
};

template&lt;CLASS t=""&gt;
struct atomic { // 
  atomic(T n) : t(n) { }
  T load(msync::none_t) const { return t;}
  T load(msync::hlb_t) const { return t; }
  T load(msync::ddhlb_t) const { return t; }
  void store(T n, msync::none_t) { t = n; }
  void store(T n, msync::ssb_t) { t = n; }
  void store(T n, msync::acq_t) { t = n; }
  void store(T n, msync::rel_t) { t = n; }
  bool attempt_update(T o,T n, msync::none_t) { return (t == o) ? (t=n, true) : false; }
  bool attempt_update(T o,T n, msync::ssb_t) { return (t == o) ? (t=n, true) : false; }
  bool attempt_update(T o,T n, msync::acq_t) { return (t == o) ? (t=n, true) : false; }
  bool attempt_update(T o,T n, msync::rel_t) { return (t == o) ? (t=n, true) : false; }
  T t;
};

enum thread_safety { unsafe, basic }; // strong aside for a moment

template&lt;TYPENAME numeric=""&gt;
class refcount;

template&lt;BOOL is_signed=""&gt;
class is_nonnegative; // just to suppress gcc 3.2 warning

template&amp;lt;&amp;gt;
struct is_nonnegative&lt;FALSE&gt; {
  template&lt;TYPENAME numeric=""&gt;
  static bool test(numeric) { return true; } 
};

template&amp;lt;&amp;gt;
struct is_nonnegative&lt;TRUE&gt; {
  template&lt;TYPENAME numeric=""&gt;
  static bool test(numeric value) { return value &amp;gt;= 0; } 
};

template&lt;TYPENAME numeric=""&gt;
class refcount&lt;NUMERIC&gt; {

  numeric m_value;

public:

  static numeric min() throw() {
    return std::numeric_limits&lt;NUMERIC&gt;::min();
  }

  static numeric max() throw() {
    return std::numeric_limits&lt;NUMERIC&gt;::max();
  }

  refcount(numeric initial_value = min()) throw() :
    m_value(initial_value) {
  }

  numeric get() const 
throw() {
    return m_value;
  }

  void set(numeric value) throw() {
    m_value = value;
  }

  void increment() throw() {
    assert(max() &amp;gt; m_value);
    ++m_value;
  }

  void add(numeric value) throw(std::overflow_error) {
    assert(is_nonnegative&lt;:NUMERIC_LIMITS&gt;&lt;NUMERIC&gt;::is_signed&amp;gt;::test(value));
    if (max() - value &amp;lt; m_value) 
      throw std::overflow_error("refcount::add(): overflow");
    m_value += value;
  }

  bool increment_if_not_min() throw() {
    assert(max() &amp;gt; m_value);
    if (min() == m_value) 
      return false;
    ++m_value;
    return true;
  }

  bool add_if_not_min(numeric value) throw(std::overflow_error) {
    assert(is_nonnegative&lt;:NUMERIC_LIMITS&gt;&lt;NUMERIC&gt;::is_signed&amp;gt;::test(value));
    if (max() - value &amp;lt; m_value) 
      throw std::overflow_error("refcount::add_if_not_min(): overflow");
    if (min() == m_value) 
      return false;
    m_value += value;
    return true;
  }

  bool decrement() throw() {
    assert(min() &amp;lt; m_value);
    return min() &amp;lt; --m_value;
  }

  bool decrement(msync::acq_t) throw() {
    return decrement();
  }

  bool decrement(msync::rel_t) throw() {
    return decrement();
  }

  bool decrement(msync::none_t) throw() {
    return decrement();
  }

  bool subtract(numeric value) throw(std::underflow_error) {
    assert(is_nonnegative&lt;:NUMERIC_LIMITS&gt;&lt;NUMERIC&gt;::is_signed&amp;gt;::test(value));
    if (min() + value &amp;gt; m_value) 
      throw std::underflow_error("refcount::subtract(): underflow");
    return min() &amp;lt; (m_value -= value);
  }

  bool subtract(numeric value, msync::acq_t) throw(std::underflow_error) {
    return subtract(value);
  }

  bool subtract(numeric value, msync::rel_t) throw(std::underflow_error) {
    return subtract(value);
  }

  bool subtract(numeric value, msync::none_t) throw(std::underflow_error) {
    return subtract(value);
  }

};

template&lt;TYPENAME numeric=""&gt;
class refcount&lt;NUMERIC&gt; {

  atomic&lt;NUMERIC&gt; m_value;

  template&lt;TYPENAME min_store_msync=""&gt;
  bool decrement(min_store_msync msm, attempt_update_msync aum) throw() {
    numeric val;
    do { 
      val = m_value.load(msync::none);
      assert(min() &amp;lt; val);
      if (min() + 1 == val) {
        m_value.store(min(), msm);
        return false;
      }
    } while (!m_value.attempt_update(val, val - 1, aum));
    return true;
  }

  template&lt;TYPENAME min_store_msync=""&gt;
  bool subtract(numeric value, min_store_msync msm, attempt_update_msync aum) 
        throw(std::underflow_error) {
    assert(is_nonnegative&lt;:NUMERIC_LIMITS&gt;&lt;NUMERIC&gt;::is_signed&amp;gt;::test(value));
    numeric val;
    do { 
      val = m_value.load(msync::none);
      if (min() + value &amp;gt; val) 
        throw std::underflow_error("refcount::subtract(): underflow");
      if (min() + value == val) {
        m_value.store(min(), msm);
        return false;
      }
    } while (!m_value.attempt_update(val, val - value, aum));
    return true;
  }

public:

  static numeric min() throw() {
    return std::numeric_limits&lt;NUMERIC&gt;::min();
  }

  static numeric max() throw() {
    return std::numeric_limits&lt;NUMERIC&gt;::max();
  }

  refcount(numeric initial_value = min()) throw() :
    m_value(initial_value) {
  }

  numeric get() const throw() {
    return m_value.load(msync::none); 
  }

  void set(numeric value) throw() {
    m_value.store(value, msync::none); 
  }

  void increment() throw() {
    numeric val;
    do { 
      val = m_value.load(msync::none);
      
assert(max() &amp;gt; val);
    } while (!m_value.attempt_update(val, val + 1, msync::none));
  }

  void add(numeric value) throw(std::overflow_error) {
    assert(is_nonnegative&lt;:NUMERIC_LIMITS&gt;&lt;NUMERIC&gt;::is_signed&amp;gt;::test(value));
    numeric val; 
    do { 
      val = m_value.load(msync::none); 
      if (max() - value &amp;lt; val)
        throw std::overflow_error("refcount::add(): overflow");
    } while (!m_value.attempt_update(val, val + value, msync::none));
  }

  bool increment_if_not_min() throw() {
    numeric val;
    do { 
      val = m_value.load(msync::none); 
      assert(max() &amp;gt; val);
      if (min() == val)
        return false;
    } while (!m_value.attempt_update(val, val + 1, msync::none));
    return true;
  }

  bool add_if_not_min(numeric value) throw(std::overflow_error) {
    assert(is_nonnegative&lt;:NUMERIC_LIMITS&gt;&lt;NUMERIC&gt;::is_signed&amp;gt;::test(value));
    numeric val;
    do { 
      val = m_value.load(msync::none); 
      if (max() - value &amp;lt; val)
        throw std::overflow_error("refcount::add(): overflow");
      if (min() == val)
        return false;
    } while (!m_value.attempt_update(val, val + value, msync::none));
    return true;
  }

  bool decrement() throw() {
    return decrement(msync::acq, msync::rel);
  }

  bool decrement(msync::acq_t) throw() {
    return decrement(msync::acq, msync::none);
  }

  bool decrement(msync::rel_t) throw() {
    return decrement(msync::none, msync::rel);
  }

  bool decrement(msync::none_t) throw() {
    return decrement(msync::none, msync::none);
  }

  bool subtract(numeric value) throw(std::underflow_error) {
    return subtract(value, msync::acq, msync::rel);
  }

  bool subtract(numeric value, msync::acq_t) throw(std::underflow_error) {
    return subtract(value, msync::acq, msync::none);
  }

  bool subtract(numeric value, msync::rel_t) throw(std::underflow_error) {
    return subtract(value, msync::none, msync::rel);
  }

  bool subtract(numeric value, msync::none_t) throw(std::underflow_error) {
    return subtract(value, msync::none, msync::none);
  }

};


&lt;/NUMERIC&gt;&lt;/:NUMERIC_LIMITS&gt;&lt;/NUMERIC&gt;&lt;/:NUMERIC_LIMITS&gt;&lt;/NUMERIC&gt;&lt;/NUMERIC&gt;&lt;/NUMERIC&gt;&lt;/:NUMERIC_LIMITS&gt;&lt;/TYPENAME&gt;&lt;/TYPENAME&gt;&lt;/NUMERIC&gt;&lt;/NUMERIC&gt;&lt;/TYPENAME&gt;&lt;/NUMERIC&gt;&lt;/:NUMERIC_LIMITS&gt;&lt;/NUMERIC&gt;&lt;/:NUMERIC_LIMITS&gt;&lt;/NUMERIC&gt;&lt;/:NUMERIC_LIMITS&gt;&lt;/NUMERIC&gt;&lt;/NUMERIC&gt;&lt;/NUMERIC&gt;&lt;/TYPENAME&gt;&lt;/TYPENAME&gt;&lt;/TRUE&gt;&lt;/TYPENAME&gt;&lt;/FALSE&gt;&lt;/BOOL&gt;&lt;/TYPENAME&gt;&lt;/CLASS&gt;&lt;/STDEXCEPT&gt;&lt;/CASSERT&gt;&lt;/LIMITS&gt;&lt;/PRE&gt;&lt;BR /&gt;&lt;BR /&gt;Questions? Comments? TIA.&lt;BR /&gt;&lt;BR /&gt;regards,&lt;BR /&gt;alexander.&lt;BR /&gt;&lt;/NUMERIC&gt;</description>
      <pubDate>Tue, 03 Jun 2003 15:51:26 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988927#M5991</guid>
      <dc:creator>Intel_C_Intel</dc:creator>
      <dc:date>2003-06-03T15:51:26Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988928#M5992</link>
      <description>&amp;gt; Really? Well, it's even more brain-damaged than I &lt;BR /&gt;&amp;gt; thought previously, then.&lt;BR /&gt;&lt;BR /&gt;No comment on the state of MS Windows, but I must be a bit brain damaged not to realize the "simpler" solution.  I'm used to looking at things in a bigger picture way when the details are what should really be focused on.  (After banging my head around a problem for a while, this tends to sink in until next time. :-)&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&amp;gt; &amp;gt; One thing that I found to be curious: I can&lt;BR /&gt;&amp;gt; &amp;gt; understand why there is a special return value for&lt;BR /&gt;&amp;gt; &amp;gt; when a counter has been decremented down to zero,&lt;BR /&gt;&amp;gt; but&lt;BR /&gt;&amp;gt; &amp;gt; why would you want to know if a counter has been&lt;BR /&gt;&amp;gt; &amp;gt; incremented to zero?  &lt;BR /&gt;&amp;gt; &lt;BR /&gt;&amp;gt; I don't know why. Neither increment nor add&lt;BR /&gt;&amp;gt; operations &lt;BR /&gt;&amp;gt; do that. Are you sure that you're not confusing it&lt;BR /&gt;&amp;gt; with&lt;BR /&gt;&amp;gt; pthread_refcount_increment_positive() (or refcount::&lt;BR /&gt;&amp;gt; increment_if_not_min())?&lt;BR /&gt;&lt;BR /&gt;Yes, looking more closely at the specification, this does refer to pthread_refcount_increment_positive().  I'll look over the citations you have listed to see if I can get a better understanding of the need and use of these routines.  &lt;BR /&gt;&lt;BR /&gt;-- clay&lt;BR /&gt;</description>
      <pubDate>Wed, 04 Jun 2003 00:41:39 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988928#M5992</guid>
      <dc:creator>ClayB</dc:creator>
      <dc:date>2003-06-04T00:41:39Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988929#M5993</link>
      <description>Folks,&lt;BR /&gt;This is a great discussion :-)&lt;BR /&gt;&lt;BR /&gt;To go back to the original question &amp;amp; the suggestion on using the atomic.h file, how one would implement this API? Does anyone have a sample code? What I am looking for is the implementation of similar function calls as InterlockIncrement() &amp;amp; InterlockDecrement() within Linux. Is anyone taking initiatives on writing these APIs in Linux? &lt;BR /&gt;&lt;BR /&gt;Thanks for your help.&lt;BR /&gt;--Yasaman</description>
      <pubDate>Wed, 04 Jun 2003 02:36:17 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988929#M5993</guid>
      <dc:creator>Yasaman_G_Intel</dc:creator>
      <dc:date>2003-06-04T02:36:17Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988930#M5994</link>
      <description>It is trivial to implement them with a global mutex. The funny thing is, the cost is only about twice as much as if you do it with inline assembly. Basically, it comes down to one synchronizing operation (if you do it the 'right' way) versus two synchronizing operations (if you lock/unlock a mutex).&lt;BR /&gt;&lt;BR /&gt;Amusingly, the WIN32 implementation of InterlockedIncrement seems to be very slow. I think it's because it doesn't inline and requires a function call.</description>
      <pubDate>Wed, 11 Jun 2003 14:28:30 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988930#M5994</guid>
      <dc:creator>davids</dc:creator>
      <dc:date>2003-06-11T14:28:30Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988931#M5995</link>
      <description>ClayB writes:&lt;BR /&gt;One thing that I found to be curious: I can understand why there is a special return value for when a counter has been decremented down to zero, but why would you want to know if a counter has been incremented to zero? If this is a counter, would it not start at zero or some other positive number? &lt;BR /&gt;&lt;BR /&gt;I use this a lot. I set a variable to '-1' to mean 'queue empty'. Threads that queue work do an InterlockedIncrement to the count variable. If it returns zero, they know they need to dispatch a thread to serve the queue. The dispatch thread sets the variable back to '-1', checks one more time to make sure there's no work, and then returns.&lt;BR /&gt;&lt;BR /&gt;DS&lt;BR /&gt;</description>
      <pubDate>Fri, 20 Jun 2003 05:26:39 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988931#M5995</guid>
      <dc:creator>davids</dc:creator>
      <dc:date>2003-06-20T05:26:39Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988932#M5996</link>
      <description>ok, so is there or isn't there some way to provide for atomic instructions?&lt;BR /&gt;&lt;BR /&gt;I really wish POSIX would get off their butts and provide a standard for this.  It can be a complicated problem and every os/architecture does it a different way.&lt;BR /&gt;&lt;BR /&gt;for reference counting on a a n-way box (where n is 2 or greater) is __extremely__ important for users of STLport std::wrope and std::crope(which uses reference counting all over the place)&lt;BR /&gt;&lt;BR /&gt;we tracked down a 50% performance bug to STLPort for HPUX using locks instead of atomic instructions for reference counting.&lt;BR /&gt;&lt;BR /&gt;I would really like Intel to step up to the plate and ask POSIX to specify a standard API for a couple instructions.  These are very similar to the AIX API and solaris and hpux also have very similar ways of atomically incrementing and decrementing ints, longs, shorts.   There should also be ways to safely compare/exchange pointers instead of casting to (int*, long*) which will cause problems on 32,64 bit operating systems.&lt;BR /&gt;&lt;BR /&gt;int  fetch_and_add();&lt;BR /&gt;uint fetch_and_and();&lt;BR /&gt;uint fetch_and_or();&lt;BR /&gt;boolean_t compare_and_swap();&lt;BR /&gt;long  fetch_and_addlp();&lt;BR /&gt;ulong fetch_and_andlp();&lt;BR /&gt;ulong fetch_and_orlp();&lt;BR /&gt;boolean_t compare_and_swaplp();&lt;BR /&gt;ushort fetch_and_add_h();</description>
      <pubDate>Sat, 14 Aug 2004 07:34:18 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988932#M5996</guid>
      <dc:creator>goanuj</dc:creator>
      <dc:date>2004-08-14T07:34:18Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988933#M5997</link>
      <description>oi, I read through my post, it is completely orthagonal to the discussion. *sigh* this stuff is sometimes over my head.  anyways, I'd revise my previous post if I could (get a better forum Intel &lt;A href="http://www.phpbb.com/)" target="_blank"&gt;http://www.phpbb.com/)&lt;/A&gt; but instead i'll have to modify what I asked for.&lt;BR /&gt;&lt;BR /&gt;Though atomic instructions can be quite complicated to use (with great power comes great responsibility) every single operating system seems to offer some variation of the atomic_increment, atomic_increment, and atomic_swap (even though it could possibly for programmers to use these instructions w/o knowledge of their full impact)&lt;BR /&gt;&lt;BR /&gt;It would still nice for POSIX to provide an API for vendors to adhere to, I am honest to god sick and tired of dealing w/ atomic instructions.&lt;BR /&gt;&lt;BR /&gt;On a completely unrelated note do people here code against kdb/k?</description>
      <pubDate>Sat, 14 Aug 2004 14:19:50 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988933#M5997</guid>
      <dc:creator>goanuj</dc:creator>
      <dc:date>2004-08-14T14:19:50Z</dc:date>
    </item>
    <item>
      <title>Re: Thread implementation in Linux</title>
      <link>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988934#M5998</link>
      <description>&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;A href="http://groups.google.com/groups?selm=kqUDc.129305%24Sw.117350%40attbi_s51&amp;amp;rnum=8" target="_blank"&gt;http://groups.google.com/groups?selm=kqUDc.129305%24Sw.117350%40attbi_s51&amp;amp;rnum=8&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;There's my stuff.&lt;/DIV&gt;</description>
      <pubDate>Sun, 15 Aug 2004 03:42:51 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Moderncode-for-Parallel/Thread-implementation-in-Linux/m-p/988934#M5998</guid>
      <dc:creator>Chris_M__Thomasson</dc:creator>
      <dc:date>2004-08-15T03:42:51Z</dc:date>
    </item>
  </channel>
</rss>

