* Copyright (c) 2023 Huawei Device 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.
*/
#include "multi_thread_container_access.h"
#include <cinttypes>
#include <cstdlib>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <thread>
#include <vector>
using namespace OHOS::HiviewDFX;
static constexpr int MAP_INDEX_LEN = 10;
static constexpr int MAX_LOOP_SIZE = 10000;
static constexpr int THREAD_SIZE = 10;
using TaskFunction = std::function<void(std::shared_ptr<MultiThreadContainerAccess>)>;
namespace {
int MultiThreadAccess(const TaskFunction& manipulate)
{
auto testcase = std::make_shared<OHOS::HiviewDFX::MultiThreadContainerAccess>();
testcase->Print();
std::vector<std::thread> threads;
for (int i = 0; i < THREAD_SIZE; i++) {
std::thread th(
[testcase, manipulate] {
manipulate(testcase);
});
threads.push_back(std::move(th));
}
for (auto& th : threads) {
th.join();
}
return 0;
}
}
int MultiThreadVectorAccess()
{
auto multiThreadVectorAccess = [](std::shared_ptr<MultiThreadContainerAccess> testcase) {
for (int i = 0; i < MAX_LOOP_SIZE; i++) {
testcase->ManipulateVector();
}
testcase->Print();
};
return MultiThreadAccess(multiThreadVectorAccess);
}
int MultiThreadMapAccess()
{
auto multiThreadMapAccess = [](std::shared_ptr<MultiThreadContainerAccess> testcase) {
for (int i = 0; i < MAX_LOOP_SIZE; i++) {
testcase->ManipulateMap();
}
testcase->Print();
};
return MultiThreadAccess(multiThreadMapAccess);
}
int MultiThreadListAccess()
{
auto multiThreadListAccess = [](std::shared_ptr<MultiThreadContainerAccess> testcase) {
for (int i = 0; i < MAX_LOOP_SIZE; i++) {
testcase->ManipulateList();
testcase->Print();
}
};
return MultiThreadAccess(multiThreadListAccess);
}
namespace OHOS {
namespace HiviewDFX {
std::string MultiThreadContainerAccess::GenerateStr()
{
constexpr int dictLen = 26;
constexpr int len = 10;
const char dict[dictLen] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z' };
std::string result = "";
for (int i = 0; i < len; i++) {
result = result + dict[rand() % dictLen];
}
return result;
}
void MultiThreadContainerAccess::ManipulateVector()
{
if ((rand() % MANIPULATION_TYPE) == ADD) {
strVector_.push_back(GenerateStr());
} else if (!strVector_.empty()) {
strVector_.pop_back();
}
}
void MultiThreadContainerAccess::ManipulateMap()
{
if ((rand() % MANIPULATION_TYPE) == ADD) {
strMap_[rand() % MAP_INDEX_LEN] = GenerateStr();
} else {
strMap_.erase(rand() % MAP_INDEX_LEN);
}
}
void MultiThreadContainerAccess::ManipulateList()
{
if ((rand() % MANIPULATION_TYPE) == ADD) {
strList_.push_back(GenerateStr());
} else if (!strList_.empty()) {
strList_.pop_back();
}
}
void MultiThreadContainerAccess::Print() const
{
printf("MultiThreadContainerAccess::Print begin\n");
for (const auto& value : strList_) {
printf("List:%s\n", value.c_str());
}
for (const auto& value : strVector_) {
printf("Vector:%s\n", value.c_str());
}
for (const auto& entry : strMap_) {
printf("Map: key[%d]:value[%s]\n", entry.first, entry.second.c_str());
}
printf("MultiThreadContainerAccess::Print end\n");
}
}
}