Compute Graph Framework SDK Reference  5.12
ChannelParameters.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) 2018-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_CHANNEL_PARAMETERS_HPP_
32#define DW_FRAMEWORK_CHANNEL_PARAMETERS_HPP_
33
34#include <dwshared/dwfoundation/dw/core/base/ExceptionWithStatus.hpp>
35#include <dwshared/dwfoundation/dw/core/container/BaseString.hpp>
36#include <dwshared/dwfoundation/dw/core/container/VectorFixed.hpp>
37#include <dwshared/dwfoundation/dw/core/safety/Safety.hpp>
38#include <dw/core/system/NvMediaExt.h>
40#include <sstream>
41#include <limits>
42
43namespace dw
44{
45namespace framework
46{
47
49
52using ChannelType = enum class ChannelType : uint8_t {
53 // coverity[autosar_cpp14_a5_1_1_violation]
54 SHMEM_LOCAL = 0,
55 SHMEM_REMOTE = 1,
56 EGLSTREAM = 2,
57 // coverity[autosar_cpp14_a5_1_1_violation]
58 SOCKET = 3,
59 DDS = 4,
60 // coverity[autosar_cpp14_a5_1_1_violation]
61 NVSCI = 5,
62};
63
64// coverity[autosar_cpp14_a0_1_3_violation]
65static inline const char* ToParam(ChannelType channelType)
66{
67 const char* result;
68 switch (channelType)
69 {
70 // coverity[autosar_cpp14_a5_1_1_violation]
71 case ChannelType::SHMEM_LOCAL:
72 // coverity[autosar_cpp14_a5_1_1_violation]
73 result = "type=SHMEM_LOCAL";
74 break;
75 // coverity[autosar_cpp14_a5_1_1_violation]
76 case ChannelType::SHMEM_REMOTE:
77 // coverity[autosar_cpp14_a5_1_1_violation]
78 result = "type=SHMEM_REMOTE";
79 break;
80 // coverity[autosar_cpp14_a5_1_1_violation]
81 case ChannelType::EGLSTREAM:
82 // coverity[autosar_cpp14_a5_1_1_violation]
83 result = "type=EGLSTREAM";
84 break;
85 // coverity[autosar_cpp14_a5_1_1_violation]
86 case ChannelType::SOCKET:
87 // coverity[autosar_cpp14_a5_1_1_violation]
88 result = "type=SOCKET";
89 break;
90 // coverity[autosar_cpp14_a5_1_1_violation]
91 case ChannelType::DDS:
92 // coverity[autosar_cpp14_a5_1_1_violation]
93 result = "type=DDS";
94 break;
95 // coverity[autosar_cpp14_a5_1_1_violation]
96 case ChannelType::NVSCI:
97 // coverity[autosar_cpp14_a5_1_1_violation]
98 result = "type=NVSCI";
99 break;
100 default:
101 // coverity[autosar_cpp14_a5_1_1_violation]
102 result = "";
103 break;
104 }
105 return result;
106}
107
111enum class ChannelRole : uint8_t
112{
116};
117
118inline constexpr bool IsProducer(ChannelRole role)
119{
121}
122
123inline constexpr bool IsConsumer(ChannelRole role)
124{
126}
127
128// coverity[autosar_cpp14_a0_1_1_violation]
129// coverity[autosar_cpp14_m0_1_4_violation]
130static constexpr uint16_t MAX_CHANNEL_PARAM_SIZE{1024U};
131// coverity[autosar_cpp14_a0_1_1_violation]
132// coverity[autosar_cpp14_m0_1_4_violation]
133static constexpr uint16_t MAX_CHANNEL_ALL_PARAMS_SIZE{1024U};
134// coverity[autosar_cpp14_a0_1_1_violation]
135// coverity[autosar_cpp14_m0_1_4_violation]
136static constexpr uint16_t MAX_CHANNEL_PRODUCERS_COUNT{2048U};
137static constexpr uint16_t MAX_CHANNEL_CONSUMERS_COUNT{256U};
138
139using ChannelParamStr = dw::core::FixedString<MAX_CHANNEL_PARAM_SIZE>;
140
141enum class ChannelMode
142{
143 FIFO,
144 MAILBOX,
146};
147
149{
150 uint32_t socID;
151 uint32_t vmID;
152};
153
154// NOTE(eklein): This is slightly awkward. I would much prefer to put this in
155// the ChannelNvSciStreamParams class directly, but I need access to the
156// operator overloads inside ChannelNvSciStreamParams.
157// I cannot forward declare the operators inside the class, and I cannot put the
158// operators inside the enum class (as you would ideally do). The best compromise
159// I could think of was to put this enum class here outside.
161{
162 COMPONENT_NONE = 0,
163
164 COMPONENT_CPU = 1 << 0,
165 COMPONENT_EGL = 1 << 1,
166 COMPONENT_CUDA = 1 << 2,
167 COMPONENT_PVA = 1 << 3,
168 COMPONENT_DLA = 1 << 4,
169 COMPONENT_NVMEDIA = 1 << 5,
170};
171
172// whether the channel is created statically, or dynamically at runtime
173// coverity[autosar_cpp14_a0_1_6_violation]
175{
179};
180
181// the farthest reach this channel can achieve
182// shorter reach is faster, so if topology is known upfront,
183// use the shortest matching reach for maximum performance
184// coverity[autosar_cpp14_a0_1_6_violation]
185enum class ChannelReach
186{
187 REACH_NONE = 0,
190 REACH_VM,
192};
193
196{
197 return static_cast<ChannelNvSciStreamEnabledComponents>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
198}
199
202{
203 return static_cast<ChannelNvSciStreamEnabledComponents>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
204}
205
206template <typename T>
207// coverity[autosar_cpp14_a2_10_4_violation]
208// coverity[autosar_cpp14_a2_10_5_violation]
209static inline T ParseChannelParameter(const ChannelParamStr& value);
210
211template <>
212// coverity[autosar_cpp14_a2_10_4_violation]
213// coverity[autosar_cpp14_a2_10_5_violation]
215{
216 // coverity[autosar_cpp14_a5_1_1_violation]
217 return dw::core::safeStrtol(value.c_str(), nullptr, 10);
218}
219
220template <>
221// coverity[autosar_cpp14_a2_10_4_violation]
222// coverity[autosar_cpp14_a2_10_5_violation]
224{
225 int64_t translatedSize{ParseChannelParameter<int64_t>(value)};
226 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
227 if (translatedSize < 0)
228 {
229 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: size_t is negative");
230 }
231 size_t result{static_cast<size_t>(translatedSize)};
232 return result;
233}
234
235template <>
236// coverity[autosar_cpp14_a2_10_4_violation]
237// coverity[autosar_cpp14_a2_10_5_violation]
239{
240 size_t translatedSize{ParseChannelParameter<size_t>(value)};
241 if (translatedSize > std::numeric_limits<uint32_t>::max())
242 {
243 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: value is larger than uint32_t allows");
244 }
245 uint32_t result{static_cast<uint32_t>(translatedSize)};
246 return result;
247}
248
249template <>
250// coverity[autosar_cpp14_a2_10_4_violation]
251// coverity[autosar_cpp14_a2_10_5_violation]
253{
254 size_t translatedSize{ParseChannelParameter<size_t>(value)};
255 if (translatedSize > std::numeric_limits<uint16_t>::max())
256 {
257 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelSocketParams: port is larger than uint16_t allows!");
258 }
259 uint16_t result{static_cast<uint16_t>(translatedSize)};
260 return result;
261}
262
263template <>
264// coverity[autosar_cpp14_a2_10_4_violation]
265// coverity[autosar_cpp14_a2_10_5_violation]
267{
268 bool result;
269 // coverity[autosar_cpp14_a5_1_1_violation]
270 if ((value == "true") || (value == "1"))
271 {
272 result = true;
273 }
274 // coverity[autosar_cpp14_a5_1_1_violation]
275 else if ((value == "false") || (value == "0"))
276 {
277 result = false;
278 }
279 else
280 {
281 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: needs to be 'true' or 'false' or 1/0");
282 }
283 return result;
284}
285
286template <>
287// coverity[autosar_cpp14_a2_10_4_violation]
288// coverity[autosar_cpp14_a2_10_5_violation]
290{
291 // coverity[autosar_cpp14_a5_1_1_violation]
292 if (value == "producer")
293 {
295 }
296 // coverity[autosar_cpp14_a5_1_1_violation]
297 if (value == "consumer")
298 {
300 }
301 // coverity[autosar_cpp14_a5_1_1_violation]
302 if (value == "composite")
303 {
305 }
306 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: role unknown!");
307}
308
309template <>
310// coverity[autosar_cpp14_a2_10_4_violation]
311// coverity[autosar_cpp14_a2_10_5_violation]
313{
314 // coverity[autosar_cpp14_a5_1_1_violation]
315 if (value == "SHMEM_LOCAL")
316 {
317 return ChannelType::SHMEM_LOCAL;
318 }
319 // coverity[autosar_cpp14_a5_1_1_violation]
320 if (value == "SHMEM_REMOTE")
321 {
322 return ChannelType::SHMEM_REMOTE;
323 }
324 // coverity[autosar_cpp14_a5_1_1_violation]
325 if (value == "EGLSTREAM")
326 {
327 return ChannelType::EGLSTREAM;
328 }
329 // coverity[autosar_cpp14_a5_1_1_violation]
330 if (value == "SOCKET")
331 {
332 return ChannelType::SOCKET;
333 }
334 // coverity[autosar_cpp14_a5_1_1_violation]
335 if (value == "DDS")
336 {
337 return ChannelType::DDS;
338 }
339 // coverity[autosar_cpp14_a5_1_1_violation]
340 if (value == "NVSCI")
341 {
342 return ChannelType::NVSCI;
343 }
344 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: type unknown!");
345}
346
347template <>
348// coverity[autosar_cpp14_a2_10_4_violation]
349// coverity[autosar_cpp14_a2_10_5_violation]
351{
352 ChannelMode result;
353 // coverity[autosar_cpp14_a5_1_1_violation]
354 if (value == "mailbox")
355 {
356 result = ChannelMode::MAILBOX;
357 }
358 // coverity[autosar_cpp14_a5_1_1_violation]
359 else if (value == "singleton")
360 {
361 result = ChannelMode::SINGLETON;
362 }
363 else
364 {
365 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: ChannelMode unknown!");
366 }
367 return result;
368}
369
370template <>
371// coverity[autosar_cpp14_a2_10_4_violation]
372// coverity[autosar_cpp14_a2_10_5_violation]
374{
375 // coverity[autosar_cpp14_a5_1_1_violation]
376 size_t pos{value.find(".")};
377 ChannelPeerLocation result{};
378 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
379 ChannelParamStr first{value.substr(0U, pos)};
380 // coverity[autosar_cpp14_a4_7_1_violation]
381 // coverity[cert_int30_c_violation]
382 ChannelParamStr second{value.substr(pos + 1U)};
383 result.socID = ParseChannelParameter<uint32_t>(first);
384 result.vmID = ParseChannelParameter<uint32_t>(second);
385 return result;
386}
387
388template <typename T>
389// coverity[autosar_cpp14_a2_10_4_violation]
390// coverity[autosar_cpp14_a2_10_5_violation]
391void ParseChannelParameter(const ChannelParamStr& value, T& result)
392{
393 result = ParseChannelParameter<T>(value);
394}
395
396template <size_t Size>
397// coverity[autosar_cpp14_a2_10_4_violation]
398// coverity[autosar_cpp14_a2_10_5_violation]
399void ParseChannelParameter(const ChannelParamStr& value, dw::core::FixedString<Size>& result)
400{
401 result = value;
402}
403
404template <typename T, size_t N>
405// coverity[autosar_cpp14_a2_10_4_violation]
406// coverity[autosar_cpp14_a2_10_5_violation]
407void ParseChannelParameter(const ChannelParamStr& value, dw::core::VectorFixed<T, N>& result)
408{
409 size_t pos{0U};
410 size_t endpos{0U};
411 while (true)
412 {
413 // coverity[autosar_cpp14_a5_1_1_violation]
414 endpos = value.find(":", pos);
415 bool done{endpos == dw::core::FixedString<1>::NPOS};
416 size_t count{done ? endpos : endpos - pos};
417 T entry{};
418 ParseChannelParameter(value.substr(pos, count), entry);
419 result.push_back(entry);
420 if (done)
421 {
422 break;
423 }
424 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
425 pos = endpos + 1U;
426 }
427}
428
429// coverity[autosar_cpp14_a2_10_4_violation]
430// coverity[autosar_cpp14_a2_10_5_violation]
431// coverity[autosar_cpp14_m0_1_8_violation]
433{
434 return;
435}
436
437template <typename T, typename... Others>
438// coverity[autosar_cpp14_a2_10_4_violation]
439// coverity[autosar_cpp14_a2_10_5_violation]
440static inline void ParseChannelParameters(const ChannelParamStr& key, const ChannelParamStr& value, const char* staticKey, T& result, Others&&... others)
441{
442 if (key == staticKey)
443 {
444 ParseChannelParameter(value, result);
445 return;
446 }
447 ParseChannelParameters(key, value, std::forward<Others>(others)...);
448}
449
450template <typename... Others>
451// coverity[autosar_cpp14_a2_10_4_violation]
452// coverity[autosar_cpp14_a2_10_5_violation]
453static inline void ParseAllChannelParameters(const ChannelParamStr& channelParams, Others&&... others)
454{
455 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
456 std::size_t key{0U};
457 // coverity[autosar_cpp14_a5_1_1_violation]
458 std::size_t pos{channelParams.find("=")};
459 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
460 std::size_t value{0U};
461 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
462 std::size_t valueEnd{0U};
463
464 ChannelParamStr keyString{};
465 ChannelParamStr valueString{};
466 while (pos != dw::core::FixedString<1>::NPOS && value != dw::core::FixedString<1>::NPOS)
467 {
468 // coverity[autosar_cpp14_a4_7_1_violation]
469 // coverity[cert_int30_c_violation]
470 keyString = channelParams.substr(key, pos - key);
471 // coverity[autosar_cpp14_a5_1_1_violation]
472 value = channelParams.find(",", pos);
473 // coverity[autosar_cpp14_a4_7_1_violation]
474 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
475 // coverity[cert_int30_c_violation]
476 valueEnd = (value == dw::core::FixedString<1>::NPOS) ? (channelParams.length() - (pos + 1U)) : (value - pos - 1U);
477 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
478 valueString = channelParams.substr(pos + 1U, valueEnd);
479 ParseChannelParameters(keyString, valueString, std::forward<Others>(others)...);
480
481 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
482 key = value + 1U;
483 // coverity[autosar_cpp14_a5_1_1_violation]
484 pos = channelParams.find("=", key);
485 }
486}
487
489{
490public:
491 static inline ChannelParamStr getParamStr(const char* serverIP,
492 uint16_t port,
493 bool producerFifo = false,
494 uint16_t numBlockingConnections = 1U,
495 dw::core::FixedString<8> const sockPrefix = dw::core::FixedString<8>())
496 {
497 std::stringstream ss{};
498 ss.flags(std::ios::dec);
499 ss << "type=SOCKET";
500 if (serverIP != nullptr)
501 {
502 ss << ",ip=";
503 ss << serverIP;
504 }
505 ss << ",id=";
506 ss << port;
507 ss << ",producer-fifo=";
508 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
509 ss << (producerFifo ? 1U : 0U);
510 ss << ",num-clients=";
511 ss << numBlockingConnections;
512 ss << ",sock-prefix=";
513 ss << sockPrefix;
514 ChannelParamStr result{ss.str().c_str()};
515 return result;
516 }
517
519 explicit ChannelSocketParams(const char* params)
520 {
521 dw::core::FixedString<MAX_CHANNEL_ALL_PARAMS_SIZE> channelParams{params};
522 ParseAllChannelParameters(channelParams,
523 // coverity[autosar_cpp14_a5_1_1_violation]
524 "ip", m_serverIP,
525 // coverity[autosar_cpp14_a5_1_1_violation]
526 "producer-fifo", m_producerFifo,
527 // coverity[autosar_cpp14_a5_1_1_violation]
528 "id", m_port,
529 // coverity[autosar_cpp14_a5_1_1_violation]
530 "connect-timeout", m_connectTimeout,
531 // coverity[autosar_cpp14_a5_1_1_violation]
532 "sock-prefix", m_sockPrefix);
533 }
534
536
538
539 ChannelParamStr getServerIP() const { return m_serverIP; }
540 uint16_t getPort() const { return m_port; }
541 bool hasProducerFifo() const { return m_producerFifo; }
542 dwTime_t getConnectTimeout() const { return m_connectTimeout; }
543 dw::core::FixedString<8> getSockPrefix() const { return m_sockPrefix; }
544
545private:
546 ChannelParamStr m_serverIP; // needed for socket client connection
547 uint16_t m_port{0U};
548 bool m_producerFifo{false}; // Allow the socket producer to have its own fifo to queue up work
549 dwTime_t m_connectTimeout{DW_TIME_INVALID};
550 dw::core::FixedString<8> m_sockPrefix{};
551};
552
554
556{
557public:
559
560 explicit ChannelNvSciStreamParams(const char* params)
562 {
563 dw::core::FixedString<MAX_CHANNEL_ALL_PARAMS_SIZE> channelParams{params};
564 ParseAllChannelParameters(channelParams,
565 // coverity[autosar_cpp14_a5_1_1_violation]
566 "streamName", m_streamNames,
567 // coverity[autosar_cpp14_a5_1_1_violation]
568 "limits", m_limits,
569 // coverity[autosar_cpp14_a5_1_1_violation]
570 "num-clients", m_localClientCount,
571 // coverity[autosar_cpp14_a5_1_1_violation]
572 "late-locs", m_lateLocs);
573 }
574
576
578
579 uint16_t getNumOutputs() const
580 {
581 static_assert(decltype(m_streamNames)::CAPACITY_AT_COMPILE_TIME < std::numeric_limits<uint16_t>::max(), "ChannelNvSciStreamParams: number of outputs over limit");
582 // coverity[autosar_cpp14_a4_7_1_violation]
583 // coverity[cert_int31_c_violation]
584 return static_cast<uint16_t>(m_streamNames.size());
585 }
586
587 uint32_t getLocalClientCount() const { return m_localClientCount; }
588
589 dw::core::span<ChannelPeerLocation const> getLateLocs() const
590 {
591 return dw::core::make_span<ChannelPeerLocation const>(m_lateLocs.data(), m_lateLocs.size());
592 }
593
594 const char* getStreamName(uint16_t index = 0) const
595 {
596 if (index >= m_streamNames.size())
597 {
598 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelNvSciStreamParams: stream name index out of range");
599 }
600 return m_streamNames[index].c_str();
601 }
602
603 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
604 int64_t getLimiterMaxPackets(uint16_t index = 0U) const
605 {
606 // Note: if no limits are denoted, return -1 and make inquirers not create limiter blocks.
607 // If not, it can lead to out of range when querying
608 if (m_limits.empty())
609 {
610 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
611 return -1;
612 }
613
614 if (index >= m_limits.size())
615 {
616 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelNvSciStreamParams: limiter maxPackets index out of range");
617 }
618 return m_limits[index];
619 }
620
621protected:
622 dw::core::VectorFixed<dw::core::FixedString<64>, 8> m_streamNames{};
623 dw::core::VectorFixed<int64_t, 8> m_limits{};
624 dw::core::VectorFixed<ChannelPeerLocation, 32> m_lateLocs{};
626};
627
632{
633public:
634 explicit ChannelParams(const char* params)
635 {
636 m_str = params;
638 // coverity[autosar_cpp14_a5_1_1_violation]
639 "fifo-size", m_fifoSize,
640 // coverity[autosar_cpp14_a5_1_1_violation]
641 "id", m_id,
642 // coverity[autosar_cpp14_a5_1_1_violation]
643 "uid", m_uid,
644 // coverity[autosar_cpp14_a5_1_1_violation]
645 "connect-group-id", m_connectGroupID,
646 // coverity[autosar_cpp14_a5_1_1_violation]
647 "singleton-id", m_singletonId,
648 // coverity[autosar_cpp14_a5_1_1_violation]
649 "mode", m_mode,
650 // coverity[autosar_cpp14_a5_1_1_violation]
651 "reuse", m_reuseEnabled,
652 // coverity[autosar_cpp14_a5_1_1_violation]
653 "debug-port", m_debugPort,
654 // coverity[autosar_cpp14_a5_1_1_violation]
655 "num-clients", m_clientsCount,
656 // coverity[autosar_cpp14_a5_1_1_violation]
657 "debug-num-clients", m_debugClientsCount,
658 // coverity[autosar_cpp14_a5_1_1_violation]
659 "role", m_role,
660 // coverity[autosar_cpp14_a5_1_1_violation]
661 "type", m_type,
662 // coverity[autosar_cpp14_a5_1_1_violation]
663 "data-offset", m_dataOffset,
664 // coverity[autosar_cpp14_a5_1_1_violation]
665 "strict", m_strictFifo,
666 // coverity[autosar_cpp14_a5_1_1_violation]
667 "sync-enabled", m_syncEnabled);
668
669 adjustPoolCapacity();
670
671 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
672 if (m_clientsCount == 0U)
673 {
674 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
675 m_clientsCount = 1U;
676 }
677
678 if (!m_singletonId.empty())
679 {
680 m_mode = ChannelMode::SINGLETON;
681 }
682
683 if (m_mode == ChannelMode::MAILBOX)
684 {
685 m_mailboxMode = true;
686 }
687 else if (m_mode == ChannelMode::SINGLETON)
688 {
689 m_singletonMode = true;
690
691 // Assign singletonId with id
692 if (!m_id.empty() && m_singletonId.empty())
693 {
694 m_singletonId = m_id;
695 }
696 }
697
698 // Why break this up like this? Code complexity.
699 // Without this, we fail the code complexity analysis.
700 ValidateMailbox();
701 ValidateSingleton();
702
703 switch (m_type)
704 {
705 // coverity[autosar_cpp14_a5_1_1_violation]
706 case ChannelType::SHMEM_LOCAL:
707 break;
708 // coverity[autosar_cpp14_a5_1_1_violation]
709 case ChannelType::SOCKET:
710 m_socketParams = ChannelSocketParams(params);
711 break;
712 // coverity[autosar_cpp14_a5_1_1_violation]
713 case ChannelType::NVSCI:
714 m_nvSciStreamParams = ChannelNvSciStreamParams(params);
715 break;
716 // coverity[autosar_cpp14_a5_1_1_violation]
717 case ChannelType::SHMEM_REMOTE:
718 // coverity[autosar_cpp14_a5_1_1_violation]
719 case ChannelType::EGLSTREAM:
720 // coverity[autosar_cpp14_a5_1_1_violation]
721 case ChannelType::DDS:
722 default:
723 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED, "ChannelParams: no parameters for channel type");
724 }
725 }
726
728 {
729 *this = other;
730 }
731
732 ChannelParams& operator=(const ChannelParams& other) = default;
733 ~ChannelParams() = default;
734
735 const char* getStr() const { return m_str.c_str(); }
736 ChannelParamStr getId() const { return m_id; }
737 ChannelParamStr getSingletonId() const { return m_singletonId; }
738 uint16_t getDebugPort() const { return m_debugPort; }
739 size_t getFifoSize() const { return m_fifoSize; }
740 // Note(chale): Normally the fifo length governs whether a consumer
741 // will receive packet. The actual packet pool's size may be larger
742 // than the fifo length. non-strict mode allows consumers to receive
743 // up to the entire pool size instead of just their fifo length.
744 bool isStrictFifo() const { return m_strictFifo; }
745 void setStrictFifo(bool strictFifo)
746 {
747 m_strictFifo = strictFifo;
748 }
749 size_t getPoolCapacity() const { return m_poolCapacity; }
750 bool getMailboxMode() const { return m_mailboxMode; }
751 // Note (ajayawardane): The data-offset parameter is used to describe
752 // the consumption offset between the producer and the consumer
753 // in the sync packet use-case. For example, if a packet is produced with the
754 // sync count x, and is inteneded to be consumed when the sync count is x + 1,
755 // the data-offset would be 1. This parameter is also used to identify whether
756 // to use sync packets to transfer data, so needs to be included in both the
757 // producer and the consumer params.
758 uint32_t getDataOffset() const { return m_dataOffset; }
759 bool getSyncEnabled() const { return m_syncEnabled; }
760 void setMailboxMode(bool mailboxEnabled) { m_mailboxMode = mailboxEnabled; }
761 bool getSingletonMode() const { return m_singletonMode; }
762 bool getReuseEnabled() const { return m_reuseEnabled; }
763 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
764 bool getDebugMode() const { return m_debugPort > 0U; }
765 uint16_t getExpectedConnectionsCount() const { return m_clientsCount; }
766 uint16_t getExpectedDebugConnectionsCount() const { return m_debugClientsCount; }
767 ChannelRole getRole() const { return m_role; }
768 ChannelType getType() const { return m_type; }
769 uint32_t getUID() const { return m_uid; }
770 uint32_t getConnectGroupID() const { return m_connectGroupID; }
771
773 {
774 if (m_type != ChannelType::SOCKET)
775 {
776 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getSocketParams: channel is not of type SOCKET");
777 }
778 return m_socketParams;
779 }
780
782 {
783 if (m_type != ChannelType::NVSCI)
784 {
785 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getNvSciStreamParams: channel is not of type NVSCI");
786 }
787 return m_nvSciStreamParams;
788 }
789
790private:
791 void ValidateMailbox()
792 {
793 if (m_singletonMode)
794 {
795 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
796 if (m_fifoSize != 1U)
797 {
798 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton and mailbox modes are incompatible with a fifo setting other than 1");
799 }
800 }
801 if (!m_mailboxMode && m_reuseEnabled)
802 {
803 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: reuse=true specified when mode!=mailbox. Not valid");
804 }
805 if (m_mailboxMode && m_singletonMode)
806 {
807 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton mode is incompatible mailbox mode");
808 }
809 }
810
811 void ValidateSingleton()
812 {
813 // Assign singletonId with id in singleton mode
814 if (m_singletonMode && m_singletonId.empty())
815 {
816 m_singletonId = m_id;
817 }
818 if (!m_singletonMode && !m_singletonId.empty())
819 {
820 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton mode requires both the mode set AND singletonId set");
821 }
822 if (m_singletonMode && (m_type != ChannelType::SHMEM_LOCAL))
823 {
824 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton mode is only valid for SHMEM_LOCAL channels");
825 }
826 }
827
828 void adjustPoolCapacity()
829 {
830 // This deserves a comment. The LocalShmem pools (in the fifo-case)
831 // need the following number of slots, in the worst case:
832 // 1 for getImpl to return at any time
833 // 1 per consumer for in-flight data
834 // fifo-size to store a full fifo worth of packets
835 // So assuming max consumers, we'd need fifo-size + MAX_CHANNEL_CONSUMERS_COUNT + 1
836 // coverity[autosar_cpp14_a4_7_1_violation]
837 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
838 // coverity[cert_int30_c_violation]
839 if (m_fifoSize + MAX_CHANNEL_CONSUMERS_COUNT + 1U > m_poolCapacity)
840 {
841 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
842 m_poolCapacity = m_fifoSize + MAX_CHANNEL_CONSUMERS_COUNT + 1U;
843 }
844 }
845
846private:
847 ChannelParamStr m_str{};
848 ChannelParamStr m_id{};
849 ChannelParamStr m_singletonId{};
850
851 // fifo size of the socket client that implies the maximum number of packets
852 // a client can hold simultaneously
853 size_t m_fifoSize{1U};
854 // This deserves a comment. The LocalShmem pools (in the fifo-case)
855 // need the following number of slots, in the worst case:
856 // 1 for getImpl to return at any time
857 // 1 per consumer for in-flight data
858 // fifo-size to store a full fifo worth of packets
859 // So assuming a fifo-size of 1 and max consumers, we'd need MAX_CHANNEL_CONSUMERS_COUNT + 2
860 size_t m_poolCapacity{MAX_CHANNEL_CONSUMERS_COUNT + 2U};
862 uint32_t m_dataOffset{0U};
863 uint32_t m_uid{0U};
864 uint32_t m_connectGroupID{0U};
865 bool m_syncEnabled{false};
866 bool m_mailboxMode{false};
867 bool m_singletonMode{false};
868 bool m_reuseEnabled{false};
870 ChannelType m_type{ChannelType::SHMEM_LOCAL};
871 bool m_strictFifo{true};
872
873 uint16_t m_clientsCount{1U}; // number of clients for blocking mode for socket
874 uint16_t m_debugClientsCount{1U}; // number of debug clients for blocking mode for socket
875
876 uint16_t m_debugPort{0U};
877
878 ChannelSocketParams m_socketParams{};
879 ChannelNvSciStreamParams m_nvSciStreamParams{};
880};
881
882} // namespace framework
883} // namespace dw
884
885#endif // DW_FRAMEWORK_CHANNEL_HPP_
ChannelNvSciStreamParams & operator=(const ChannelNvSciStreamParams &other)=default
int64_t getLimiterMaxPackets(uint16_t index=0U) const
dw::core::VectorFixed< ChannelPeerLocation, 32 > m_lateLocs
ChannelNvSciStreamParams(const ChannelNvSciStreamParams &other)=default
dw::core::span< ChannelPeerLocation const > getLateLocs() const
const char * getStreamName(uint16_t index=0) const
dw::core::VectorFixed< dw::core::FixedString< 64 >, 8 > m_streamNames
dw::core::VectorFixed< int64_t, 8 > m_limits
void setMailboxMode(bool mailboxEnabled)
uint16_t getExpectedConnectionsCount() const
uint16_t getExpectedDebugConnectionsCount() const
ChannelParams & operator=(const ChannelParams &other)=default
const ChannelSocketParams & getSocketParams() const
const ChannelNvSciStreamParams & getNvSciStreamParams() const
ChannelParamStr getSingletonId() const
void setStrictFifo(bool strictFifo)
ChannelParams(const ChannelParams &other)
ChannelParamStr getId() const
dw::core::FixedString< 8 > getSockPrefix() const
ChannelSocketParams & operator=(const ChannelSocketParams &other)=default
ChannelSocketParams(const ChannelSocketParams &other)=default
static ChannelParamStr getParamStr(const char *serverIP, uint16_t port, bool producerFifo=false, uint16_t numBlockingConnections=1U, dw::core::FixedString< 8 > const sockPrefix=dw::core::FixedString< 8 >())
static const char * ToParam(ChannelType channelType)
static constexpr uint16_t MAX_CHANNEL_ALL_PARAMS_SIZE
dw::core::FixedString< MAX_CHANNEL_PARAM_SIZE > ChannelParamStr
@ DW_CHANNEL_ROLE_PRODUCER
allows producer only
@ DW_CHANNEL_ROLE_CONSUMER
allows consumer only
@ DW_CHANNEL_ROLE_COMPOSITE
allows both producer and consumer
static void ParseChannelParameters(const ChannelParamStr &, const ChannelParamStr &)
constexpr bool IsProducer(ChannelRole role)
static T ParseChannelParameter(const ChannelParamStr &value)
constexpr ChannelNvSciStreamEnabledComponents operator&(ChannelNvSciStreamEnabledComponents a, ChannelNvSciStreamEnabledComponents b)
constexpr ChannelNvSciStreamEnabledComponents operator|(ChannelNvSciStreamEnabledComponents a, ChannelNvSciStreamEnabledComponents b)
static void ParseAllChannelParameters(const ChannelParamStr &channelParams, Others &&... others)
static constexpr uint16_t MAX_CHANNEL_PARAM_SIZE
enum class ChannelType :uint8_t { SHMEM_LOCAL=0, SHMEM_REMOTE=1, EGLSTREAM=2, SOCKET=3, DDS=4, NVSCI=5, } ChannelType
constexpr bool IsConsumer(ChannelRole role)
static constexpr uint16_t MAX_CHANNEL_PRODUCERS_COUNT
static constexpr uint16_t MAX_CHANNEL_CONSUMERS_COUNT
Definition: Buffer.hpp:40