mirror of
git://nv-tegra.nvidia.com/tegra/nv-sci-src/nvsci_samples.git
synced 2025-12-22 09:21:21 +03:00
Updating prebuilts and/or headers
2eba699906039d6615aae4967f6ea79bfe44a40a - event_sample_app/block_pool.c f3abb0a884f0647204ad32ff51255c4712e52120 - event_sample_app/Makefile 9ee49033e077ac5c8bf458a04c91dd3dbed9633d - event_sample_app/event_loop.h b33adce6eb1bbc7af23f6c37b6a635479e18a66a - event_sample_app/block_returnsync.c a56041c06b6bc1d3812b72b399d7d78dd7895485 - event_sample_app/block_limiter.c ca34c957759f7a010f0cbbbf9bedc03a2c98092b - event_sample_app/block_c2c.c 8d6d0ec3aa8e374a1d2a5fedc9dd24ff7bbdb731 - event_sample_app/block_multicast.c a76149a2531899e35843d939f60ad8979d8cf65f - event_sample_app/block_consumer_uc1.c 9da8763e4af4b4b7278507a3ebfe2c68a7a24585 - event_sample_app/util.h 2bf7e1383d6e8913c9b0a6a8bdd48fe63d8098d0 - event_sample_app/block_producer_uc1.c a54abf82eaa2d888e379ab4596ba68ce264e80b5 - event_sample_app/block_info.h 080a6efe263be076c7046e70e31098c2bbed0f6d - event_sample_app/block_presentsync.c 7dd10e5ea71f0c4a09bbe1f9f148f67a13ee098c - event_sample_app/util.c bc1a6f9017b28e5707c166a658a35e6b3986fdf4 - event_sample_app/usecase1.h 317f43efc59638bf1eae8303f0c79eafb059241a - event_sample_app/block_ipc.c 40361c8f0b68f7d5207db2466ce08c19c0bf1c90 - event_sample_app/event_loop_service.c efad113d0107e5d8f90146f3102a7c0ed22f1a35 - event_sample_app/event_loop_threads.c 2908615cebcf36330b9850c57e8745bf324867b2 - event_sample_app/block_queue.c 36ed68eca1a7800cf0d94e763c9fc352ee8cda1e - event_sample_app/block_common.c 675f75d61bd0226625a8eaaf0e503c9e976c8d61 - event_sample_app/main.c c3b26619dd07d221e953fc5dc29a50dcb95a8b97 - rawstream/Makefile 1fbb82e2281bb2e168c87fd20903bbed898ca160 - rawstream/rawstream_cuda.c 1d96498fe3c922f143f7e50e0a32b099714060ad - rawstream/rawstream_consumer.c d077dafc9176686f6d081026225325c2a303a60e - rawstream/rawstream_producer.c 54ae655edddda7dcabe22fbf0b27c3f617978851 - rawstream/rawstream.h d5ffeef3c7ad2af6f6f31385db7917b5ef9a7438 - rawstream/rawstream_ipc_linux.c 81e3d6f8ff5252797a7e9e170b74df6255f54f1b - rawstream/rawstream_main.c Change-Id: I0f4e671693eb0addfe8d0e6532cc8f240cb6c778
This commit is contained in:
279
event_sample_app/block_common.c
Normal file
279
event_sample_app/block_common.c
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NvSciStream Event Loop Driven Sample App - common block event handling
|
||||
*
|
||||
* Block types which do not require type-specific interactions make use of
|
||||
* this common code.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#if (QNX == 1)
|
||||
#include <sys/neutrino.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include "nvscistream.h"
|
||||
#include "block_info.h"
|
||||
#include "event_loop.h"
|
||||
|
||||
/* Variable indicates whether the thread handling the
|
||||
* late consumer connetions is started or not
|
||||
*/
|
||||
static bool threadStarted = false;
|
||||
|
||||
/* Delete common block */
|
||||
void deleteCommon(
|
||||
void* data)
|
||||
{
|
||||
BlockData* blockData = (BlockData*)data;
|
||||
|
||||
/* Destroy block */
|
||||
if (blockData->block != 0) {
|
||||
(void)NvSciStreamBlockDelete(blockData->block);
|
||||
}
|
||||
|
||||
/* Check if it is late/re-attach usecase */
|
||||
if (opts.numLateConsumer > 0U) {
|
||||
/* Close the endpoints used by the IpcSrc/C2CSrc
|
||||
* blocks for next late-/re-attach consumer connection
|
||||
*/
|
||||
pthread_mutex_lock(&mutex);
|
||||
if ((!strcmp(blockData->name, "IpcSrc")) ||
|
||||
(!strcmp(blockData->name, "C2cSrc"))) {
|
||||
for (uint32_t i=0; i< MAX_CONSUMERS; i++) {
|
||||
if (ipcEP[i].ipcBlock == blockData->block) {
|
||||
/* close the Ipc endpoint */
|
||||
if (ipcEP[i].ipcEndpoint) {
|
||||
#if (QNX == 1)
|
||||
if (ipcEP[i].coid != 0) {
|
||||
(void)ConnectDetach_r(ipcEP[i].coid);
|
||||
ipcEP[i].coid = 0;
|
||||
}
|
||||
if (ipcEP[i].chid != 0) {
|
||||
(void)ChannelDestroy_r(ipcEP[i].chid);
|
||||
ipcEP[i].chid = 0;
|
||||
}
|
||||
#endif
|
||||
if (NvSciError_Success !=
|
||||
NvSciIpcCloseEndpointSafe(ipcEP[i].ipcEndpoint, false)) {
|
||||
printf("Failed to close ipc endpoint\n");
|
||||
}
|
||||
sleep(2);
|
||||
ipcEP[i].ipcEndpoint = 0U;
|
||||
}
|
||||
/* close the C2C endpoint */
|
||||
if (ipcEP[i].c2cEndpoint) {
|
||||
if (NvSciError_Success !=
|
||||
NvSciIpcCloseEndpointSafe(ipcEP[i].c2cEndpoint, false)) {
|
||||
printf("Failed to close ipc endpoint\n");
|
||||
}
|
||||
ipcEP[i].c2cEndpoint = 0U;
|
||||
}
|
||||
|
||||
/* clear the informaton as this is needed
|
||||
* for next late-/re-attach connection
|
||||
*/
|
||||
ipcEP[i].ipcBlock = 0U;
|
||||
ipcEP[i].ipcConnected = false;
|
||||
ipcEP[i].c2cConnected = false;
|
||||
ipcEP[i].ipcOpened = false;
|
||||
ipcEP[i].c2cOpened = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Wakeup the thread to handle the next set of
|
||||
* late-/re-attach consumer connections
|
||||
*/
|
||||
pthread_cond_signal(&cond);
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
/* Free data */
|
||||
free(blockData);
|
||||
}
|
||||
|
||||
/* Handle events on a common block
|
||||
*
|
||||
* Blocks that don't require interaction after connection usually just
|
||||
* receive notification of connection and disconnection.
|
||||
*/
|
||||
int32_t handleCommon(
|
||||
void* data,
|
||||
uint32_t wait)
|
||||
{
|
||||
/* Cast to common data */
|
||||
BlockData* blockData = (BlockData*)data;
|
||||
|
||||
/* Get time to wait */
|
||||
int64_t waitTime = wait ? blockData->waitTime : 0;
|
||||
|
||||
/* Query/wait for an event on the block */
|
||||
|
||||
NvSciStreamEventType event;
|
||||
NvSciError err;
|
||||
err = NvSciStreamBlockEventQuery(blockData->block, waitTime, &event);
|
||||
|
||||
/* Handle errors */
|
||||
if (NvSciError_Success != err) {
|
||||
|
||||
/* If not asked to wait, a timeout is not an error */
|
||||
if (!waitTime && (NvSciError_Timeout == err)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, any error is considered fatal. A timeout probably
|
||||
* indicates a failure to connect and complete setup in a timely
|
||||
* fashion, so we specifically call out this case.
|
||||
*/
|
||||
if (NvSciError_Timeout == err) {
|
||||
printf("%s timed out waiting for setup instructions\n",
|
||||
blockData->name);
|
||||
} else {
|
||||
printf("%s event query failed with error %x\n",
|
||||
blockData->name, err);
|
||||
}
|
||||
blockData->deleteFunc(blockData);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If we received an event, handle it based on its type */
|
||||
int32_t rv = 1;
|
||||
NvSciError status;
|
||||
switch (event) {
|
||||
|
||||
/*
|
||||
* Any event we don't explicitly handle is a fatal error
|
||||
*/
|
||||
default:
|
||||
printf("%s received unknown event %x\n",
|
||||
blockData->name, event);
|
||||
|
||||
rv = -1;
|
||||
break;
|
||||
|
||||
/*
|
||||
* Error events should never occur with safety-certified drivers,
|
||||
* and are provided only in non-safety builds for debugging
|
||||
* purposes. Even then, they should only occur when something
|
||||
* fundamental goes wrong, like the system running out of memory,
|
||||
* or stack/heap corruption, or a bug in NvSci which should be
|
||||
* reported to NVIDIA.
|
||||
*/
|
||||
case NvSciStreamEventType_Error:
|
||||
err = NvSciStreamBlockErrorGet(blockData->block, &status);
|
||||
if (NvSciError_Success != err) {
|
||||
printf("%s Failed to query the error event code %x\n",
|
||||
blockData->name, err);
|
||||
rv = -1;
|
||||
} else {
|
||||
if ((opts.numLateConsumer > 0U) &&
|
||||
(status == NvSciError_StreamNotConnected)) {
|
||||
printf("[WARN] %s received error event: %x\n",
|
||||
blockData->name, status);
|
||||
rv = 2;
|
||||
} else {
|
||||
printf("%s received error event: %x\n",
|
||||
blockData->name, status);
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* If told to disconnect, it means either the stream finished its
|
||||
* business or some other block had a failure. We'll just do a
|
||||
* clean up and return without an error.
|
||||
*/
|
||||
case NvSciStreamEventType_Disconnected:
|
||||
rv = 2;
|
||||
break;
|
||||
|
||||
/*
|
||||
* The block doesn't have to do anything on connection, but now we may
|
||||
* wait forever for any further events, so the timeout becomes infinite.
|
||||
*/
|
||||
case NvSciStreamEventType_Connected:
|
||||
/* Query producer and consumer(s) endpoint info if needed */
|
||||
blockData->waitTime = -1;
|
||||
break;
|
||||
|
||||
/* All setup complete. Transition to runtime phase */
|
||||
case NvSciStreamEventType_SetupComplete:
|
||||
if (opts.numLateConsumer > 0U) {
|
||||
/* Check if it is multicast block */
|
||||
if (!strcmp(blockData->name, "Multicast")) {
|
||||
/* Wakeup the thread to handle the next set
|
||||
* of late-/re-attach consumer connections
|
||||
*/
|
||||
pthread_cond_signal(&cond);
|
||||
if (!threadStarted) {
|
||||
threadStarted = true;
|
||||
/* Spawn a thread to handle the late attach connections */
|
||||
int32_t status = pthread_create(&dispatchThread,
|
||||
NULL,
|
||||
handleLateConsumerThreadFunc,
|
||||
NULL);
|
||||
if (status != 0) {
|
||||
printf("Failed to spawn thread to monitor late consumer connections\n");
|
||||
/* Abort the process as this thread is important
|
||||
* to process the late-/re-attach consumer connections.
|
||||
* Failed to create this thread makes the late/re-attach usecase
|
||||
* unusable.
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* On failure or final event, clean up the block */
|
||||
if ((rv < 0) || (1 < rv)) {
|
||||
blockData->deleteFunc(blockData);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Create and register a new common block */
|
||||
BlockData* createCommon(
|
||||
char const* name,
|
||||
size_t size)
|
||||
{
|
||||
/* If no size specified, just use BlockData */
|
||||
if (0 == size) {
|
||||
size = sizeof(BlockData);
|
||||
}
|
||||
|
||||
/* Create a data structure to track the block's status */
|
||||
BlockData* commonData = (BlockData*)calloc(1, size);
|
||||
if (NULL == commonData) {
|
||||
printf("Failed to allocate data structure for %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Save the name for debugging purposes */
|
||||
strcpy(commonData->name, name);
|
||||
|
||||
/* Wait time for initial connection event will be 60 seconds */
|
||||
commonData->waitTime = 60 * 1000000;
|
||||
|
||||
/* Use the common delete function */
|
||||
commonData->deleteFunc = deleteCommon;
|
||||
|
||||
return commonData;
|
||||
}
|
||||
Reference in New Issue
Block a user