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 <random>
17 #include <csignal>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <unistd.h>
21 #include <cstdint>
22 #include <cstring>
23 #include <cerrno>
24 #include <fcntl.h>
25 #include <cstdbool>
26 #include <sys/ioctl.h>
27 #include <gtest/gtest.h>
28 #include "ffrt_inner.h"
29 #include "dfx/log/ffrt_log_api.h"
30 #include "c/ffrt_flo.h"
31 #include "../common.h"
32
33 using namespace std;
34 using namespace testing;
35 #ifdef HWTEST_TESTING_EXT_ENABLE
36 using namespace testing::ext;
37 #endif
38 using namespace ffrt;
39
40 #define IOCTL_SET_FLO_CONFIG _IOWR('x', 51, struct FloCfg)
41 struct FloCfg {
42 int pid; // process id
43 int id; // code part context id (0-32), shouldn't be duplicate
44 unsigned int size; // this context using how much ddr size set 0x100000(1MB) as default
45 unsigned int port; // 0 as default I/D cache FLO work on the same time
46 unsigned int offset; // how many ahead used by FLO prefecher
47 #ifndef __OHOS__
48 bool ffrt;
49 #endif
50 };
51
InitCfg(int ctxId)52 int InitCfg(int ctxId)
53 {
54 int fd;
55 struct FloCfg data;
56
57 struct FloCfg cfg = {
58 .pid = getpid(),
59 .id = ctxId,
60 .size = 1048576,
61 .port = 0,
62 .offset = 256,
63 #ifndef __OHOS__
64 .ffrt = true,
65 #endif
66 };
67
68 printf("get para: pid-%d id-%d size-0x%x port-%d offset-%d.\n",
69 cfg.pid, cfg.id, cfg.size, cfg.port, cfg.offset);
70
71 fd = open("/dev/hisi_perf_ctrl", O_RDWR);
72 if (fd < 0) {
73 printf("open /dev/hisi_perf_ctrl failed.\n");
74 return -1;
75 }
76
77 if (ioctl(fd, IOCTL_SET_FLO_CONFIG, &cfg) == -1) {
78 printf("Error %d (%s) in IOCTL_SET_FLO_CONFIG\n", errno, strerror(errno));
79 close(fd);
80 return -1;
81 }
82
83 close(fd);
84 printf("flo cfg finished.\n");
85 return 0;
86 }
87
88 class FloTest : public testing::Test {
89 protected:
SetUpTestCase()90 static void SetUpTestCase()
91 {
92 }
93
TearDownTestCase()94 static void TearDownTestCase()
95 {
96 }
97
SetUp()98 virtual void SetUp()
99 {
100 }
101
TearDown()102 virtual void TearDown()
103 {
104 }
105 };
106
HWTEST_F(FloTest, FFRTFloApiSuccess, TestSize.Level1)107 HWTEST_F(FloTest, FFRTFloApiSuccess, TestSize.Level1)
108 {
109 InitCfg(1);
110 ffrt_flo_start(1);
111 ffrt_flo_end(1);
112 }
113
HWTEST_F(FloTest, FFRTFloTaskWithoutYield, TestSize.Level1)114 HWTEST_F(FloTest, FFRTFloTaskWithoutYield, TestSize.Level1)
115 {
116 InitCfg(2);
117 auto handle = ffrt::submit_h([] {
118 ffrt_flo_start(2);
119 ffrt_flo_end(2);
120 }, {}, {});
121 ffrt::wait({handle});
122 }
123
HWTEST_F(FloTest, FFRTFloTaskWithYield, TestSize.Level1)124 HWTEST_F(FloTest, FFRTFloTaskWithYield, TestSize.Level1)
125 {
126 InitCfg(3);
127 auto handle = ffrt::submit_h([] {
128 ffrt_flo_start(3);
129 ffrt::this_task::yield();
130 ffrt_flo_end(3);
131 }, {}, {});
132 ffrt::wait({handle});
133 }