1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "multi_thread_container_access.h"
17
18 #include <cinttypes>
19 #include <cstdlib>
20 #include <list>
21 #include <map>
22 #include <memory>
23 #include <string>
24 #include <thread>
25 #include <vector>
26
27 using namespace OHOS::HiviewDFX;
28
29 static constexpr int MAP_INDEX_LEN = 10;
30 static constexpr int MAX_LOOP_SIZE = 10000;
31 static constexpr int THREAD_SIZE = 10;
32
33 using TaskFunction = std::function<void(std::shared_ptr<MultiThreadContainerAccess>)>;
34
35 namespace {
MultiThreadAccess(const TaskFunction & manipulate)36 int MultiThreadAccess(const TaskFunction& manipulate)
37 {
38 auto testcase = std::make_shared<OHOS::HiviewDFX::MultiThreadContainerAccess>();
39 testcase->Print();
40 std::vector<std::thread> threads;
41 for (int i = 0; i < THREAD_SIZE; i++) {
42 std::thread th(
43 [testcase, manipulate] {
44 manipulate(testcase);
45 });
46 threads.push_back(std::move(th));
47 }
48
49 for (auto& th : threads) {
50 th.join();
51 }
52 return 0;
53 }
54 }
55
MultiThreadVectorAccess()56 int MultiThreadVectorAccess()
57 {
58 auto multiThreadVectorAccess = [](std::shared_ptr<MultiThreadContainerAccess> testcase) {
59 for (int i = 0; i < MAX_LOOP_SIZE; i++) {
60 testcase->ManipulateVector();
61 }
62 testcase->Print();
63 };
64 return MultiThreadAccess(multiThreadVectorAccess);
65 }
66
MultiThreadMapAccess()67 int MultiThreadMapAccess()
68 {
69 auto multiThreadMapAccess = [](std::shared_ptr<MultiThreadContainerAccess> testcase) {
70 for (int i = 0; i < MAX_LOOP_SIZE; i++) {
71 testcase->ManipulateMap();
72 }
73 testcase->Print();
74 };
75 return MultiThreadAccess(multiThreadMapAccess);
76 }
77
MultiThreadListAccess()78 int MultiThreadListAccess()
79 {
80 auto multiThreadListAccess = [](std::shared_ptr<MultiThreadContainerAccess> testcase) {
81 for (int i = 0; i < MAX_LOOP_SIZE; i++) {
82 // may crash inside loop
83 testcase->ManipulateList();
84 testcase->Print();
85 }
86 };
87 return MultiThreadAccess(multiThreadListAccess);
88 }
89
90 namespace OHOS {
91 namespace HiviewDFX {
GenerateStr()92 std::string MultiThreadContainerAccess::GenerateStr()
93 {
94 constexpr int dictLen = 26;
95 constexpr int len = 10;
96 const char dict[dictLen] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
97 'h', 'i', 'j', 'k', 'l', 'm', 'n',
98 'o', 'p', 'q', 'r', 's', 't', 'u',
99 'v', 'w', 'x', 'y', 'z' };
100 std::string result = "";
101 for (int i = 0; i < len; i++) {
102 result = result + dict[rand() % dictLen];
103 }
104 return result;
105 }
106
ManipulateVector()107 void MultiThreadContainerAccess::ManipulateVector()
108 {
109 if ((rand() % MANIPULATION_TYPE) == ADD) {
110 strVector_.push_back(GenerateStr());
111 } else if (!strVector_.empty()) {
112 strVector_.pop_back();
113 }
114 }
115
ManipulateMap()116 void MultiThreadContainerAccess::ManipulateMap()
117 {
118 if ((rand() % MANIPULATION_TYPE) == ADD) {
119 strMap_[rand() % MAP_INDEX_LEN] = GenerateStr();
120 } else {
121 strMap_.erase(rand() % MAP_INDEX_LEN);
122 }
123 }
124
ManipulateList()125 void MultiThreadContainerAccess::ManipulateList()
126 {
127 if ((rand() % MANIPULATION_TYPE) == ADD) {
128 strList_.push_back(GenerateStr());
129 } else if (!strList_.empty()) {
130 strList_.pop_back();
131 }
132 }
133
Print() const134 void MultiThreadContainerAccess::Print() const
135 {
136 printf("MultiThreadContainerAccess::Print begin\n");
137 for (const auto& value : strList_) {
138 printf("List:%s\n", value.c_str());
139 }
140
141 for (const auto& value : strVector_) {
142 printf("Vector:%s\n", value.c_str());
143 }
144
145 for (const auto& entry : strMap_) {
146 printf("Map: key[%d]:value[%s]\n", entry.first, entry.second.c_str());
147 }
148 printf("MultiThreadContainerAccess::Print end\n");
149 }
150 } // namespace HiviewDFX
151 } // namespace OHOS
152