Skip to content

Commit 6ebbc83

Browse files
committed
[c2][store] Add concurrent-instances support and fixed cts failures
cases: testLowerPriorityProcessFailsToReclaimResources testHigherPriorityProcessReclaimsResources * The creating component instances of the same type can't exceece the configured the number of maximum concurrent instances. * The default value is 32, you can configure it in xml file if you want. (e.g. `<Limit name="concurrent-instances" max="16" />`) Tracked-On: OAM-117236 Signed-off-by: zhangyichix <yichix.zhang@intel.com>
1 parent 7210e66 commit 6ebbc83

8 files changed

Lines changed: 185 additions & 0 deletions

File tree

c2_components/include/mfx_c2_component.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class MfxC2Component : public C2ComponentInterface,
3737
{
3838
int flags{0};
3939
bool dump_output{false};
40+
uint32_t concurrent_instances{0};
4041
};
4142
protected:
4243
/* State diagram:

c2_components/src/mfx_c2_component.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "mfx_debug.h"
2323
#include "mfx_c2_debug.h"
2424
#include "mfx_c2_components_registry.h"
25+
#include "mfx_c2_components_monitor.h"
2526

2627
using namespace android;
2728

@@ -303,6 +304,17 @@ c2_status_t MfxC2Component::start()
303304
MFX_DEBUG_TRACE_FUNC;
304305

305306
c2_status_t res = C2_OK;
307+
308+
MfxC2ComponentsMonitor::getInstance().increase(m_name.c_str());
309+
310+
// The creating component instances of the same type can't exceece the configured the number of maximum concurrent instances
311+
// And must ensure that C2_NO_MEMORY is returned by start() which because the reclaimResource calling happens in
312+
// MediaCodec::start() in libstagefright
313+
MFX_DEBUG_TRACE_I32(m_createConfig.concurrent_instances);
314+
if (MfxC2ComponentsMonitor::getInstance().get(m_name.c_str()) > m_createConfig.concurrent_instances) {
315+
MFX_DEBUG_TRACE_MSG("Cannot create component, the number of created components has exceeded maximum instance limit.");
316+
return C2_NO_MEMORY;
317+
}
306318
// work to be done for state change
307319
std::function<c2_status_t()> action = [] () { return C2_CORRUPTED; };
308320

@@ -339,6 +351,8 @@ c2_status_t MfxC2Component::start()
339351
}
340352
m_condStateStable.notify_all();
341353
}
354+
} else {
355+
MfxC2ComponentsMonitor::getInstance().decrease(m_name.c_str());
342356
}
343357

344358
MFX_DEBUG_TRACE__android_c2_status_t(res);
@@ -449,6 +463,9 @@ c2_status_t MfxC2Component::release()
449463
}
450464
}
451465

466+
if (C2_OK == res) {
467+
MfxC2ComponentsMonitor::getInstance().decrease(m_name.c_str());
468+
}
452469
MFX_DEBUG_TRACE__android_c2_status_t(res);
453470
return res;
454471
}

c2_store/src/mfx_c2_store.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ c2_status_t MfxC2ComponentStore::readConfigFile()
314314
MfxC2Component::CreateConfig config;
315315
config.flags = flags;
316316
config.dump_output = m_xmlParser.dumpOutputEnabled(name.c_str());
317+
config.concurrent_instances = m_xmlParser.getConcurrentInstances(name.c_str());
317318

318319
m_componentsRegistry_.emplace(name, ComponentDesc(module.c_str(), media_type.c_str(), kind, config));
319320
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) 2017-2023 Intel Corporation
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in all
11+
// copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#pragma once
22+
23+
#include <string>
24+
#include <map>
25+
#include <mutex>
26+
#include "mfx_defs.h"
27+
28+
class MfxC2ComponentsMonitor
29+
{
30+
private:
31+
MfxC2ComponentsMonitor() {}
32+
public:
33+
MFX_CLASS_NO_COPY(MfxC2ComponentsMonitor);
34+
35+
static MfxC2ComponentsMonitor& getInstance()
36+
{
37+
static MfxC2ComponentsMonitor m_pInstance;
38+
return m_pInstance;
39+
}
40+
41+
unsigned int get(std::string name);
42+
void increase(std::string name);
43+
void decrease(std::string name);
44+
45+
private:
46+
std::map<std::string, unsigned int> m_monitor;
47+
std::mutex m_mutex;
48+
};

c2_utils/include/mfx_c2_xml_parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class MfxXmlParser
4949
c2_status_t parseConfig(const char *path);
5050
C2Component::kind_t getKind(const char *name);
5151
C2String getMediaType(const char *name);
52+
uint32_t getConcurrentInstances(const char *name);
5253
bool dumpOutputEnabled(const char *name);
5354

5455
private:
@@ -60,6 +61,7 @@ class MfxXmlParser
6061
size_t order; // order of appearance in the file (starting from 0)
6162
std::map<C2String, AttributeMap> typeMap; // map of types supported by this codec
6263
bool dump_output{false};
64+
uint32_t concurrentInstance{0};
6365
};
6466

6567
enum Section {
@@ -79,6 +81,8 @@ class MfxXmlParser
7981

8082
c2_status_t addDiagnostics(const char **attrs);
8183

84+
c2_status_t addLimits(const char **attrs);
85+
8286
void startElementHandler(const char *name, const char **attrs);
8387
void endElementHandler(const char *name);
8488

c2_utils/include/mfx_defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ extern mfxVersion g_required_mfx_version;
5959
#include <va/va.h>
6060
#endif // #ifdef LIBVA_SUPPORT
6161

62+
constexpr uint32_t DEFAULT_MAX_INSTANCES = 32;
63+
6264
#define MFX_MAX_PATH 260
6365

6466
#define WIDTH_16K 16384
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) 2017-2023 Intel Corporation
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in all
11+
// copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#include "mfx_c2_components_monitor.h"
22+
#include "mfx_c2_debug.h"
23+
24+
#undef MFX_DEBUG_MODULE_NAME
25+
#define MFX_DEBUG_MODULE_NAME "mfx_c2_components_monitor"
26+
27+
uint32_t MfxC2ComponentsMonitor::get(std::string name)
28+
{
29+
MFX_DEBUG_TRACE_FUNC;
30+
31+
std::unique_lock<std::mutex> lock(m_mutex);
32+
auto obj = m_monitor.find(name);
33+
if (m_monitor.end() != obj)
34+
{
35+
MFX_DEBUG_TRACE_I32(obj->second);
36+
return obj->second;
37+
}
38+
return 0;
39+
}
40+
41+
void MfxC2ComponentsMonitor::increase(std::string name)
42+
{
43+
MFX_DEBUG_TRACE_FUNC;
44+
45+
std::unique_lock<std::mutex> lock(m_mutex);
46+
auto obj = m_monitor.find(name);
47+
if (m_monitor.end() == obj)
48+
{
49+
MFX_DEBUG_TRACE_STREAM("increase " << name << ", instances 0 + 1");
50+
m_monitor.insert(std::pair<std::string, uint32_t>(name, 1));
51+
}
52+
else
53+
{
54+
MFX_DEBUG_TRACE_STREAM("increase " << name << ", instances " << obj->second << " + 1");
55+
obj->second++;
56+
}
57+
}
58+
59+
void MfxC2ComponentsMonitor::decrease(std::string name)
60+
{
61+
MFX_DEBUG_TRACE_FUNC;
62+
63+
std::unique_lock<std::mutex> lock(m_mutex);
64+
auto obj = m_monitor.find(name);
65+
if (m_monitor.end() == obj) // impossible
66+
{
67+
MFX_DEBUG_TRACE_MSG("can't find the record!");
68+
m_monitor.insert(std::pair<std::string, uint32_t>(name, 0));
69+
}
70+
else
71+
{
72+
MFX_DEBUG_TRACE_STREAM("decrease " << name << ", instances " << obj->second << " - 1");
73+
if (0 == obj->second)
74+
obj->second = 0;
75+
else
76+
obj->second--;
77+
}
78+
}

c2_utils/src/mfx_c2_xml_parser.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
*/
3737

