[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