Ejemplo n.º 1
0
    void link_nodes_unsafe(node * new_top_node, node * end_node)
    {
        tagged_node_handle old_tos = tos.load(detail::memory_order_relaxed);

        tagged_node_handle new_tos (pool.get_handle(new_top_node), old_tos.get_tag());
        end_node->next = pool.get_pointer(old_tos);

        tos.store(new_tos, memory_order_relaxed);
    }
Ejemplo n.º 2
0
    void link_nodes_atomic(node * new_top_node, node * end_node)
    {
        tagged_node_handle old_tos = tos.load(detail::memory_order_relaxed);
        for (;;) {
            tagged_node_handle new_tos (pool.get_handle(new_top_node), old_tos.get_tag());
            end_node->next = pool.get_handle(old_tos);

            if (tos.compare_exchange_weak(old_tos, new_tos))
                break;
        }
    }
Ejemplo n.º 3
0
Archivo: stack.hpp Proyecto: 7ev3n/hpx
    /** Pops object from stack.
     *
     * If pop operation is successful,
     * object is written to memory location denoted by ret.
     *
     * \returns true, if the pop operation is successful, false if stack was empty.
     *
     * \note Not thread-safe
     *
     * */
    bool pop_unsafe(T & ret)
    {
        tagged_node_ptr old_tos = tos.load(detail::memory_order_relaxed);

        if (!old_tos.get_ptr())
            return false;

        node * new_tos_ptr = old_tos->next.get_ptr();
        tagged_node_ptr new_tos(new_tos_ptr, old_tos.get_tag() + 1);

        tos.store(new_tos, memory_order_relaxed);
        ret = old_tos->v;
        pool.destruct_unsafe(old_tos.get_ptr());
        return true;
    }
Ejemplo n.º 4
0
Archivo: stack.hpp Proyecto: 7ev3n/hpx
    /** Pushes object t to the queue.
     *  May fail, if the freelist is not able to allocate a new queue node.
     *
     * \returns true, if the push operation is successful.
     *
     * \note Not thread-safe
     * \warning \b Warning:
     * May block if node needs to be allocated from the operating system
     * */
    bool push_unsafe(T const & v)
    {
        node * newnode = pool.construct_unsafe(v);

        if (newnode == 0)
            return false;

        tagged_node_ptr old_tos = tos.load(detail::memory_order_relaxed);

        tagged_node_ptr new_tos (newnode, old_tos.get_tag());
        newnode->next.set_ptr(old_tos.get_ptr());

        tos.store(new_tos, memory_order_relaxed);
        return true;
    }
Ejemplo n.º 5
0
    bool unsynchronized_pop(U & ret)
    {
        BOOST_STATIC_ASSERT((boost::is_convertible<T, U>::value));
        tagged_node_handle old_tos = tos.load(detail::memory_order_relaxed);
        node * old_tos_pointer = pool.get_pointer(old_tos);

        if (!pool.get_pointer(old_tos))
            return false;

        node * new_tos_ptr = pool.get_pointer(old_tos_pointer->next);
        tagged_node_handle new_tos(pool.get_handle(new_tos_ptr), old_tos.get_tag() + 1);

        tos.store(new_tos, memory_order_relaxed);
        detail::copy_payload(old_tos_pointer->v, ret);
        pool.template destruct<false>(old_tos);
        return true;
    }
Ejemplo n.º 6
0
Archivo: stack.hpp Proyecto: 7ev3n/hpx
    /** Pushes object t to the queue.
     *  May fail, if the freelist is not able to allocate a new queue node.
     *
     * \returns true, if the push operation is successful.
     *
     * \note Thread-safe and non-blocking
     * \warning \b Warning:
     * May block if node needs to be allocated from the operating system
     * */
    bool push(T const & v)
    {
        node * newnode = pool.construct(v);

        if (newnode == 0)
            return false;

        tagged_node_ptr old_tos = tos.load(detail::memory_order_relaxed);

        for (;;) {
            tagged_node_ptr new_tos (newnode, old_tos.get_tag());
            newnode->next.set_ptr(old_tos.get_ptr());

            if (tos.compare_exchange_weak(old_tos, new_tos))
                return true;
        }
    }
Ejemplo n.º 7
0
Archivo: stack.hpp Proyecto: 7ev3n/hpx
    /** Pops object from stack.
     *
     * If pop operation is successful,
     * object is written to memory location denoted by ret.
     *
     * \returns true, if the pop operation is successful, false if stack was empty.
     *
     * \note Thread-safe and non-blocking
     *
     * */
    bool pop(T & ret)
    {
        tagged_node_ptr old_tos = tos.load(detail::memory_order_consume);

        for (;;) {
            if (!old_tos.get_ptr())
                return false;

            node * new_tos_ptr = old_tos->next.get_ptr();
            tagged_node_ptr new_tos(new_tos_ptr, old_tos.get_tag() + 1);

            if (tos.compare_exchange_weak(old_tos, new_tos)) {
                ret = old_tos->v;
                pool.destruct(old_tos.get_ptr());
                return true;
            }
        }
    }
Ejemplo n.º 8
0
    bool consume_one(Functor const & f)
    {
        tagged_node_handle old_tos = tos.load(detail::memory_order_consume);

        for (;;) {
            node * old_tos_pointer = pool.get_pointer(old_tos);
            if (!old_tos_pointer)
                return false;

            tagged_node_handle new_tos(old_tos_pointer->next, old_tos.get_next_tag());

            if (tos.compare_exchange_weak(old_tos, new_tos)) {
                f(old_tos_pointer->v);
                pool.template destruct<true>(old_tos);
                return true;
            }
        }
    }
Ejemplo n.º 9
0
    bool pop(U & ret)
    {
        BOOST_STATIC_ASSERT((boost::is_convertible<T, U>::value));
        tagged_node_handle old_tos = tos.load(detail::memory_order_consume);

        for (;;) {
            node * old_tos_pointer = pool.get_pointer(old_tos);
            if (!old_tos_pointer)
                return false;

            tagged_node_handle new_tos(old_tos_pointer->next, old_tos.get_tag() + 1);

            if (tos.compare_exchange_weak(old_tos, new_tos)) {
                detail::copy_payload(old_tos_pointer->v, ret);
                pool.template destruct<true>(old_tos);
                return true;
            }
        }
    }