3838
#include "mfx_c2_xml_parser.h"
39+
#include "mfx_defs.h"
3940
#include "mfx_c2_debug.h"
4041
#include <expat.h>
4142

@@ -81,6 +82,18 @@ C2Component::kind_t MfxXmlParser::getKind(const char *name) {
8182
return codec->second.isEncoder ? KIND_ENCODER : KIND_DECODER;
8283
}
8384

85+
uint32_t MfxXmlParser::getConcurrentInstances(const char *name) {
86+
MFX_DEBUG_TRACE_FUNC;
87+
88+
auto codec = m_codecMap.find(name);
89+
if (codec == m_codecMap.end() || 0 == codec->second.concurrentInstance) {
90+
MFX_DEBUG_TRACE_STREAM("concurrent-instances wasn't found, using default value " << DEFAULT_MAX_INSTANCES);
91+
return DEFAULT_MAX_INSTANCES;
92+
}
93+
94+
return codec->second.concurrentInstance;
95+
}
96+
8497
bool MfxXmlParser::dumpOutputEnabled(const char *name) {
8598

8699
MFX_DEBUG_TRACE_FUNC;
@@ -177,6 +190,25 @@ c2_status_t MfxXmlParser::addDiagnostics(const char **attrs) {
177190
return C2_OK;
178191
}
179192

193+
c2_status_t MfxXmlParser::addLimits(const char **attrs) {
194+
MFX_DEBUG_TRACE_FUNC;
195+
size_t i = 0;
196+
while (attrs[i] != nullptr) {
197+
if (strcmp(attrs[i], "concurrent-instances") == 0) {
198+
if (strcmp(attrs[++i], "max") == 0) {
199+
m_currentCodec->second.concurrentInstance = std::atoi(attrs[++i]);
200+
MFX_DEBUG_TRACE_STREAM("m_currentCodec->second.concurrentInstance = %d", m_currentCodec->second.concurrentInstance);
201+
} else {
202+
MFX_DEBUG_TRACE_MSG("concurrent-instances is null");
203+
return C2_BAD_VALUE;
204+
}
205+
}
206+
i++;
207+
}
208+
209+
return C2_OK;
210+
}
211+
180212
void MfxXmlParser::startElementHandler(const char* name, const char** attrs) {
181213

182214
MFX_DEBUG_TRACE_FUNC;
@@ -233,6 +265,8 @@ void MfxXmlParser::startElementHandler(const char* name, const char** attrs) {
233265
if (strcmp(name, "Diagnostics") == 0) {
234266
m_parsingStatus =
235267
addDiagnostics(attrs);
268+
} else if (strcmp(name, "Limit") == 0) {
269+
addLimits(attrs);
236270
}
237271
break;
238272
}

0 commit comments

Comments
 (0)