2025-05-10 21:58:58 +08:00

120 lines
4.4 KiB
C++

/*
* Copyright 2020 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* src author: <mediapipe-team@google.com>
* new author: modified by <rimon.xu@rock-chips.com> and <martin.cheng@rock-chips.com>
* date: 2020-03-19
* reference: https://github.com/google/mediapipe
*/
#ifndef SRC_RT_TASK_TASK_GRAPH_RTEXECUTOR_H_
#define SRC_RT_TASK_TASK_GRAPH_RTEXECUTOR_H_
#include "rt_header.h"
#include "RTThreadOptions.h"
#include "RTThreadPool.h"
#include "rt_metadata.h"
// Abstract base class for the task queue.
// NOTE: The task queue orders the ready tasks by their priorities. This
// enables the executor to run ready tasks in priority order.
class RTTaskQueue {
public:
virtual ~RTTaskQueue();
// Runs the next ready task in the current thread. Should be invoked by the
// executor. This method should be called exactly as many times as AddTask
// was called on the executor.
virtual void runNextTask() = 0;
};
// Abstract base class for the RTExecutor.
class RTExecutor {
public:
virtual ~RTExecutor();
// A registered RTExecutor subclass must implement the static factory method
// Create. The RTExecutor subclass cannot be registered without it.
//
// static ::mediapipe::StatusOr<RTExecutor*> Create(
// const MediaPipeOptions& extendable_options);
//
// Create validates extendable_options, then calls the constructor, and
// returns the newly allocated RTExecutor object.
// The scheduler queue calls this method to tell the executor that it has
// a new task to run. The executor should use its execution mechanism to
// invoke taskQueue->runNextTask.
virtual void addTask(RTTaskQueue* taskQueue, INT32 threadId = 0) {
schedule([taskQueue] { taskQueue->runNextTask(); }, threadId);
}
// schedule the specified "task" for execution in this executor.
virtual void schedule(std::function<void()> task, INT32 threadId = 0) = 0;
virtual INT32 getNumThreads() const = 0;
};
// A multithreaded executor based on a thread pool.
class RTThreadPoolExecutor : public RTExecutor {
public:
static RTExecutor* create(RtMetaData *extendOptions);
explicit RTThreadPoolExecutor(INT32 numThreads);
explicit RTThreadPoolExecutor(const RTThreadOptions& threadOptions, INT32 numThreads,
RTThreadPoolMode mode = RT_THREAD_POOL_RANDOM_MODE);
~RTThreadPoolExecutor() override;
public:
void schedule(std::function<void()> task, INT32 threadId = 0) override;
INT32 getNumThreads() const { return mThreadPool.getNumThreads(); }
// Returns the thread stack size (in bytes).
size_t getStackSize() const { return mStackSize; }
private:
// Saves the value of the stack size option and starts the thread pool.
void start();
RTThreadPool mThreadPool;
// Records the stack size in RTThreadOptions right before we call
// mThreadPool.startWorkers().
//
// The actual stack size passed to pthread_attr_setstacksize() for the
// worker threads differs from the stack size we specified. It includes the
// guard size and space for thread-local storage. (See Thread::start() in
// thread/thread.cc.) So the unit tests check the stack size in
// RTThreadOptions, in addition to trying to recover the specified stack
// size from the stack size returned by pthread_getattr_np(),
// pthread_attr_getstacksize(), and pthread_attr_getguardsize().
size_t mStackSize = 0;
};
class RTSingleExecutor : public RTExecutor {
public:
static RTExecutor* create(void *extendOptions);
explicit RTSingleExecutor(const RTThreadOptions& threadOptions);
~RTSingleExecutor() override;
void schedule(std::function<void()> task, INT32 threadId = 0) override;
INT32 getNumThreads() const { return 1; }
private:
RTThreadPool mThreadPool;
};
#endif // SRC_RT_TASK_TASK_GRAPH_RTEXECUTOR_H_