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 "c/thread.h"
17 #include "cpp/thread.h"
18 #include "internal_inc/osal.h"
19 #include "dfx/log/ffrt_log_api.h"
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 struct ThreadRes {
25 bool is_joinable;
26 void* result;
27 };
28 API_ATTRIBUTE((visibility("default")))
ffrt_thread_create(ffrt_thread_t * thr,const ffrt_thread_attr_t * attr,void * (* func)(void *),void * arg)29 int ffrt_thread_create(ffrt_thread_t* thr, const ffrt_thread_attr_t* attr, void* (*func)(void*), void* arg)
30 {
31 if (!thr || !func) {
32 FFRT_LOGE("thr and func should not be empty");
33 return ffrt_error_inval;
34 }
35 if (attr) {
36 FFRT_LOGE("attr should be empty");
37 return ffrt_error;
38 }
39
40 auto p = reinterpret_cast<ThreadRes*>(malloc(sizeof(ThreadRes)));
41 if (p == nullptr) {
42 FFRT_LOGE("p is empty");
43 return ffrt_error_nomem;
44 }
45 p->is_joinable = true;
46 p->result = nullptr;
47 ffrt::submit([p, func, arg]() {
48 p->result = func(arg);
49 }, {}, {p});
50
51 *thr = p;
52 return ffrt_success;
53 }
54
55 API_ATTRIBUTE((visibility("default")))
ffrt_thread_join(ffrt_thread_t thr,void ** res)56 int ffrt_thread_join(ffrt_thread_t thr, void** res)
57 {
58 if (!thr || !res) {
59 FFRT_LOGE("thr or res should not be empty");
60 return ffrt_error_inval;
61 }
62
63 auto p = reinterpret_cast<ThreadRes*>(thr);
64 if (p == nullptr || !p->is_joinable) {
65 return ffrt_error_inval;
66 }
67 ffrt::wait({p});
68 *res = p->result;
69 p->is_joinable = false;
70 free(p);
71 return ffrt_success;
72 }
73
74 API_ATTRIBUTE((visibility("default")))
ffrt_thread_detach(ffrt_thread_t thr)75 int ffrt_thread_detach(ffrt_thread_t thr)
76 {
77 if (!thr) {
78 FFRT_LOGE("thr should not be empty");
79 return ffrt_error_inval;
80 }
81 auto p = reinterpret_cast<ThreadRes*>(thr);
82 if (p == nullptr || !p->is_joinable) {
83 return ffrt_error_inval;
84 }
85 p->is_joinable = false;
86 ffrt::submit([thr]() { free(thr); }, {thr});
87 return ffrt_success;
88 }
89 #ifdef __cplusplus
90 }
91 #endif
92