예제 #1
0
파일: server.hpp 프로젝트: 41i/hpx
        void post_receive(boost::system::error_code &ec)
        {
            util::spinlock::scoped_lock lk(mtx_);
            if(!id_)
            {
                HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::not_connected);
                return;
            }
            struct ibv_recv_wr wr, *bad_wr = NULL;
            struct ibv_sge sge;

            std::memset(&wr, 0, sizeof(ibv_recv_wr));

            HPX_ASSERT(id_);
            wr.wr_id = (uintptr_t)id_;
            wr.sg_list = &sge;
            wr.num_sge = 1;

            sge.addr = (uintptr_t)client_msg_;
            sge.length = sizeof(message);
            sge.lkey = client_msg_mr_->lkey;

            int ret = 0;
            HPX_ASSERT(id_);
            ret = ibv_post_recv(id_->qp, &wr, &bad_wr);
            if(ret)
            {
                int verrno = errno;
                boost::system::error_code err(verrno, boost::system::system_category());
                HPX_IBVERBS_THROWS_IF(
                    ec
                  , err
                );
            }
        }
예제 #2
0
파일: server.hpp 프로젝트: 41i/hpx
        void on_preconnect(rdma_cm_id * id, ibv_pd * pd, boost::system::error_code &ec)
        {
            close();
            {
                util::spinlock::scoped_lock lk(mtx_);
                HPX_ASSERT(buffer_);
                buffer_mr_ = ibv_reg_mr(
                    pd
                  , buffer_
                  , buffer_size_
                  , IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE
                );
                if(!buffer_mr_)
                {
                    int verrno = errno;
                    boost::system::error_code err(verrno, boost::system::system_category());
                    HPX_IBVERBS_THROWS_IF(
                        ec
                      , err
                    );
                }
                server_msg_mr_ = ibv_reg_mr(
                    pd
                  , server_msg_
                  , sizeof(hpx::parcelset::policies::ibverbs::message)
                  , IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE
                );
                if(!server_msg_mr_)
                {
                    int verrno = errno;
                    boost::system::error_code err(verrno, boost::system::system_category());
                    HPX_IBVERBS_THROWS_IF(
                        ec
                      , err
                    );
                }
                client_msg_mr_ = ibv_reg_mr(
                    pd
                  , client_msg_
                  , sizeof(hpx::parcelset::policies::ibverbs::message)
                  , IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE
                );
                if(!client_msg_mr_)
                {
                    int verrno = errno;
                    boost::system::error_code err(verrno, boost::system::system_category());
                    HPX_IBVERBS_THROWS_IF(
                        ec
                      , err
                    );
                }

                id_ = id;
            }

            //post_receive();
        }
예제 #3
0
ibv_pd *connection_handler::get_pd(ibv_context *context, boost::system::error_code & ec)
{
    hpx::lcos::local::spinlock::scoped_lock l(pd_map_mtx_);
    typedef pd_map_type::iterator iterator;

    iterator it = pd_map_.find(context);
    if(it == pd_map_.end())
    {
        ibv_pd *pd = ibv_alloc_pd(context);
        if(pd == 0)
        {
            int verrno = errno;
            boost::system::error_code err(verrno, boost::system::system_category());
            HPX_IBVERBS_THROWS_IF(
                ec
                , err
            );
            return 0;
        }
        memory_pool_.register_chunk(pd);
        pd_map_.insert(std::make_pair(context, pd));
        mr_map_.insert(std::make_pair(pd, mr_cache_type()));
        return pd;
    }
    return it->second;

}
예제 #4
0
    inline bool get_next_event(
        rdma_event_channel *event_channel, rdma_cm_event & event_copy, Connection * c
      , boost::system::error_code &ec
    )
    {
        if(!event_channel)
        {
            HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::not_connected);
            return false;
        }

        rdma_cm_event * event = NULL;

        if(rdma_get_cm_event(event_channel, &event) == 0)
        {
            std::memcpy(&event_copy, event, sizeof(rdma_cm_event));

            rdma_ack_cm_event(event);

            if(event_copy.event == RDMA_CM_EVENT_DISCONNECTED)
            {
                c->on_disconnect(event_copy.id);
                return get_next_event(event_channel, event_copy, c, ec);
            }

            return true;
        }
        else
        {
            int verrno = errno;
            if(verrno == EBADF) return false;
            if(verrno == EAGAIN) return false;
            if(verrno == EWOULDBLOCK) return false;

            boost::system::error_code err(verrno, boost::system::system_category());
            HPX_IBVERBS_THROWS_IF(
                ec
              , err
            );

            return false;
        }
        HPX_ASSERT(false);
        return false;
    }
