• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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