Files
nvsci_samples/event_sample_app/event_loop_threads.c
svcmobrel-release e42833bdf1 Updating prebuilts and/or headers
1158201e78094e9e866fa99095c9ffc2ec9f5a27 - event_sample_app/block_limiter.c
a71ed037f9d77d0944f40f54cf25db8180d007e2 - event_sample_app/block_queue.c
ced622a41d1a48dcb23e6a1a02ae9640ef9b837c - event_sample_app/util.h
a0bd135d707994a41ed3a4234b5f875a268fed4d - event_sample_app/Makefile
d7e42e2b6088ff4596abc7256eb018d757a4021e - event_sample_app/usecase1.h
f5e2aea98ba9264ee1068a700222dff8d5d5c7a4 - event_sample_app/block_c2c.c
dac99c442185b020fbdae07bfc1e7df78343eb83 - event_sample_app/block_info.h
5001f036389a4f7952cb4974dd3323908208ca30 - event_sample_app/event_loop_threads.c
8193be73ce0a488f62034cb87083cdf09f52cd5d - event_sample_app/block_pool.c
3a1013021a572887303fb6db245b5b01fe07e9a0 - event_sample_app/block_producer_uc1.c
6ff0f1c2d7ef2e2fa9ece6fdc850b58b87207526 - event_sample_app/block_returnsync.c
e0861e9fe5d160d47d758464146d7192f9c70a5f - event_sample_app/util.c
b5dd68bec3ae6f9049aad1cb5a86c3db4af02e17 - event_sample_app/block_presentsync.c
b52e34443ac441a9df48029de944aa0a50d1b101 - event_sample_app/event_loop_service.c
ef057870dade9af70656b37340e9bcad35d49380 - event_sample_app/block_multicast.c
65ffe5af6ae6bc0418f348167c473849d4697e47 - event_sample_app/block_ipc.c
44f6de348f8bdd5cb584b3e8cc4b05e9482dddd2 - event_sample_app/event_loop.h
40f949c4c37ab4aa4a84182b345f3de6fceab39b - event_sample_app/main.c
641e3634da873970b574b23a1024b2e7155b88ff - event_sample_app/block_consumer_uc1.c
d6bbd17599543f1760d87851150a12a2a842a24d - event_sample_app/block_common.c
1fbb82e2281bb2e168c87fd20903bbed898ca160 - rawstream/rawstream_cuda.c
458833ab233a725c067bf9b1fc60ef39872eee80 - rawstream/Makefile
3df4e5c00a3dc002ee9877e282bd28ffa87fa6f0 - rawstream/rawstream.h
d5ffeef3c7ad2af6f6f31385db7917b5ef9a7438 - rawstream/rawstream_ipc_linux.c
f28c1cd5fe26b6dc5930d5556b54364c9b91767c - rawstream/rawstream_main.c
2bed038ca070aa5dccd6b672a98f093340e829bb - rawstream/rawstream_producer.c
e26c09f1ad1a3a7d2c29dae1b38d3fd90c23af6e - rawstream/rawstream_consumer.c

Change-Id: Iec84f03094414392580a103d2bc94bac8ed86fbb
2024-05-02 11:24:59 -07:00

127 lines
3.9 KiB
C

/* NvSciStream Event Loop Driven Sample App - thread-based event handling
*
* Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* 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.
*/
/*
* This file implements the option to handle events for each block in
* a separate thread. Each thread just has a loop that waits for a
* block event to occur and handles it appropriately, until the block
* has performed all required actions or receives notification that
* the stream has disconnected.
*
* In practice, only a few block types (producer, consumer, and pool)
* receive any events that need to be handled. So a more streamlined
* application might choose to only monitor them, assuming that the
* other blocks can be left alone until the time comes to tear them
* down.
*
* Note: We use standard pthread functions here because it allows this
* sample to run on all operating systems. QNX has its own thread
* management functions which might be more efficient when using
* this approach.
*/
#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
#include "event_loop.h"
/* Structure to track block info */
typedef struct {
NvSciStreamBlock handle;
void* data;
BlockFunc func;
pthread_t thread;
} BlockEventData;
/* List of blocks */
#define MAX_BLOCKS 100U
static uint32_t numBlocks = 0U;
static BlockEventData blocks[MAX_BLOCKS];
static uint32_t success = 1U;
/* The per-thread loop function for each block */
static void* eventThreadFunc(void* arg)
{
/* Simple loop, waiting for events on the block until the block is done */
BlockEventData* entry = (BlockEventData*)arg;
while (1) {
int32_t rv = entry->func(entry->data, 1);
if (rv < 0) {
success = 0U;
break;
} else if (rv == 2) {
break;
}
}
return NULL;
}
/* Initialize per-thread event handling */
static int32_t eventThreadInit(void)
{
/* No special initialization required for this method */
return 1;
}
/* Register a new block with the event management */
static int32_t eventThreadRegister(
NvSciStreamBlock blockHandle,
void* blockData,
BlockFunc blockFunc)
{
/* Sanity check to make sure we left room for enough blocks */
if (numBlocks >= MAX_BLOCKS) {
printf("Exceeded maximum number of blocks\n");
return 0;
}
/* Grab the next entry in the list for the new block and fill it in */
BlockEventData* entry = &blocks[numBlocks++];
entry->handle = blockHandle;
entry->data = blockData;
entry->func = blockFunc;
/* Spawn a thread */
int32_t rv = pthread_create(&entry->thread,
NULL,
eventThreadFunc,
(void*)entry);
if (rv != 0) {
printf("Failed to spawn thread to monitor block\n");
return 0;
}
return 1;
}
/* Main per-thread event loop */
static int32_t eventThreadLoop(void)
{
/*
* Each block has its own thread loop. This main function just needs
* to wait for all of them to exit, and then return any error. This
* waiting can be done in any order.
*/
for (uint32_t i=0; i<numBlocks; ++i) {
(void)pthread_join(blocks[i].thread, NULL);
}
return success;
}
/* Table of functions for per-thread event handling */
EventFuncs const eventFuncs_Threads = {
.init = eventThreadInit,
.reg = eventThreadRegister,
.loop = eventThreadLoop
};