예제 #5
0
파일: server.hpp 프로젝트: 41i/hpx
        void send_message(message_type m, boost::system::error_code &ec)
        {
            util::spinlock::scoped_lock lk(mtx_);
            if(!id_)
            {
                HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::not_connected);
                return;
            }

            struct ibv_send_wr wr, *bad_wr = NULL;
            struct ibv_sge sge;

            std::memset(&wr, 0, sizeof(ibv_recv_wr));

            HPX_ASSERT(id_);
            wr.wr_id = (uintptr_t)id_;
            wr.opcode = IBV_WR_SEND;
            wr.sg_list = &sge;
            wr.num_sge = 1;
            wr.send_flags = IBV_SEND_SIGNALED;

            server_msg_->id = m;
            sge.addr = (uintptr_t)server_msg_;
            sge.length = sizeof(message);
            sge.lkey = server_msg_mr_->lkey;

            int ret = 0;
            HPX_ASSERT(id_);
            ret = ibv_post_send(id_->qp, &wr, &bad_wr);
            if(ret)
            {
                int verrno = errno;
                boost::system::error_code err(verrno, boost::system::system_category());
                HPX_IBVERBS_THROWS_IF(
                    ec
                  , err
                );
            }
        }
예제 #6
0
 inline void set_nonblocking(int fd, boost::system::error_code &ec)
 {
     int flags = fcntl(fd, F_GETFL);
     int rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK | FASYNC);
     if(rc < 0)
     {
         int verrno = errno;
         boost::system::error_code err(verrno, boost::system::system_category());
         HPX_IBVERBS_THROWS_IF(
             ec
           , err
         );
     }
 }
예제 #7
0
파일: server.hpp 프로젝트: 41i/hpx
        message_type on_completion(ibv_wc * wc, boost::system::error_code &ec)
        {
            util::spinlock::scoped_lock lk(mtx_);
            if(!id_)
            {
                HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::not_connected);
                return MSG_SHUTDOWN;
            }

            if(wc->opcode == IBV_WC_RECV)
            {
                switch(client_msg_->id)
                {
                    case MSG_DATA:
                        return MSG_DATA;
                    case MSG_SHUTDOWN:
                        return MSG_SHUTDOWN;
                    default:
                        return MSG_INVALID;
                }
            }

            if(wc->opcode == IBV_WC_SEND)
            {
                switch(server_msg_->id)
                {
                    case MSG_DONE:
                        return MSG_DONE;
                    case MSG_DATA:
                        return MSG_DATA;
                    case MSG_MR:
                        return MSG_MR;
                    case MSG_SHUTDOWN:
                        return MSG_SHUTDOWN;
                    default:
                        return MSG_INVALID;
                }
                return MSG_INVALID;
            }

            return MSG_RETRY;
        }
예제 #8
0
        void close(boost::system::error_code &ec)
        {
            if(!event_channel_)
            {
                HPX_IBVERBS_RESET_EC(ec);
                return;
            }
            if(event_channel_)
            {
                rdma_destroy_event_channel(event_channel_);
                event_channel_ = 0;
            }
            else {
                HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::not_connected);
            }

            if(listener_)
            {
                rdma_destroy_id(listener_);
                listener_ = 0;
            }

            HPX_IBVERBS_RESET_EC(ec);
        }
예제 #9
0
        void bind(
            boost::asio::ip::tcp::endpoint const & ep
          , boost::system::error_code &ec)
        {
            if(event_channel_)
            {
                HPX_IBVERBS_THROWS_IF(ec, boost::asio::error::already_connected);
            }
            else
            {
                event_channel_ = rdma_create_event_channel();
                if(!event_channel_)
                {
                    int verrno = errno;
                    close(ec);
                    boost::system::error_code err(verrno, boost::system::system_category());
                    HPX_IBVERBS_THROWS_IF(
                        ec
                      , err
                    );
                    return;
                }
                set_nonblocking(event_channel_->fd, ec);
                if(ec)
                {
                    close(ec);
                    return;
                }

                int ret = 0;
                ret = rdma_create_id(event_channel_, &listener_, NULL, RDMA_PS_TCP);

                if(ret)
                {
                    int verrno = errno;
                    close(ec);
                    boost::system::error_code err(verrno, boost::system::system_category());
                    HPX_IBVERBS_THROWS_IF(
                        ec
                      , err
                    );
                    return;
                }

                std::string host = ep.address().to_string();
                std::string port = boost::lexical_cast<std::string>(ep.port());

                addrinfo *addr;

                getaddrinfo(host.c_str(), port.c_str(), NULL, &addr);

                ret = rdma_bind_addr(listener_, addr->ai_addr);

                freeaddrinfo(addr);
                if(ret)
                {
                    int verrno = errno;
                    close(ec);
                    boost::system::error_code err(verrno, boost::system::system_category());
                    HPX_IBVERBS_THROWS_IF(
                        ec
                      , err
                    );
                    return;
                }
                ret = rdma_listen(listener_, 10); /* backlog = 10 is arbitrary */
                if(ret)
                {
                    int verrno = errno;
                    close(ec);
                    boost::system::error_code err(verrno, boost::system::system_category());
                    HPX_IBVERBS_THROWS_IF(
                        ec
                      , err
                    );
                    return;
                }
                HPX_IBVERBS_RESET_EC(ec);
            }
        }