Compute Graph Framework SDK Reference  5.10
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-2022 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 <dw/core/language/Optional.hpp>
39#include <dw/core/container/RingBuffer.hpp>
40#include <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:
121 {
122 };
123
125 {
130 bool syncEnabled = false;
131 };
132
134 {
137 };
141 bool isBufferAvailable() const noexcept;
142
150 void acquire();
151
159 void send();
160
161 const Properties& getProperties() const noexcept;
162
166 void setCallbackBeforeSend(dw::core::Function<dwStatus()> callback);
167
168 // Implemented inherited methods
169 void bindChannel(ChannelObject* channel) override;
170 bool isBound() const noexcept override;
171
176 void reset() override;
177
182 ChannelMetadata& getMetadata();
183
187 void sendAdvTimestamp();
188
189protected:
191 GenericData getBufferGeneric();
192
193private:
194 static BoundProperties getBoundProperties(const ChannelObject& channel);
195 void populateDefaultMetadata(ChannelMetadata& header);
197 ChannelObject::Producer* m_channelProducer;
198 Properties m_props;
199 dw::core::Optional<GenericData> m_buffer;
200 dw::core::Function<dwStatus()> m_callbackBeforeSend;
201 uint32_t m_sendSeqNum;
202};
203
208{
209public:
210 using RingBuffer = dw::core::RingBuffer<GenericData>;
211
213 {
217 uint32_t maxBuffers = 1U;
223 dwTime_t waitTime = 0;
224 };
225
227 {
237 bool enableReuse = false;
238
242 bool syncEnabled = false;
247 uint32_t dataOffset = 0U;
248 };
249
251 {
260 };
261
265 const Properties& getProperties() const noexcept;
266
276 void recv();
277
283 void release();
284
289 void reset() override;
290
294 bool isBufferAvailable() const noexcept;
295
296 // Implemented inherited methods
297 void bindChannel(ChannelObject* channel) override;
298 bool isBound() const noexcept override;
299
304 void setCallbackAfterRecv(dw::core::Function<dwStatus()> callback);
305
310 const ChannelMetadata& getMetadata();
311
315 void sendAdvTimestamp();
316
317protected:
319 GenericData getBufferGeneric() const;
320 GenericData popBufferGeneric();
321 void releaseToChannel(void* data);
322
323private:
324 static BoundProperties getBoundProperties(const ChannelObject& channel);
325 bool recvSingle(dwTime_t waitTime);
326 bool stashConsumed();
327 bool packetStashed(GenericData packet);
328 void handleReuseDrop();
329
330 void releaseSingle();
331 bool postProcessLockstepReplayData(GenericData packet);
332 dwTime_t getWaitTime();
333 bool recvData();
334 bool waitForData();
335
336 Properties m_props;
338 ChannelObject::Consumer* m_channelConsumer;
339 bool m_shouldDropFirstBuffer;
340 dw::core::Function<dwStatus()> m_callbackAfterRecv;
341
342protected:
343 RingBuffer m_buffers;
344 GenericData m_stashedFuturePacket;
345 bool m_stashValid;
346};
347
348namespace detail
349{
350
351template <typename T>
352T* getBufferTyped(GenericData buffer)
353{
354 auto metadataPacket = extractMetadata(buffer);
355 T* ptr = metadataPacket->data.template getData<T>();
356
357 if (ptr == nullptr)
358 {
359 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "getBufferTyped: type mismatch");
360 }
361 return ptr;
362}
363
364} // namespace detail
365
369template <typename T>
371{
373 "Channel packet type not declared. Ensure channel packet type "
374 "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
375
376 using SpecimenT = typename parameter_traits<T>::SpecimenT;
377
378public:
384 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID != DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
386 : ManagedPortOutputBase(std::move(props), make_specimen<T>(&ref))
387 {
388 }
389
394 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID != DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
395 ManagedPortOutput(SpecimenT& ref)
396 : ManagedPortOutputBase({}, make_specimen<T>(&ref))
397 {
398 }
399
403 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID == DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
405 : ManagedPortOutputBase(std::move(props), make_specimen<T>(nullptr))
406 {
407 }
408
409 template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID == DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
411 : ManagedPortOutputBase({}, make_specimen<T>(nullptr))
412 {
413 }
414
421 {
422 return detail::getBufferTyped<T>(getBufferGeneric());
423 }
424};
425
429template <typename T>
431{
433 "Channel packet type not declared. Ensure channel packet type "
434 "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
435 using SpecimenT = typename parameter_traits<T>::SpecimenT;
436
437 struct PacketDeleter;
438
439public:
444 : ManagedPortInputBase(std::move(props), make_specimen<T>(nullptr))
445 {
446 }
447
449 : ManagedPortInputBase({}, make_specimen<T>(nullptr))
450 {
451 }
452
459 {
460 return iterable(*this);
461 }
462
469 {
470 return detail::getBufferTyped<T>(getBufferGeneric());
471 }
472
480 {
481 return isBufferAvailable() ? getBuffer() : nullptr;
482 }
483
484 using UniquePacketPtr = std::unique_ptr<T, PacketDeleter>;
485
487 {
488 GenericData packet = popBufferGeneric();
489 auto* ptr = detail::getBufferTyped<T>(packet);
490 void* releasePtr = packet.getPointer();
491 return UniquePacketPtr(ptr, PacketDeleter{this, releasePtr});
492 }
493
494private:
495 struct PacketDeleter
496 {
497 void operator()(T* p)
498 {
499 (void)p;
500 port->releaseToChannel(releasePtr);
501 }
502 ManagedPortInput* port;
503 void* releasePtr;
504 };
505
506 struct iterable
507 {
508 explicit iterable(ManagedPortInput<T>& port)
509 : m_port(port)
510 {
511 }
512
514 // There are no specific requirements on the template type
515 // coverity[autosar_cpp14_a14_1_1_violation]
516 template <class TT>
517 class iterator : public ManagedPortInputBase::RingBuffer::iterator
518 {
519 using Base = ManagedPortInputBase::RingBuffer::iterator;
520
521 public:
522 // Same naming is used in dwshared, hence keeping the iterator name and its accessors for now
523 // coverity[cert_dcl51_cpp_violation]
524 iterator(Base&& base, ManagedPortInput<T>& port)
525 : Base(base)
526 , m_port(port)
527 {
528 }
529
530 const Base& baseFromThis() const
531 {
532 return *this;
533 }
534
535 auto operator*() const
536 {
537 GenericData buffer = *baseFromThis();
538 return detail::getBufferTyped<TT>(buffer);
539 }
540
541 private:
542 ManagedPortInput<T>& m_port;
543 };
544
545 // coverity[cert_dcl51_cpp_violation]
546 iterator<T> begin() { return iterator<T>(m_port.m_buffers.begin(), m_port); }
547
548 // coverity[cert_dcl51_cpp_violation]
549 iterator<T> end() { return iterator<T>(m_port.m_buffers.end(), m_port); }
550
551 // coverity[cert_dcl51_cpp_violation]
552 iterator<const T> begin() const { return iterator<const T>(m_port.m_buffers.begin(), m_port); }
553
554 // coverity[cert_dcl51_cpp_violation]
555 iterator<const T> end() const { return iterator<const T>(m_port.m_buffers.end(), m_port); }
556
557 private:
558 ManagedPortInput<T>& m_port;
559 };
560};
561
562template <typename T>
564
565} // namespace framework
566} // namespace dw
567
568#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)
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