[cpp-threads] pthreads (was: RE: C++ Connections proposal)

Alexander Terekhov alexander.terekhov at gmail.com
Tue Apr 26 03:03:37 BST 2005


On 4/26/05, Boehm, Hans <hans.boehm at hp.com> wrote:
> That's what I meant.  I hadn't seen that discussion.
> 
> (I think we were slightly misquoted here.  I don't think Posix
> is any more broken than other comparable specifications of
> the time.  And much of that was because they were given an
> impossible task.  And I would explicitly NOT like to see us design
> an API that is at the same level as, and hence competes with Posix.

Well, what I'd like to see (as a mere observer ;-) ) is 

http://lists.boost.org/boost/2005/04/24857.php

> That view was also expressed by others at the Lillehammer C++
> meeting.)
> 
> The major other issue that needs to be addressed carefully are
> speculative stores introduced by a compiler, which may introduce
> races.  

In theory, hardware can also do it. Imagine "redundant" memory 
system that can bring back the old value (and the new value 
becomes visible "immediately"). In the case of speculation miss, 
processor would simply send "rollback" message. Or some 
multi-hyper-duper-core-thread beast with speculative store buffer
partly shared between siblings. Oder?

> Those, along with memory isolation, really need to be
> addressed in the language spec.

Well, pls see msync::cchsb below.

< pseudo C++ >

// Introspection (for bool argument below) aside for a moment
template<typename T, bool copy_ctor_or_dtor_can_mutate_object>
class mutex_and_condvar_free_single_producer_single_consumer {

  typedef isolated< aligned_storage< T > > ELEM;

  size_t           m_size; // > 1
  ELEM *           m_elem;
  atomic< ELEM * > m_head;
  atomic< ELEM * > m_tail;

  ELEM * advance(ELEM * elem) const {
    return (++elem < m_elem + m_size) ? elem : m_elem;
  }

  ...

public:

  ...

  void producer(const T & value) {
    ELEM * tail = m_tail.load(msync::naked_noncompeting);
    ELEM * next = advance(tail);
    while (next == m_head.load(msync::cchsb)) usleep(1000);
    new(tail) T(value);
    m_tail.store(next, msync::ssb);
  }

  T consumer() {
    ELEM * head = m_head.load(msync::naked_noncompeting);
    while (head == m_tail.load(type_list< msync::cchlb_t, msync::ccacq_t >::
      element<copy_ctor_or_dtor_can_mutate_object>::type())) usleep(1000);
    T value(*head);
    head->~T();
    m_head.store(advance(head), type_list< msync::slb_t, msync::rel_t >::
      element<copy_ctor_or_dtor_can_mutate_object>::type());
    return value;
  }

};

> 
> As far as I can tell, that also accounts for most of the cost in
> fixing this.  Based on a small survey, most current optimizing
> compilers do introduce speculative stores in some cases.

To tell the truth (for the sake of job security ;-) ), I'd love if
the only conforming incarnation of your

  if (x == 1) ++y;

  if (y == 1) ++x;

example would be nothing but

  data:

    isolated<T> x, y; // implied isolation aside for a moment

   threaded code:

    if (x.ref(msync::cchsb) == 1) ++y.ref();

    if (y.ref(msync::cchsb) == 1) ++x.ref();

;-)

regards,
alexander.




More information about the cpp-threads mailing list