mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-22 23:43:34 +08:00
First stab at global refactoring of memory management - the library builds, but unit tests are failing horribly
This commit is contained in:
@@ -119,25 +119,16 @@ public:
|
||||
* This helper class does some compile-time magic on the transport layer machinery. For authorized personnel only.
|
||||
*/
|
||||
template <typename DataStruct_,
|
||||
unsigned NumStaticReceivers_,
|
||||
unsigned NumStaticBufs_,
|
||||
template<unsigned, unsigned, unsigned> class TransferListenerTemplate = TransferListener
|
||||
template<unsigned> class TransferListenerTemplate = TransferListener
|
||||
>
|
||||
class UAVCAN_EXPORT TransferListenerInstantiationHelper
|
||||
{
|
||||
enum { DataTypeMaxByteLen = BitLenToByteLen<DataStruct_::MaxBitLen>::Result };
|
||||
enum { NeedsBuffer = int(DataTypeMaxByteLen) > int(GuaranteedPayloadLenPerFrame) };
|
||||
enum { BufferSize = NeedsBuffer ? DataTypeMaxByteLen : 0 };
|
||||
#if UAVCAN_TINY
|
||||
enum { NumStaticBufs = 0 };
|
||||
enum { NumStaticReceivers = 0 };
|
||||
#else
|
||||
enum { NumStaticBufs = NeedsBuffer ? NumStaticBufs_: 0 };
|
||||
enum { NumStaticReceivers = NumStaticReceivers_ };
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef TransferListenerTemplate<BufferSize, NumStaticBufs, NumStaticReceivers> Type;
|
||||
typedef TransferListenerTemplate<BufferSize> Type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,22 +35,8 @@ namespace uavcan
|
||||
* For simple nodes this number can be reduced.
|
||||
* For high-traffic nodes the recommended minimum is
|
||||
* like 16K * (number of CAN ifaces + 1).
|
||||
*
|
||||
* @tparam OutgoingTransferRegistryStaticEntries Number of statically allocated objects
|
||||
* to track Transfer ID for outgoing transfers.
|
||||
* Normally it should be equal to expected number of
|
||||
* publishers and service callers, but it's not necessary.
|
||||
* Additional objects for Transfer ID tracking will
|
||||
* be allocated in the memory pool if needed.
|
||||
* Default value is acceptable for any use case.
|
||||
*/
|
||||
template <std::size_t MemPoolSize_,
|
||||
#if UAVCAN_TINY
|
||||
unsigned OutgoingTransferRegistryStaticEntries = 0
|
||||
#else
|
||||
unsigned OutgoingTransferRegistryStaticEntries = 10
|
||||
#endif
|
||||
>
|
||||
template <std::size_t MemPoolSize_>
|
||||
class UAVCAN_EXPORT Node : public INode
|
||||
{
|
||||
enum
|
||||
@@ -61,7 +47,7 @@ class UAVCAN_EXPORT Node : public INode
|
||||
typedef PoolAllocator<MemPoolSize, MemPoolBlockSize> Allocator;
|
||||
|
||||
Allocator pool_allocator_;
|
||||
OutgoingTransferRegistry<OutgoingTransferRegistryStaticEntries> outgoing_trans_reg_;
|
||||
OutgoingTransferRegistry outgoing_trans_reg_;
|
||||
Scheduler scheduler_;
|
||||
|
||||
NodeStatusProvider proto_nsp_;
|
||||
@@ -260,9 +246,8 @@ public:
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
template <std::size_t MemPoolSize_, unsigned OutgoingTransferRegistryStaticEntries>
|
||||
int Node<MemPoolSize_, OutgoingTransferRegistryStaticEntries>::start(
|
||||
const TransferPriority priority)
|
||||
template <std::size_t MemPoolSize_>
|
||||
int Node<MemPoolSize_>::start(const TransferPriority priority)
|
||||
{
|
||||
if (started_)
|
||||
{
|
||||
|
||||
@@ -21,13 +21,11 @@
|
||||
namespace uavcan
|
||||
{
|
||||
|
||||
template <typename ServiceDataType, unsigned NumStaticReceiversAndBuffers>
|
||||
template <typename ServiceDataType>
|
||||
class UAVCAN_EXPORT ServiceResponseTransferListenerInstantiationHelper
|
||||
{
|
||||
public: // so much templating it hurts
|
||||
public:
|
||||
typedef typename TransferListenerInstantiationHelper<typename ServiceDataType::Response,
|
||||
NumStaticReceiversAndBuffers,
|
||||
NumStaticReceiversAndBuffers,
|
||||
TransferListenerWithFilter>::Type Type;
|
||||
};
|
||||
|
||||
@@ -217,24 +215,18 @@ public:
|
||||
* In C++11 mode this type defaults to std::function<>.
|
||||
* In C++03 mode this type defaults to a plain function pointer; use binder to
|
||||
* call member functions as callbacks.
|
||||
*
|
||||
* @tparam NumStaticCalls_ Number of concurrent calls that the class will be able to handle without using the
|
||||
* memory pool. Note that this is NOT the maximum possible number of concurrent calls,
|
||||
* there's no such limit. Defaults to one.
|
||||
*/
|
||||
template <typename DataType_,
|
||||
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
|
||||
typename Callback_ = std::function<void (const ServiceCallResult<DataType_>&)>,
|
||||
typename Callback_ = std::function<void (const ServiceCallResult<DataType_>&)>
|
||||
#else
|
||||
typename Callback_ = void (*)(const ServiceCallResult<DataType_>&),
|
||||
typename Callback_ = void (*)(const ServiceCallResult<DataType_>&)
|
||||
#endif
|
||||
unsigned NumStaticCalls_ = 1
|
||||
>
|
||||
class UAVCAN_EXPORT ServiceClient
|
||||
: public GenericSubscriber<DataType_,
|
||||
typename DataType_::Response,
|
||||
typename ServiceResponseTransferListenerInstantiationHelper<DataType_,
|
||||
NumStaticCalls_>::Type>
|
||||
typename ServiceResponseTransferListenerInstantiationHelper<DataType_>::Type>
|
||||
, public ServiceClientBase
|
||||
{
|
||||
public:
|
||||
@@ -244,16 +236,13 @@ public:
|
||||
typedef ServiceCallResult<DataType> ServiceCallResultType;
|
||||
typedef Callback_ Callback;
|
||||
|
||||
enum { NumStaticCalls = NumStaticCalls_ };
|
||||
|
||||
private:
|
||||
typedef ServiceClient<DataType, Callback> SelfType;
|
||||
typedef GenericPublisher<DataType, RequestType> PublisherType;
|
||||
typedef typename ServiceResponseTransferListenerInstantiationHelper<DataType, NumStaticCalls>::Type
|
||||
TransferListenerType;
|
||||
typedef typename ServiceResponseTransferListenerInstantiationHelper<DataType>::Type TransferListenerType;
|
||||
typedef GenericSubscriber<DataType, ResponseType, TransferListenerType> SubscriberType;
|
||||
|
||||
typedef Multiset<CallState, NumStaticCalls> CallRegistry;
|
||||
typedef Multiset<CallState> CallRegistry;
|
||||
|
||||
struct TimeoutCallbackCaller
|
||||
{
|
||||
@@ -424,8 +413,8 @@ public:
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
void ServiceClient<DataType_, Callback_, NumStaticCalls_>::invokeCallback(ServiceCallResultType& result)
|
||||
template <typename DataType_, typename Callback_>
|
||||
void ServiceClient<DataType_, Callback_>::invokeCallback(ServiceCallResultType& result)
|
||||
{
|
||||
if (coerceOrFallback<bool>(callback_, true))
|
||||
{
|
||||
@@ -437,8 +426,8 @@ void ServiceClient<DataType_, Callback_, NumStaticCalls_>::invokeCallback(Servic
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
bool ServiceClient<DataType_, Callback_, NumStaticCalls_>::shouldAcceptFrame(const RxFrame& frame) const
|
||||
template <typename DataType_, typename Callback_>
|
||||
bool ServiceClient<DataType_, Callback_>::shouldAcceptFrame(const RxFrame& frame) const
|
||||
{
|
||||
UAVCAN_ASSERT(frame.getTransferType() == TransferTypeServiceResponse); // Other types filtered out by dispatcher
|
||||
|
||||
@@ -447,9 +436,8 @@ bool ServiceClient<DataType_, Callback_, NumStaticCalls_>::shouldAcceptFrame(con
|
||||
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
void ServiceClient<DataType_, Callback_, NumStaticCalls_>::
|
||||
handleReceivedDataStruct(ReceivedDataStructure<ResponseType>& response)
|
||||
template <typename DataType_, typename Callback_>
|
||||
void ServiceClient<DataType_, Callback_>::handleReceivedDataStruct(ReceivedDataStructure<ResponseType>& response)
|
||||
{
|
||||
UAVCAN_ASSERT(response.getTransferType() == TransferTypeServiceResponse);
|
||||
|
||||
@@ -460,8 +448,8 @@ handleReceivedDataStruct(ReceivedDataStructure<ResponseType>& response)
|
||||
}
|
||||
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
void ServiceClient<DataType_, Callback_, NumStaticCalls_>::handleDeadline(MonotonicTime)
|
||||
template <typename DataType_, typename Callback_>
|
||||
void ServiceClient<DataType_, Callback_>::handleDeadline(MonotonicTime)
|
||||
{
|
||||
UAVCAN_TRACE("ServiceClient", "Shared deadline event received");
|
||||
/*
|
||||
@@ -484,8 +472,8 @@ void ServiceClient<DataType_, Callback_, NumStaticCalls_>::handleDeadline(Monoto
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
int ServiceClient<DataType_, Callback_, NumStaticCalls_>::addCallState(ServiceCallID call_id)
|
||||
template <typename DataType_, typename Callback_>
|
||||
int ServiceClient<DataType_, Callback_>::addCallState(ServiceCallID call_id)
|
||||
{
|
||||
if (call_registry_.isEmpty())
|
||||
{
|
||||
@@ -507,16 +495,16 @@ int ServiceClient<DataType_, Callback_, NumStaticCalls_>::addCallState(ServiceCa
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
int ServiceClient<DataType_, Callback_, NumStaticCalls_>::call(NodeID server_node_id, const RequestType& request)
|
||||
template <typename DataType_, typename Callback_>
|
||||
int ServiceClient<DataType_, Callback_>::call(NodeID server_node_id, const RequestType& request)
|
||||
{
|
||||
ServiceCallID dummy;
|
||||
return call(server_node_id, request, dummy);
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
int ServiceClient<DataType_, Callback_, NumStaticCalls_>::call(NodeID server_node_id, const RequestType& request,
|
||||
ServiceCallID& out_call_id)
|
||||
template <typename DataType_, typename Callback_>
|
||||
int ServiceClient<DataType_, Callback_>::call(NodeID server_node_id, const RequestType& request,
|
||||
ServiceCallID& out_call_id)
|
||||
{
|
||||
if (!coerceOrFallback<bool>(callback_, true))
|
||||
{
|
||||
@@ -573,8 +561,8 @@ int ServiceClient<DataType_, Callback_, NumStaticCalls_>::call(NodeID server_nod
|
||||
return publisher_res;
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
void ServiceClient<DataType_, Callback_, NumStaticCalls_>::cancelCall(ServiceCallID call_id)
|
||||
template <typename DataType_, typename Callback_>
|
||||
void ServiceClient<DataType_, Callback_>::cancelCall(ServiceCallID call_id)
|
||||
{
|
||||
call_registry_.removeFirstWhere(CallStateMatchingPredicate(call_id));
|
||||
if (call_registry_.isEmpty())
|
||||
@@ -583,21 +571,21 @@ void ServiceClient<DataType_, Callback_, NumStaticCalls_>::cancelCall(ServiceCal
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
void ServiceClient<DataType_, Callback_, NumStaticCalls_>::cancelAllCalls()
|
||||
template <typename DataType_, typename Callback_>
|
||||
void ServiceClient<DataType_, Callback_>::cancelAllCalls()
|
||||
{
|
||||
call_registry_.clear();
|
||||
SubscriberType::stop();
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
bool ServiceClient<DataType_, Callback_, NumStaticCalls_>::hasPendingCallToServer(NodeID server_node_id) const
|
||||
template <typename DataType_, typename Callback_>
|
||||
bool ServiceClient<DataType_, Callback_>::hasPendingCallToServer(NodeID server_node_id) const
|
||||
{
|
||||
return NULL != call_registry_.find(ServerSearchPredicate(server_node_id));
|
||||
}
|
||||
|
||||
template <typename DataType_, typename Callback_, unsigned NumStaticCalls_>
|
||||
ServiceCallID ServiceClient<DataType_, Callback_, NumStaticCalls_>::getCallIDByIndex(unsigned index) const
|
||||
template <typename DataType_, typename Callback_>
|
||||
ServiceCallID ServiceClient<DataType_, Callback_>::getCallIDByIndex(unsigned index) const
|
||||
{
|
||||
const CallState* const id = call_registry_.getByIndex(index);
|
||||
return (id == NULL) ? ServiceCallID() : id->getCallID();
|
||||
|
||||
@@ -77,33 +77,19 @@ public:
|
||||
* In C++11 mode this type defaults to std::function<>.
|
||||
* In C++03 mode this type defaults to a plain function pointer; use binder to
|
||||
* call member functions as callbacks.
|
||||
*
|
||||
* @tparam NumStaticReceivers Number of statically allocated receiver objects. If there's more service
|
||||
* clients for this service, extra receivers will be allocated in the memory pool.
|
||||
*
|
||||
* @tparam NumStaticBufs Number of statically allocated receiver buffers. If there's more concurrent
|
||||
* incoming transfers, extra buffers will be allocated in the memory pool.
|
||||
*/
|
||||
template <typename DataType_,
|
||||
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
|
||||
typename Callback_ = std::function<void (const ReceivedDataStructure<typename DataType_::Request>&,
|
||||
ServiceResponseDataStructure<typename DataType_::Response>&)>,
|
||||
ServiceResponseDataStructure<typename DataType_::Response>&)>
|
||||
#else
|
||||
typename Callback_ = void (*)(const ReceivedDataStructure<typename DataType_::Request>&,
|
||||
ServiceResponseDataStructure<typename DataType_::Response>&),
|
||||
#endif
|
||||
#if UAVCAN_TINY
|
||||
unsigned NumStaticReceivers = 0,
|
||||
unsigned NumStaticBufs = 0
|
||||
#else
|
||||
unsigned NumStaticReceivers = 2,
|
||||
unsigned NumStaticBufs = 1
|
||||
ServiceResponseDataStructure<typename DataType_::Response>&)
|
||||
#endif
|
||||
>
|
||||
class UAVCAN_EXPORT ServiceServer
|
||||
: public GenericSubscriber<DataType_, typename DataType_::Request,
|
||||
typename TransferListenerInstantiationHelper<typename DataType_::Request,
|
||||
NumStaticReceivers, NumStaticBufs>::Type>
|
||||
typename TransferListenerInstantiationHelper<typename DataType_::Request>::Type>
|
||||
{
|
||||
public:
|
||||
typedef DataType_ DataType;
|
||||
@@ -112,8 +98,7 @@ public:
|
||||
typedef Callback_ Callback;
|
||||
|
||||
private:
|
||||
typedef typename TransferListenerInstantiationHelper<RequestType, NumStaticReceivers, NumStaticBufs>::Type
|
||||
TransferListenerType;
|
||||
typedef typename TransferListenerInstantiationHelper<RequestType>::Type TransferListenerType;
|
||||
typedef GenericSubscriber<DataType, RequestType, TransferListenerType> SubscriberType;
|
||||
typedef GenericPublisher<DataType, ResponseType> PublisherType;
|
||||
|
||||
|
||||
@@ -20,9 +20,7 @@ namespace uavcan
|
||||
* Please refer to the @ref Node<> for documentation concerning the template arguments; refer to the tutorials
|
||||
* to lean how to use libuavcan in multiprocess applications.
|
||||
*/
|
||||
template <std::size_t MemPoolSize_,
|
||||
unsigned OutgoingTransferRegistryStaticEntries = 10
|
||||
>
|
||||
template <std::size_t MemPoolSize_>
|
||||
class UAVCAN_EXPORT SubNode : public INode
|
||||
{
|
||||
enum
|
||||
@@ -33,7 +31,7 @@ class UAVCAN_EXPORT SubNode : public INode
|
||||
typedef PoolAllocator<MemPoolSize, MemPoolBlockSize> Allocator;
|
||||
|
||||
Allocator pool_allocator_;
|
||||
OutgoingTransferRegistry<OutgoingTransferRegistryStaticEntries> outgoing_trans_reg_;
|
||||
OutgoingTransferRegistry outgoing_trans_reg_;
|
||||
Scheduler scheduler_;
|
||||
|
||||
uint64_t internal_failure_cnt_;
|
||||
|
||||
@@ -34,38 +34,23 @@ namespace uavcan
|
||||
* In C++11 mode this type defaults to std::function<>.
|
||||
* In C++03 mode this type defaults to a plain function pointer; use binder to
|
||||
* call member functions as callbacks.
|
||||
*
|
||||
* @tparam NumStaticReceivers Number of statically allocated receiver objects. If there's more publishers
|
||||
* of this message, extra receivers will be allocated in the memory pool.
|
||||
*
|
||||
* @tparam NumStaticBufs Number of statically allocated receiver buffers. If there's more concurrent
|
||||
* incoming transfers, extra buffers will be allocated in the memory pool.
|
||||
*/
|
||||
template <typename DataType_,
|
||||
#if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
|
||||
typename Callback_ = std::function<void (const ReceivedDataStructure<DataType_>&)>,
|
||||
typename Callback_ = std::function<void (const ReceivedDataStructure<DataType_>&)>
|
||||
#else
|
||||
typename Callback_ = void (*)(const ReceivedDataStructure<DataType_>&),
|
||||
#endif
|
||||
#if UAVCAN_TINY
|
||||
unsigned NumStaticReceivers = 0,
|
||||
unsigned NumStaticBufs = 0
|
||||
#else
|
||||
unsigned NumStaticReceivers = 2,
|
||||
unsigned NumStaticBufs = 1
|
||||
typename Callback_ = void (*)(const ReceivedDataStructure<DataType_>&)
|
||||
#endif
|
||||
>
|
||||
class UAVCAN_EXPORT Subscriber
|
||||
: public GenericSubscriber<DataType_, DataType_,
|
||||
typename TransferListenerInstantiationHelper<DataType_, NumStaticReceivers,
|
||||
NumStaticBufs>::Type>
|
||||
typename TransferListenerInstantiationHelper<DataType_>::Type>
|
||||
{
|
||||
public:
|
||||
typedef Callback_ Callback;
|
||||
|
||||
private:
|
||||
typedef typename TransferListenerInstantiationHelper<DataType_, NumStaticReceivers, NumStaticBufs>::Type
|
||||
TransferListenerType;
|
||||
typedef typename TransferListenerInstantiationHelper<DataType_>::Type TransferListenerType;
|
||||
typedef GenericSubscriber<DataType_, DataType_, TransferListenerType> BaseType;
|
||||
|
||||
Callback callback_;
|
||||
|
||||
Reference in New Issue
Block a user