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 "cpp/thread.h"
17 #include "c/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 thread_res {
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<thread_res*>(malloc(sizeof(thread_res)));
41 p->is_joinable = true;
42 p->result = nullptr;
43 ffrt::submit([p, func, arg]() {
44 p->result = func(arg);
45 }, {}, {p});
46
47 *thr = p;
48 return ffrt_success;
49 }
50
51 API_ATTRIBUTE((visibility("default")))
ffrt_thread_join(ffrt_thread_t thr,void ** res)52 int ffrt_thread_join(ffrt_thread_t thr, void** res)
53 {
54 if (!thr) {
55 FFRT_LOGE("thr should not be empty");
56 return ffrt_error_inval;
57 }
58 auto p = reinterpret_cast<thread_res*>(thr);
59 if (p == nullptr || !p->is_joinable) {
60 return ffrt_error_inval;
61 }
62 ffrt::wait({p});
63 *res = p->result;
64 p->is_joinable = false;
65 free(p);
66 return ffrt_success;
67 }
68
69 API_ATTRIBUTE((visibility("default")))
ffrt_thread_detach(ffrt_thread_t thr)70 int ffrt_thread_detach(ffrt_thread_t thr)
71 {
72 if (!thr) {
73 FFRT_LOGE("thr should not be empty");
74 return ffrt_error_inval;
75 }
76 auto p = reinterpret_cast<thread_res*>(thr);
77 if (p == nullptr || !p->is_joinable) {
78 return ffrt_error_inval;
79 }
80 p->is_joinable = false;
81 ffrt::submit([thr]() { free(thr); }, {thr});
82 return ffrt_success;
83 }
84 #ifdef __cplusplus
85 }
86 #endif
87