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
MultiThreadVectorAccess()33 int MultiThreadVectorAccess()
34 {
35 auto testcase = std::make_shared<MultiThreadContainerAccess>();
36 testcase->Print();
37 std::vector<std::thread> threads;
38 for (int i = 0; i < THREAD_SIZE; i++) {
39 std::thread th(
40 [testcase] {
41 for (int i = 0; i < MAX_LOOP_SIZE; i++) {
42 testcase->ManipulateVector();
43 }
44 testcase->Print();
45 });
46 threads.push_back(std::move(th));
47 }
48
49 for (auto& th : threads) {
50 th.join();
51 }
52 return 0;
53 }
54
MultiThreadMapAccess()55 int MultiThreadMapAccess()
56 {
57 auto testcase = std::make_shared<MultiThreadContainerAccess>();
58 testcase->Print();
59 std::vector<std::thread> threads;
60 for (int i = 0; i < THREAD_SIZE; i++) {
61 std::thread th(
62 [testcase] {
63 for (int i = 0; i < MAX_LOOP_SIZE; i++) {
64 testcase->ManipulateMap();
65 }
66 testcase->Print();
67 });
68 threads.push_back(std::move(th));
69 }
70
71 for (auto& th : threads) {
72 th.join();
73 }
74 return 0;
75 }
76
MultiThreadListAccess()77 int MultiThreadListAccess()
78 {
79 auto testcase = std::make_shared<MultiThreadContainerAccess>();
80 testcase->Print();
81 std::vector<std::thread> threads;
82 for (int i = 0; i < THREAD_SIZE; i++) {
83 std::thread th(
84 [testcase] {
85 for (int i = 0; i < MAX_LOOP_SIZE; i++) {
86 // may crash inside loop
87 testcase->ManipulateList();
88 testcase->Print();
89 }
90 });
91 threads.push_back(std::move(th));
92 }
93
94 for (auto& th : threads) {
95 th.join();
96 }
97 return 0;
98 }
99 namespace OHOS {
100 namespace HiviewDFX {
GenerateStr()101 std::string MultiThreadContainerAccess::GenerateStr()
102 {
103 constexpr int dictLen = 26;
104 constexpr int len = 10;
105 const char dict[dictLen] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
106 'h', 'i', 'j', 'k', 'l', 'm', 'n',
107 'o', 'p', 'q', 'r', 's', 't', 'u',
108 'v', 'w', 'x', 'y', 'z' };
109 std::string result = "";
110 for (int i = 0; i < len; i++) {
111 result = result + dict[rand() % dictLen];
112 }
113 return result;
114 }
115
ManipulateVector()116 void MultiThreadContainerAccess::ManipulateVector()
117 {
118 if ((rand() % MANIPULATION_TYPE) == ADD) {
119 strVector_.push_back(GenerateStr());
120 } else if (!strVector_.empty()) {
121 strVector_.pop_back();
122 }
123 }
124
ManipulateMap()125 void MultiThreadContainerAccess::ManipulateMap()
126 {
127 if ((rand() % MANIPULATION_TYPE) == ADD) {
128 strMap_[rand() % MAP_INDEX_LEN] = GenerateStr();
129 } else {
130 strMap_.erase(rand() % MAP_INDEX_LEN);
131 }
132 }
133
ManipulateList()134 void MultiThreadContainerAccess::ManipulateList()
135 {
136 if ((rand() % MANIPULATION_TYPE) == ADD) {
137 strList_.push_back(GenerateStr());
138 } else if (!strList_.empty()) {
139 strList_.pop_back();
140 }
141 }
142
Print() const143 void MultiThreadContainerAccess::Print() const
144 {
145 printf("MultiThreadContainerAccess::Print begin\n");
146 for (const auto& value : strList_) {
147 printf("List:%s\n", value.c_str());
148 }
149
150 for (const auto& value : strVector_) {
151 printf("Vector:%s\n", value.c_str());
152 }
153
154 for (const auto& entry : strMap_) {
155 printf("Map: key[%d]:value[%s]\n", entry.first, entry.second.c_str());
156 }
157 printf("MultiThreadContainerAccess::Print end\n");
158 }
159 } // namespace HiviewDFX
160 } // namespace OHOS
161