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 <cerrno>
17 #include <cstring>
18 #include <fcntl.h>
19 #include <js_native_api.h>
20 #include <node_api.h>
21 #include <sched.h>
22 #include <unistd.h>
23
24 #define NO_ERR 0
25 #define TWENTYTHREE 23
26 #define DEFAULTVALUE (-100)
27 #define SYS_pidfd_open 4
28 #define ONEVAL 1
29 #define MINUSONE (-1)
30 #define MINUSTEN (-10)
31 #define TWOTHREE 23
32 #define FAIL (-1)
33 #define NO_ERR 0
34 #define PARAM_0 0
35 #define PARAM_1 1
36 #define PARAM_2 2
37 #define PARAM_UNNORMAL (-1)
38 #define ERRON_0 0
39 #define TWENTYTHREE 23
40 #define DEFAULTVALUE (-100)
41
SchedGetPriorityMax(napi_env env, napi_callback_info info)42 static napi_value SchedGetPriorityMax(napi_env env, napi_callback_info info)
43 {
44 size_t argc = PARAM_1;
45 napi_value args[1] = {nullptr};
46 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
47 int first = PARAM_0;
48 napi_get_value_int32(env, args[0], &first);
49 int maxvalue = sched_get_priority_max(first);
50 napi_value result = nullptr;
51 napi_create_int32(env, maxvalue, &result);
52 return result;
53 }
54
SchedGetPriorityMin(napi_env env, napi_callback_info info)55 static napi_value SchedGetPriorityMin(napi_env env, napi_callback_info info)
56 {
57 size_t argc = PARAM_1;
58 napi_value args[1] = {nullptr};
59 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
60 int first = PARAM_0;
61 napi_get_value_int32(env, args[0], &first);
62 int minvalue = sched_get_priority_min(first);
63 napi_value result = nullptr;
64 napi_create_int32(env, minvalue, &result);
65 return result;
66 }
SchedCpualloc(napi_env env, napi_callback_info info)67 static napi_value SchedCpualloc(napi_env env, napi_callback_info info)
68 {
69 size_t count = PARAM_0;
70 cpu_set_t *ret = __sched_cpualloc(count);
71 napi_value result = nullptr;
72 if (ret == nullptr) {
73 napi_create_int32(env, PARAM_UNNORMAL, &result);
74 } else {
75 napi_create_int32(env, PARAM_0, &result);
76 }
77 return result;
78 }
SchedYield(napi_env env, napi_callback_info info)79 static napi_value SchedYield(napi_env env, napi_callback_info info)
80 {
81 int schValue = sched_yield();
82 napi_value result = nullptr;
83 napi_create_int32(env, schValue, &result);
84 return result;
85 }
86
SchedGetscheduler(napi_env env, napi_callback_info info)87 static napi_value SchedGetscheduler(napi_env env, napi_callback_info info)
88 {
89 size_t argc = PARAM_1;
90 napi_value args[1] = {nullptr};
91 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
92 int first = PARAM_0;
93 napi_get_value_int32(env, args[0], &first);
94 napi_value result = nullptr;
95
96 if (first == PARAM_0) {
97 int schval = sched_getscheduler(getpid());
98 napi_create_int32(env, schval, &result);
99 }
100 if (first == MINUSONE) {
101 int schval = sched_getscheduler(MINUSTEN);
102 napi_create_int32(env, schval, &result);
103 }
104 return result;
105 }
106
SchedSetparam(napi_env env, napi_callback_info info)107 static napi_value SchedSetparam(napi_env env, napi_callback_info info)
108 {
109 napi_value result = nullptr;
110 size_t argc = PARAM_1;
111 napi_value args[1] = {nullptr};
112 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
113 struct sched_param param = {PARAM_0};
114 pid_t pid = getpid();
115 int first = PARAM_0;
116 napi_get_value_int32(env, args[0], &first);
117 int maxpri = sched_get_priority_max(SCHED_RR);
118 int minpri = sched_get_priority_min(SCHED_RR);
119 if (maxpri == FAIL || minpri == FAIL) {
120 napi_create_int32(env, FAIL, &result);
121 }
122 errno = 0;
123 if (first == PARAM_0) {
124 int ret = sched_getparam(pid, ¶m);
125 if (ret == NO_ERR) {
126 ret = sched_setparam(pid, ¶m);
127 }
128 napi_create_int32(env, ret, &result);
129 } else if (first == FAIL) {
130 int schval = sched_setparam(pid, nullptr);
131 napi_create_int32(env, schval, &result);
132 } else {
133 napi_create_int32(env, DEFAULTVALUE, &result);
134 }
135 return result;
136 }
137
SchedSetscheduler(napi_env env, napi_callback_info info)138 static napi_value SchedSetscheduler(napi_env env, napi_callback_info info)
139 {
140 napi_value result = nullptr;
141 size_t argc = PARAM_1;
142 napi_value args[1] = {nullptr};
143 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
144 int first = PARAM_0;
145 napi_get_value_int32(env, args[0], &first);
146 int sched = PARAM_0;
147 pid_t pid = getpid();
148 sched = SCHED_FIFO;
149 struct sched_param param = {PARAM_0};
150 if (first == NO_ERR) {
151 param.sched_priority = TWENTYTHREE;
152 int schval = sched_setscheduler(pid, sched, ¶m);
153 napi_create_int32(env, schval, &result);
154 } else if (first == FAIL) {
155 int schval = sched_setscheduler(pid, sched, nullptr);
156 napi_create_int32(env, schval, &result);
157 } else {
158 napi_create_int32(env, DEFAULTVALUE, &result);
159 }
160 return result;
161 }
162
SchedGetaffinity(napi_env env, napi_callback_info info)163 static napi_value SchedGetaffinity(napi_env env, napi_callback_info info)
164 {
165 cpu_set_t mask;
166 cpu_set_t get;
167 CPU_ZERO(&mask);
168 CPU_SET(PARAM_0, &mask);
169 int schval = sched_setaffinity(PARAM_0, sizeof(mask), &mask);
170 CPU_ZERO(&get);
171 schval = sched_getaffinity(PARAM_0, sizeof(get), &get);
172 napi_value result;
173 napi_create_int32(env, schval, &result);
174 return result;
175 }
176
SchedGetcpu(napi_env env, napi_callback_info info)177 static napi_value SchedGetcpu(napi_env env, napi_callback_info info)
178 {
179 errno = ERRON_0;
180 int schval = sched_getcpu();
181 napi_value result = nullptr;
182 if (errno != PARAM_0) {
183 napi_create_int32(env, MINUSONE, &result);
184 } else if (schval >= PARAM_0) {
185 napi_create_int32(env, PARAM_0, &result);
186 }
187 return result;
188 }
189
SchedSetaffinity(napi_env env, napi_callback_info info)190 static napi_value SchedSetaffinity(napi_env env, napi_callback_info info)
191 {
192 cpu_set_t mask;
193 CPU_ZERO(&mask);
194 CPU_SET(PARAM_0, &mask);
195 int schval = sched_setaffinity(PARAM_0, sizeof(mask), &mask);
196 napi_value result;
197 napi_create_int32(env, schval, &result);
198 return result;
199 }
200
SchedRrGetInterval(napi_env env, napi_callback_info info)201 static napi_value SchedRrGetInterval(napi_env env, napi_callback_info info)
202 {
203 size_t argc = PARAM_1;
204 napi_value args[1] = {nullptr};
205 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
206 int first = PARAM_0;
207 napi_value result;
208 napi_get_value_int32(env, args[0], &first);
209 if (first == PARAM_0) {
210 pid_t pid = getpid();
211 struct timespec ts = {PARAM_0};
212 int schedvalue = sched_rr_get_interval(pid, &ts);
213 napi_create_int32(env, schedvalue, &result);
214 } else {
215 pid_t pid = MINUSONE;
216 struct timespec ts = {PARAM_0};
217 int schedvalue = sched_rr_get_interval(pid, &ts);
218 napi_create_int32(env, schedvalue, &result);
219 }
220 return result;
221 }
Setns(napi_env env, napi_callback_info info)222 static napi_value Setns(napi_env env, napi_callback_info info)
223 {
224 errno = ERRON_0;
225 pid_t pid = getpid();
226 int fd = syscall(SYS_pidfd_open, pid, PARAM_0);
227 int setval = PARAM_1;
228 if (fd >= PARAM_0) {
229 setval = setns(fd, PARAM_0);
230 }
231 napi_value result;
232 napi_create_int32(env, setval, &result);
233 return result;
234 }
Schedcpucount(napi_env env, napi_callback_info info)235 static napi_value Schedcpucount(napi_env env, napi_callback_info info)
236 {
237 napi_value result = nullptr;
238 int num_cpus = PARAM_0;
239 num_cpus = sysconf(_SC_NPROCESSORS_CONF);
240 size_t size;
241 size = CPU_ALLOC_SIZE(num_cpus);
242 cpu_set_t *cpu;
243 cpu = CPU_ALLOC(num_cpus);
244 int returnValue = __sched_cpucount(size, cpu);
245 napi_create_int32(env, returnValue, &result);
246 return result;
247 }
248
Unshare(napi_env env, napi_callback_info info)249 static napi_value Unshare(napi_env env, napi_callback_info info)
250 {
251 size_t argc = PARAM_1;
252 napi_value args[1] = {nullptr};
253 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
254 int isOpenFile = PARAM_0, toJsResult = FAIL;
255 napi_get_value_int32(env, args[0], &isOpenFile);
256 if (isOpenFile == PARAM_1) {
257 int unshareResult = unshare(CLONE_FILES);
258 if (unshareResult == PARAM_0) {
259 toJsResult = PARAM_1;
260 }
261 }
262 napi_value result = nullptr;
263 napi_create_int32(env, toJsResult, &result);
264 return result;
265 }
266
SchedGetparam(napi_env env, napi_callback_info info)267 static napi_value SchedGetparam(napi_env env, napi_callback_info info)
268 {
269 struct sched_param param1;
270 int ret = sched_getparam(PARAM_0, ¶m1);
271 napi_value result = nullptr;
272 napi_create_int32(env, ret, &result);
273 return result;
274 }
275
276 EXTERN_C_START
Init(napi_env env, napi_value exports)277 static napi_value Init(napi_env env, napi_value exports)
278 {
279 napi_property_descriptor desc[] = {
280 {"schedGetPriorityMax", nullptr, SchedGetPriorityMax, nullptr, nullptr, nullptr, napi_default, nullptr},
281 {"schedGetPriorityMin", nullptr, SchedGetPriorityMin, nullptr, nullptr, nullptr, napi_default, nullptr},
282 {"sched_yield", nullptr, SchedYield, nullptr, nullptr, nullptr, napi_default, nullptr},
283 {"sched_getscheduler", nullptr, SchedGetscheduler, nullptr, nullptr, nullptr, napi_default, nullptr},
284 {"sched_setparam", nullptr, SchedSetparam, nullptr, nullptr, nullptr, napi_default, nullptr},
285 {"sched_setscheduler", nullptr, SchedSetscheduler, nullptr, nullptr, nullptr, napi_default, nullptr},
286 {"sched_getaffinity", nullptr, SchedGetaffinity, nullptr, nullptr, nullptr, napi_default, nullptr},
287 {"sched_getcpu", nullptr, SchedGetcpu, nullptr, nullptr, nullptr, napi_default, nullptr},
288 {"sched_setaffinity", nullptr, SchedSetaffinity, nullptr, nullptr, nullptr, napi_default, nullptr},
289 {"sched_rr_get_interval", nullptr, SchedRrGetInterval, nullptr, nullptr, nullptr, napi_default, nullptr},
290 {"setns", nullptr, Setns, nullptr, nullptr, nullptr, napi_default, nullptr},
291 {"schedCpuCount", nullptr, Schedcpucount, nullptr, nullptr, nullptr, napi_default, nullptr},
292 {"schedCpualloc", nullptr, SchedCpualloc, nullptr, nullptr, nullptr, napi_default, nullptr},
293 {"unshare", nullptr, Unshare, nullptr, nullptr, nullptr, napi_default, nullptr},
294 {"schedGetparam", nullptr, SchedGetparam, nullptr, nullptr, nullptr, napi_default, nullptr},
295 };
296 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
297 return exports;
298 }
299 EXTERN_C_END
300
301 static napi_module demoModule = {
302 .nm_version = 1,
303 .nm_flags = 0,
304 .nm_filename = nullptr,
305 .nm_register_func = Init,
306 .nm_modname = "sched",
307 .nm_priv = ((void *)0),
308 .reserved = {0},
309 };
310
RegisterModule(void)311 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }