Statistics
| Branch: | Tag: | Revision:

root / host / lib / transport / zero_copy.cpp @ b2054a45

History | View | Annotate | Download (4.29 KB)

1
//
2
// Copyright 2010 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
#include <uhd/transport/zero_copy.hpp>
19
#include <boost/cstdint.hpp>
20
#include <boost/function.hpp>
21
#include <boost/bind.hpp>
22

    
23
using namespace uhd::transport;
24

    
25
/***********************************************************************
26
 * The pure-virtual deconstructor needs an implementation to be happy
27
 **********************************************************************/
28
managed_recv_buffer::~managed_recv_buffer(void){
29
    /* NOP */
30
}
31

    
32
/***********************************************************************
33
 * Phony zero-copy recv interface implementation
34
 **********************************************************************/
35

    
36
//! phony zero-copy recv buffer implementation
37
class managed_recv_buffer_impl : public managed_recv_buffer{
38
public:
39
    managed_recv_buffer_impl(const boost::asio::const_buffer &buff) : _buff(buff){
40
        /* NOP */
41
    }
42

    
43
    ~managed_recv_buffer_impl(void){
44
        delete [] this->cast<const boost::uint8_t *>();
45
    }
46

    
47
private:
48
    const boost::asio::const_buffer &get(void) const{
49
        return _buff;
50
    }
51

    
52
    const boost::asio::const_buffer _buff;
53
};
54

    
55
//! phony zero-copy recv interface implementation
56
struct phony_zero_copy_recv_if::impl{
57
    size_t max_buff_size;
58
};
59

    
60
phony_zero_copy_recv_if::phony_zero_copy_recv_if(size_t max_buff_size){
61
    _impl = UHD_PIMPL_MAKE(impl, ());
62
    _impl->max_buff_size = max_buff_size;
63
}
64

    
65
phony_zero_copy_recv_if::~phony_zero_copy_recv_if(void){
66
    /* NOP */
67
}
68

    
69
managed_recv_buffer::sptr phony_zero_copy_recv_if::get_recv_buff(void){
70
    //allocate memory
71
    boost::uint8_t *recv_mem = new boost::uint8_t[_impl->max_buff_size];
72

    
73
    //call recv() with timeout option
74
    size_t num_bytes = this->recv(boost::asio::buffer(recv_mem, _impl->max_buff_size));
75

    
76
    //create a new managed buffer to house the data
77
    return managed_recv_buffer::sptr(
78
        new managed_recv_buffer_impl(boost::asio::buffer(recv_mem, num_bytes))
79
    );
80
}
81

    
82
/***********************************************************************
83
 * Phony zero-copy send interface implementation
84
 **********************************************************************/
85

    
86
//! phony zero-copy send buffer implementation
87
class managed_send_buffer_impl : public managed_send_buffer{
88
public:
89
    typedef boost::function<size_t(const boost::asio::const_buffer &)> send_fcn_t;
90

    
91
    managed_send_buffer_impl(
92
        const boost::asio::mutable_buffer &buff,
93
        const send_fcn_t &send_fcn
94
    ):
95
        _buff(buff),
96
        _send_fcn(send_fcn)
97
    {
98
        /* NOP */
99
    }
100

    
101
    ~managed_send_buffer_impl(void){
102
        /* NOP */
103
    }
104

    
105
    void commit(size_t num_bytes){
106
        _send_fcn(boost::asio::buffer(_buff, num_bytes));
107
    }
108

    
109
private:
110
    const boost::asio::mutable_buffer &get(void) const{
111
        return _buff;
112
    }
113

    
114
    const boost::asio::mutable_buffer _buff;
115
    const send_fcn_t                  _send_fcn;
116
};
117

    
118
//! phony zero-copy send interface implementation
119
struct phony_zero_copy_send_if::impl{
120
    boost::uint8_t *send_mem;
121
    managed_send_buffer::sptr send_buff;
122
};
123

    
124
phony_zero_copy_send_if::phony_zero_copy_send_if(size_t max_buff_size){
125
    _impl = UHD_PIMPL_MAKE(impl, ());
126
    _impl->send_mem = new boost::uint8_t[max_buff_size];
127
    _impl->send_buff = managed_send_buffer::sptr(new managed_send_buffer_impl(
128
        boost::asio::buffer(_impl->send_mem, max_buff_size),
129
        boost::bind(&phony_zero_copy_send_if::send, this, _1)
130
    ));
131
}
132

    
133
phony_zero_copy_send_if::~phony_zero_copy_send_if(void){
134
    delete [] _impl->send_mem;
135
}
136

    
137
managed_send_buffer::sptr phony_zero_copy_send_if::get_send_buff(void){
138
    return _impl->send_buff; //FIXME there is only ever one send buff, we assume that the caller doesnt hang onto these
139
}