1 /*
2 * Copyright (c) 2019, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file frame_tracker.h
24 //! \brief Manages the multiple trackers in one place.
25 //!
26
27 #ifndef __FRAME_TRACKER_H__
28 #define __FRAME_TRACKER_H__
29
30 #include "mos_os.h"
31 #include <map>
32
33 #define MAX_TRACKER_NUMBER 64
34 #define CHK_INDEX(index) if ((index) >= MAX_TRACKER_NUMBER) {return MOS_STATUS_NOT_ENOUGH_BUFFER; }
35
36 class FrameTrackerToken;
37 class FrameTrackerProducer;
38
39 // C-style struct for FrameTrackerToken
40 // for tokens that embeded in a struct other than a class
41 // in legacy DSH code, the token is always embeded in another struct
42 struct FrameTrackerTokenFlat
43 {
44 FrameTrackerProducer *producer;
45 uint32_t trackers[MAX_TRACKER_NUMBER];
46 bool valid;
47 bool stick;
48 };
49
50 bool FrameTrackerTokenFlat_IsExpired(const FrameTrackerTokenFlat *self);
51
FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat * self,uint32_t index,uint32_t tracker)52 static inline void FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat *self, uint32_t index, uint32_t tracker)
53 {
54 if (index < MAX_TRACKER_NUMBER && tracker != 0)
55 {
56 self->trackers[index] = tracker;
57 }
58 }
59
FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat * self,const FrameTrackerTokenFlat * token)60 static inline void FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat *self, const FrameTrackerTokenFlat *token)
61 {
62 self->producer = token->producer;
63 for (int i = 0; i < MAX_TRACKER_NUMBER; i++)
64 {
65 if (token->trackers[i] != 0)
66 {
67 FrameTrackerTokenFlat_Merge(self, i, token->trackers[i]);
68 }
69 }
70 }
71
FrameTrackerTokenFlat_SetProducer(FrameTrackerTokenFlat * self,FrameTrackerProducer * producer)72 static inline void FrameTrackerTokenFlat_SetProducer(FrameTrackerTokenFlat *self, FrameTrackerProducer *producer)
73 {
74 self->producer = producer;
75 }
76
FrameTrackerTokenFlat_Clear(FrameTrackerTokenFlat * self)77 static inline void FrameTrackerTokenFlat_Clear(FrameTrackerTokenFlat *self)
78 {
79 self->stick = false;
80 MOS_ZeroMemory(self->trackers, sizeof(self->trackers));
81 }
82
FrameTrackerTokenFlat_Validate(FrameTrackerTokenFlat * self)83 static inline void FrameTrackerTokenFlat_Validate(FrameTrackerTokenFlat *self)
84 {
85 self->valid = true;
86 }
87
FrameTrackerTokenFlat_Invalidate(FrameTrackerTokenFlat * self)88 static inline void FrameTrackerTokenFlat_Invalidate(FrameTrackerTokenFlat *self)
89 {
90 self->valid = false;
91 }
92
FrameTrackerTokenFlat_IsValid(const FrameTrackerTokenFlat * self)93 static inline bool FrameTrackerTokenFlat_IsValid(const FrameTrackerTokenFlat *self)
94 {
95 return self->valid;
96 }
97
FrameTrackerTokenFlat_Stick(FrameTrackerTokenFlat * self)98 static inline void FrameTrackerTokenFlat_Stick(FrameTrackerTokenFlat *self)
99 {
100 self->stick = true;
101 }
102
103 class FrameTrackerProducer
104 {
105 public:
106 FrameTrackerProducer();
107 ~FrameTrackerProducer();
108
109 MOS_STATUS Initialize(MOS_INTERFACE *osInterface);
110
111 int AssignNewTracker();
112
GetLatestTrackerResource(uint32_t index,MOS_RESOURCE ** resource,uint32_t * offset)113 inline void GetLatestTrackerResource(uint32_t index, MOS_RESOURCE **resource, uint32_t *offset)
114 {
115 *resource = &m_resource;
116 *offset = index * m_trackerSize;
117 }
118
GetLatestTrackerAddress(uint32_t index)119 inline volatile uint32_t *GetLatestTrackerAddress(uint32_t index)
120 {
121 return (uint32_t *)((uint8_t *)m_resourceData + index * m_trackerSize);
122 }
123
GetNextTracker(uint32_t index)124 inline uint32_t GetNextTracker(uint32_t index) { return m_counters[index];}
125
StepForward(uint32_t index)126 inline MOS_STATUS StepForward(uint32_t index)
127 {
128 CHK_INDEX(index);
129 ++ m_counters[index];
130 if (m_counters[index] == 0)
131 {
132 m_counters[index] = 1;
133 }
134 return MOS_STATUS_SUCCESS;
135 }
136
137 protected:
138 // indexes to assign a new tracer
139 uint32_t m_nextTrackerIndex;
140 bool m_trackerInUse[MAX_TRACKER_NUMBER];
141
142 // resource
143 static const uint32_t m_trackerSize = 8; // reserved two dwords for each tracker
144 MOS_RESOURCE m_resource;
145 uint32_t *m_resourceData;
146
147 // counters
148 uint32_t m_counters[MAX_TRACKER_NUMBER];
149
150 // interfaces
151 MOS_INTERFACE *m_osInterface;
152 };
153
154 class FrameTrackerToken
155 {
156 public:
FrameTrackerToken()157 FrameTrackerToken():
158 m_producer(nullptr)
159 {
160 }
161
~FrameTrackerToken()162 ~FrameTrackerToken()
163 {
164 }
165
IsExpired()166 bool IsExpired()
167 {
168 if (m_producer == nullptr)
169 {
170 return true;
171 }
172
173 for (auto ite = m_holdTrackers.begin(); ite != m_holdTrackers.end(); ite ++)
174 {
175 uint32_t index = ite->first;
176 volatile uint32_t latestTracker = *(m_producer->GetLatestTrackerAddress(index));
177 uint32_t holdTracker = ite->second;
178 if ((int)(holdTracker - latestTracker) > 0)
179 {
180 return false;
181 }
182 }
183 return true;
184 }
185
186 void Merge(const FrameTrackerToken *token);
187
Merge(uint32_t index,uint32_t tracker)188 inline void Merge(uint32_t index, uint32_t tracker) {m_holdTrackers[index] = tracker; }
189
SetProducer(FrameTrackerProducer * producer)190 inline void SetProducer(FrameTrackerProducer *producer)
191 {
192 m_producer = producer;
193 }
194
Clear()195 inline void Clear() {m_holdTrackers.clear(); }
196
197 protected:
198 FrameTrackerProducer *m_producer;
199 std::map<uint32_t, uint32_t> m_holdTrackers;
200 };
201
202 #endif // __FRAME_TRACKER_H__
203