aboutsummaryrefslogtreecommitdiff
path: root/RequestThread.hpp
blob: 79f309a32ecb6b38998bd24cf1a9a2654a026606 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>

#include "ArmnnDriver.hpp"
#include "ArmnnDriverImpl.hpp"

#include <CpuExecutor.h>
#include <armnn/ArmNN.hpp>

namespace armnn_driver
{
using TimePoint = std::chrono::steady_clock::time_point;
static const TimePoint g_Min = std::chrono::steady_clock::time_point::min();

template<template <typename HalVersion> class PreparedModel, typename HalVersion, typename CallbackContext>
class RequestThread
{
public:
    /// Constructor creates the thread
    RequestThread();

    /// Destructor terminates the thread
    ~RequestThread();

    /// Add a message to the thread queue.
    /// @param[in] model pointer to the prepared model handling the request
    /// @param[in] memPools pointer to the memory pools vector for the tensors
    /// @param[in] inputTensors pointer to the input tensors for the request
    /// @param[in] outputTensors pointer to the output tensors for the request
    /// @param[in] callback the android notification callback
    void PostMsg(PreparedModel<HalVersion>* model,
                 std::shared_ptr<std::vector<::android::nn::RunTimePoolInfo>>& memPools,
                 std::shared_ptr<armnn::InputTensors>& inputTensors,
                 std::shared_ptr<armnn::OutputTensors>& outputTensors,
                 CallbackContext callbackContext);

private:
    RequestThread(const RequestThread&) = delete;
    RequestThread& operator=(const RequestThread&) = delete;

    /// storage for a prepared model and args for the asyncExecute call
    struct AsyncExecuteData
    {
        AsyncExecuteData(PreparedModel<HalVersion>* model,
                         std::shared_ptr<std::vector<::android::nn::RunTimePoolInfo>>& memPools,
                         std::shared_ptr<armnn::InputTensors>& inputTensors,
                         std::shared_ptr<armnn::OutputTensors>& outputTensors,
                         CallbackContext callbackContext)
            : m_Model(model)
            , m_MemPools(memPools)
            , m_InputTensors(inputTensors)
            , m_OutputTensors(outputTensors)
            , m_CallbackContext(callbackContext)
        {
        }

        PreparedModel<HalVersion>* m_Model;
        std::shared_ptr<std::vector<::android::nn::RunTimePoolInfo>> m_MemPools;
        std::shared_ptr<armnn::InputTensors> m_InputTensors;
        std::shared_ptr<armnn::OutputTensors> m_OutputTensors;
        CallbackContext m_CallbackContext;
    };
    enum class ThreadMsgType
    {
        EXIT,                   // exit the thread
        REQUEST                 // user request to process
    };

    /// storage for the thread message type and data
    struct ThreadMsg
    {
        ThreadMsg(ThreadMsgType msgType,
                  std::shared_ptr<AsyncExecuteData>& msgData)
            : type(msgType)
            , data(msgData)
        {
        }

        ThreadMsgType type;
        std::shared_ptr<AsyncExecuteData> data;
    };

    /// Add a prepared thread message to the thread queue.
    /// @param[in] threadMsg the message to add to the queue
    void PostMsg(std::shared_ptr<ThreadMsg>& pThreadMsg);

    /// Entry point for the request thread
    void Process();

    std::unique_ptr<std::thread> m_Thread;
    std::queue<std::shared_ptr<ThreadMsg>> m_Queue;
    std::mutex m_Mutex;
    std::condition_variable m_Cv;
};

} // namespace armnn_driver