Compute Graph Framework SDK Reference  5.12
ManagedPort.hpp
Go to the documentation of this file.
1
2//
3// Notice
4// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
5// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
6// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
7// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8//
9// NVIDIA CORPORATION & AFFILIATES assumes no responsibility for the consequences of use of such
10// information or for any infringement of patents or other rights of third parties that may
11// result from its use. No license is granted by implication or otherwise under any patent
12// or patent rights of NVIDIA CORPORATION & AFFILIATES. No third party distribution is allowed unless
13// expressly authorized by NVIDIA. Details are subject to change without notice.
14// This code supersedes and replaces all information previously supplied.
15// NVIDIA CORPORATION & AFFILIATES products are not authorized for use as critical
16// components in life support devices or systems without express written approval of
17// NVIDIA CORPORATION & AFFILIATES.
18//
19// SPDX-FileCopyrightText: Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
20// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
21//
22// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
23// property and proprietary rights in and to this material, related
24// documentation and any modifications thereto. Any use, reproduction,
25// disclosure or distribution of this material and related documentation
26// without an express license agreement from NVIDIA CORPORATION or
27// its affiliates is strictly prohibited.
28//
30
31#ifndef DW_FRAMEWORK_MANAGEDPORT_HPP_
32#define DW_FRAMEWORK_MANAGEDPORT_HPP_
33
35#include <dwcgf/port/Port.hpp>
38#include <dwshared/dwfoundation/dw/core/language/Optional.hpp>
39#include <dwshared/dwfoundation/dw/core/container/RingBuffer.hpp>
40#include <dwshared/dwfoundation/dw/core/language/Function.hpp>
41#include <type_traits>
42
43namespace dw
44{
45namespace framework
46{
47
49{
50public:
52
53 virtual ~ManagedPortBase() = default;
54
59 ManagedPortBase(const ManagedPortBase& other) = delete;
60 ManagedPortBase& operator=(const ManagedPortBase& other) = delete;
63
71 virtual void bindChannel(ChannelObject* channel) = 0;
72
79
83 virtual bool isBound() const noexcept = 0;
84
88 void setCycleCount(uint32_t cycleCount);
89
93 void setPeriod(uint32_t period);
94
99 virtual void reset();
100
106
107protected:
108 uint32_t m_cycleCount;
109 uint32_t m_period;
111 dw::framework::lockstep::ILockstepSyncClient* m_lockstepSyncClient;
112};
113
118{
119public:
120 // Due to single TU checking
121 // coverity[autosar_cpp14_a0_1_1_violation]
122 static constexpr char LOG_TAG[]{"ManagedPortOutputBase"};
123
125 {
126 };
127
129 {
134 bool syncEnabled = false;
135 };
136
138 {
141 };
145 bool isBufferAvailable() const noexcept;
146
150 dw::core::VectorFixed<GenericData> getAllBuffers();
151
159 void acquire();
160
168 void send();
169
170 const Properties& getProperties() const noexcept;
171
175 void setCallbackBeforeSend(dw::core::Function<dwStatus()> callback);
176
177 // Implemented inherited methods
178 void bindChannel(ChannelObject* channel) override;
179 bool isBound() const noexcept override;
180
185 void reset() override;
186
191 ChannelMetadata& getMetadata();
192
196 void sendAdvTimestamp();
197
198protected:
200 GenericData getBufferGeneric();
201
202private:
203 static BoundProperties getBoundProperties(const ChannelObject& channel);
204 void populateDefaultMetadata(ChannelMetadata& header);
206 ChannelObject::Producer* m_channelProducer;
207 Properties m_props;
208 dw::core::Optional<GenericData> m_buffer;
209 dw::core::Function<dwStatus()> m_callbackBeforeSend;
210 uint32_t m_sendSeqNum;
211};
212
217{
218public:
219 using RingBuffer = dw::core::RingBuffer<GenericData>;
220
222 {
226 uint32_t maxBuffers = 1U;
232 dwTime_t waitTime = 0;
233 };
234
236 {
246 bool enableReuse = false;
247
251 bool syncEnabled = false;
256 uint32_t dataOffset = 0U;
257 };
258
260 {
269 };
270
274 const Properties& getProperties() const noexcept;
275
285 void recv();
286
292 void release();
293
298 void reset() override;
299
303 bool isBufferAvailable() const noexcept;
304
308 dw::core::VectorFixed<GenericData> getAllBuffers();
309
310 // Implemented inherited methods
311 void bindChannel(ChannelObject* channel) override;
312 bool isBound() const noexcept override;
313
318 void setCallbackAfterRecv(dw::core::Function<dwStatus()> callback);
319
324 const ChannelMetadata& getMetadata();
325
329 void sendAdvTimestamp();
330
331protected:
333 GenericData getBufferGeneric() const;
334 GenericData popBufferGeneric();
335 void releaseToChannel(void* data);
336
337private:
338 static BoundProperties getBoundProperties(const ChannelObject& channel);
339 bool recvSingle(dwTime_t waitTime);
340 bool stashConsumed();
341 bool packetStashed(GenericData packet);
342 void handleReuseDrop();
343
344 void releaseSingle();
345 bool postProcessLockstepReplayData(GenericData packet);
346 dwTime_t getWaitTime();
347 bool recvData();
348 bool waitForData();
349 void handleWaitFailure(dwStatus status);
350 void handleCallbackAfterRecv();
351
352 Properties m_props;
354 ChannelObject::Consumer* m_channelConsumer;
355 bool m_shouldDropFirstBuffer;
356 dw::core::Function<dwStatus()> m_callbackAfterRecv;
357
358protected:
359 RingBuffer m_buffers;
360 GenericData m_stashedFuturePacket;
361 bool m_stashValid;
362};
363
364namespace detail
365{
366
367template <typename T>
368// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
369T* getBufferTyped(GenericData buffer)
370{
371 MetadataPayload* metadataPacket{extractMetadata(buffer)};
372 T* ptr{metadataPacket->data.template getData<T>()};
373
374 if (ptr == nullptr)
375 {
376 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "getBufferTyped: type mismatch");
377 }
378 return ptr;
379}
380
381// coverity[autosar_cpp14_a14_1_1_violation]
382template <typename T>
383struct vectorIterable
384{
385 explicit vectorIterable(dw::core::VectorFixed<GenericData> allBuffers)
386 : m_allBuffers(std::move(allBuffers))
387 {
388 }
389
391 // There are no specific requirements on the template type
392 // coverity[autosar_cpp14_a14_1_1_violation]
393 template <class TT>
394 class iterator : public dw::core::VectorFixed<GenericData>::iterator
395 {
396 public:
397 using Base = dw::core::VectorFixed<GenericData>::iterator;
398 // Same naming is used in dwshared, hence keeping the iterator name and its accessors for now
399 // coverity[cert_dcl51_cpp_violation]
400 iterator(Base&& base)
401 : Base(base)
402 {
403 }
404
405 const Base& baseFromThis() const
406 {
407 return *this;
408 }
409
410 auto operator*() const
411 {
412 GenericData buffer = *baseFromThis();
413 return getBufferTyped<TT>(buffer);
414 }
415 };
416
417 // coverity[cert_dcl51_cpp_violation]
418 iterator<T> begin() { return iterator<T>(m_allBuffers.begin()); }
419
420 // coverity[cert_dcl51_cpp_violation]
421 iterator<T> end() { return iterator<T>(m_allBuffers.end()); }
422
423 // coverity[cert_dcl51_cpp_violation]
424 iterator<const T> begin() const { return iterator<const T>(m_allBuffers.begin()); }
425
426 // coverity[cert_dcl51_cpp_violation]
427 iterator<const T> end() const { return iterator<const T>(m_allBuffers.end()); }
428
429private:
430 dw::core::VectorFixed<GenericData> m_allBuffers;
431};
432
433} // namespace detail
434
438template <typename T>
440{
442 "Channel packet type not declared. Ensure channel packet type "
443 "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_POD "
444 "or DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
445
446 using SpecimenT = typename parameter_traits<T>::SpecimenT;
447
448public:
454 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID != DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
456 : ManagedPortOutputBase(std::move(props), make_specimen<T>(&ref))
457 {
458 }
459
464 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID != DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
465 ManagedPortOutput(SpecimenT& ref)
466 : ManagedPortOutputBase({}, make_specimen<T>(&ref))
467 {
468 }
469
473 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID == DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
475 : ManagedPortOutputBase(std::move(props), make_specimen<T>(nullptr))
476 {
477 }
478
479 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID == DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
481 : ManagedPortOutputBase({}, make_specimen<T>(nullptr))
482 {
483 }
484
488 // coverity[autosar_cpp14_a7_1_5_violation]
490 {
491 return detail::vectorIterable<T>(getAllBuffers());
492 }
493
499 auto getBuffer() -> T*
500 {
501 return detail::getBufferTyped<T>(getBufferGeneric());
502 }
503};
504
508template <typename T>
510{
512 "Channel packet type not declared. Ensure channel packet type "
513 "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_POD "
514 "or DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
515 // coverity[autosar_cpp14_a0_1_6_violation]
516 using SpecimenT = typename parameter_traits<T>::SpecimenT;
517
518 struct PacketDeleter;
519 struct iterable;
520
521public:
526 : ManagedPortInputBase(std::move(props), make_specimen<T>(nullptr))
527 {
528 }
529
531 : ManagedPortInputBase({}, make_specimen<T>(nullptr))
532 {
533 }
534
535 ManagedPortInput(ConstructProperties props, SpecimenT specimen)
536 : ManagedPortInputBase(std::move(props), make_specimen<T>(&specimen))
537 {
538 }
539
543 detail::vectorIterable<T> getAllBufferIter()
544 {
545 return detail::vectorIterable<T>(getAllBuffers());
546 }
547
553 iterable getBufferIter()
554 {
555 return iterable(*this);
556 }
557
563 auto getBuffer() -> T*
564 {
565 return detail::getBufferTyped<T>(getBufferGeneric());
566 }
567
574 auto getOptionalBuffer() -> T*
575 {
576 return isBufferAvailable() ? getBuffer() : nullptr;
577 }
578
579 using UniquePacketPtr = std::unique_ptr<T, PacketDeleter>;
580
582 {
583 GenericData packet{popBufferGeneric()};
584 T* ptr{detail::getBufferTyped<T>(packet)};
585 void* releasePtr{packet.getPointer()};
586 return UniquePacketPtr(ptr, PacketDeleter{this, releasePtr});
587 }
588
589private:
590 struct PacketDeleter
591 {
592 void operator()(T* p)
593 {
594 static_cast<void>(p);
595 port->releaseToChannel(releasePtr);
596 }
597 ManagedPortInput* port;
598 void* releasePtr;
599 };
600
601 struct iterable
602 {
603 explicit iterable(ManagedPortInput<T>& port)
604 : m_port(port)
605 {
606 }
607
609 // There are no specific requirements on the template type
610 // coverity[autosar_cpp14_a14_1_1_violation]
611 template <class TT>
612 class iterator : public ManagedPortInputBase::RingBuffer::iterator
613 {
614 using Base = ManagedPortInputBase::RingBuffer::iterator;
615
616 public:
617 // Same naming is used in dwshared, hence keeping the iterator name and its accessors for now
618 // coverity[cert_dcl51_cpp_violation]
619 iterator(Base&& base, ManagedPortInput<T>& port)
620 : Base(std::move(base))
621 , m_port(port)
622 {
623 }
624
625 const Base& baseFromThis() const
626 {
627 return *this;
628 }
629
630 auto operator*() const -> TT*
631 {
632 GenericData buffer{*baseFromThis()};
633 return detail::getBufferTyped<TT>(buffer);
634 }
635
636 private:
637 ManagedPortInput<T>& m_port;
638 };
639
640 // coverity[cert_dcl51_cpp_violation]
641 iterator<T> begin() { return iterator<T>(m_port.m_buffers.begin(), m_port); }
642
643 // coverity[cert_dcl51_cpp_violation]
644 iterator<T> end() { return iterator<T>(m_port.m_buffers.end(), m_port); }
645
646 // coverity[cert_dcl51_cpp_violation]
647 iterator<const T> begin() const { return iterator<const T>(m_port.m_buffers.begin(), m_port); }
648
649 // coverity[cert_dcl51_cpp_violation]
650 iterator<const T> end() const { return iterator<const T>(m_port.m_buffers.end(), m_port); }
651
652 private:
653 ManagedPortInput<T>& m_port;
654 };
655};
656
657template <typename T>
659
660} // namespace framework
661} // namespace dw
662
663#endif // DW_FRAMEWORK_MANAGEDPORT_HPP_
ManagedPortBase & operator=(ManagedPortBase &&other)=delete
virtual bool isBound() const noexcept=0
virtual ~ManagedPortBase()=default
ManagedPortBase(const ManagedPortBase &other)=delete
virtual void bindChannel(ChannelObject *channel)=0
ChannelObject * getChannel()
ManagedPortBase(ManagedPortBase &&other)=delete
ManagedPortBase & operator=(const ManagedPortBase &other)=delete
void bindLockstepSyncClient(dw::framework::lockstep::ILockstepSyncClient *syncClient)
dw::framework::lockstep::ILockstepSyncClient * m_lockstepSyncClient
void setCycleCount(uint32_t cycleCount)
void setPeriod(uint32_t period)
dw::core::RingBuffer< GenericData > RingBuffer
const Properties & getProperties() const noexcept
iterator(Base &&base, ManagedPortInput< T > &port)
ManagedPortInput(ConstructProperties props, SpecimenT specimen)
ManagedPortInput(ConstructProperties props)
detail::vectorIterable< T > getAllBufferIter()
std::unique_ptr< T, PacketDeleter > UniquePacketPtr
bool isBufferAvailable() const noexcept
ManagedPortOutput(ConstructProperties props)
ManagedPortOutput(ConstructProperties props, SpecimenT &ref)
static GenericDataReference make_specimen(typename parameter_traits< T >::SpecimenT *specimen)
MetadataPayload * extractMetadata(GenericData packet)
constexpr ChannelPacketTypeID DWFRAMEWORK_PACKET_ID_DEFAULT
typename ManagedPortInput< T >::UniquePacketPtr UniquePacketPtr
Definition: Buffer.hpp:40