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"))) 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; __anon42dd67380102() 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"))) 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"))) 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; __anon42dd67380502() 86 ffrt::submit([thr]() { free(thr); }, {thr}); 87 return ffrt_success; 88 } 89 #ifdef __cplusplus 90 } 91 #endif 92