ffrtndk.cpp 9.5 KB
Newer Older
W
wangyulie 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
W
wangyulie 已提交
15 16
#include "napi/native_api.h"
#include "hilog/log.h"
W
wangyulie 已提交
17 18 19 20 21 22
#include "c/task.h"
#include "c/type_def.h"
#include "c/condition_variable.h"
#include "c/mutex.h"
#include "c/queue.h"
#include "c/sleep.h"
W
wangyulie 已提交
23 24 25
#include <string>
#include <unistd.h>

W
wangyulie 已提交
26
void my_print(void* arg)
W
wangyulie 已提交
27
{
W
wangyulie 已提交
28
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "%{public}s", "hello ffrt\n");
W
wangyulie 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
}

void OnePlusForTest(void* arg)
{
    *(int*) arg += 1;
}

void MulipleForTest(void* arg)
{
    *(int*) arg *= 10;
}

void SubForTest(void* arg)
{
    *(int*) arg -= 1;
}

typedef struct {
    ffrt_function_header_t header;
    ffrt_function_t func;
    ffrt_function_t after_func;
    void* arg;
W
wangyulie 已提交
51
} c_function;
W
wangyulie 已提交
52 53 54 55 56

typedef struct {
    ffrt_cond_t* cond;
    int* a;
    ffrt_mutex_t* lock_;
W
wangyulie 已提交
57
} tuple;
W
wangyulie 已提交
58

W
wangyulie 已提交
59
void func1(void* arg)
W
wangyulie 已提交
60
{
W
wangyulie 已提交
61
    tuple* t = (tuple*)arg;
W
wangyulie 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    int ret = ffrt_mutex_lock(t->lock_);
    if (ret != ffrt_success) {
        printf("error\n");
    }
    while (*t->a != 1) {
        ret = ffrt_cond_wait(t->cond, t->lock_);
        if (ret != ffrt_success) {
            printf("error\n");
        }
    }
    *(t->a) = 3;
    ret = ffrt_cond_signal(t->cond);
    if (ret != ffrt_success) {
        printf("error\n");
    }
    ret = ffrt_mutex_unlock(t->lock_);
    if (ret != ffrt_success) {
        printf("error\n");
    }
    printf("a = %d", *(t->a));
}

W
wangyulie 已提交
84
void func2(void* arg)
W
wangyulie 已提交
85
{
W
wangyulie 已提交
86
    tuple* t = (tuple*)arg;
W
wangyulie 已提交
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    int ret = ffrt_mutex_lock(t->lock_);
    if (ret != ffrt_success) {
        printf("error\n");
    }
    *(t->a) = 1;
    ret = ffrt_cond_broadcast(t->cond);
    if (ret != ffrt_success) {
        printf("error\n");
    }
    ret = ffrt_mutex_unlock(t->lock_);
    if (ret != ffrt_success) {
        printf("error\n");
    }
}

W
wangyulie 已提交
102
void func3(void* arg)
W
wangyulie 已提交
103
{
W
wangyulie 已提交
104
    tuple* t = (tuple*)arg;
W
wangyulie 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
    int ret = ffrt_mutex_trylock(t->lock_);
    if (ret != ffrt_success) {
        printf("error\n");
        ret = ffrt_mutex_lock(t->lock_);
        if (ret != ffrt_success) {
            printf("error\n");
        }
    }
    while (*t->a != 3) {
        ret = ffrt_cond_timedwait(t->cond, t->lock_, nullptr);
        if (ret != ffrt_success) {
            printf("error\n");
            ret = ffrt_cond_wait(t->cond, t->lock_);
            if (ret != ffrt_success) {
                printf("error\n");
            }
        }
    }
    ret = ffrt_mutex_unlock(t->lock_);
    if (ret != ffrt_success) {
        printf("error\n");
    }
    printf("a = %d", *(t->a));
}

W
wangyulie 已提交
130
static void ffrt_exec_function_wrapper(void* t)
W
wangyulie 已提交
131
{
W
wangyulie 已提交
132
    c_function* f = (c_function*)t;
W
wangyulie 已提交
133 134 135 136 137
    if (f->func) {
        f->func(f->arg);
    }
}

W
wangyulie 已提交
138
static void ffrt_destroy_function_wrapper(void* t)
W
wangyulie 已提交
139
{
W
wangyulie 已提交
140
    c_function* f = (c_function*)t;
W
wangyulie 已提交
141 142 143 144 145 146 147 148 149
    if (f->after_func) {
        f->after_func(f->arg);
    }
}

#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
    const ffrt_function_t after_func, void* arg, ffrt_function_kind_t kind_t = ffrt_function_kind_general)
{
W
wangyulie 已提交
150
    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
W
wangyulie 已提交
151
        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
W
wangyulie 已提交
152 153 154
    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(kind_t);
    f->header.exec = ffrt_exec_function_wrapper;
    f->header.destroy = ffrt_destroy_function_wrapper;
W
wangyulie 已提交
155 156 157 158 159 160
    f->func = func;
    f->after_func = after_func;
    f->arg = arg;
    return (ffrt_function_header_t*)f;
}

W
wangyulie 已提交
161 162
static inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
W
wangyulie 已提交
163
{
W
wangyulie 已提交
164
    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
W
wangyulie 已提交
165 166
}

W
wangyulie 已提交
167 168
static inline ffrt_task_handle_t ffrt_submit_h_c(ffrt_function_t func, const ffrt_function_t after_func,
    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
W
wangyulie 已提交
169
{
W
wangyulie 已提交
170
    return ffrt_submit_h_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
W
wangyulie 已提交
171 172
}

W
wangyulie 已提交
173
void ffrt_cv_task(void* arg)
W
wangyulie 已提交
174 175 176 177 178 179 180 181
{
    int* a = (int*) arg;
    ffrt_cond_t cond;
    int ret = ffrt_cond_init(&cond, NULL);
    if (ret != ffrt_success) {
        printf("error\n");
    }
    ffrt_mutex_t lock_;
W
wangyulie 已提交
182
    tuple t = {&cond, a, &lock_};
W
wangyulie 已提交
183 184 185 186
    ret = ffrt_mutex_init(&lock_, NULL);
    if (ret != ffrt_success) {
        printf("error\n");
    }
W
wangyulie 已提交
187 188 189
    ffrt_submit_c(func1, NULL, &t, NULL, NULL, NULL);
    ffrt_submit_c(func2, NULL, &t, NULL, NULL, NULL);
    ffrt_submit_c(func3, NULL, &t, NULL, NULL, NULL);
W
wangyulie 已提交
190 191 192 193 194 195 196
    ffrt_wait();
    ffrt_cond_destroy(&cond);
    ffrt_mutex_destroy(&lock_);
}

static napi_value SubmitSimpleFfrtTask(napi_env env, napi_callback_info info)
{
W
wangyulie 已提交
197
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "%{public}s", "ffrt start\n");
W
wangyulie 已提交
198 199 200 201
    ffrt_task_attr_t attr;
    ffrt_task_attr_init(&attr);
    ffrt_task_attr_set_qos(&attr, static_cast<ffrt_qos_t>(ffrt_qos_background));
    ffrt_task_attr_set_name(&attr, "ffrt_testA");
W
wangyulie 已提交
202 203
    ffrt_task_attr_get_delay(&attr);
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "task name is %{public}s", ffrt_task_attr_get_name(&attr));
W
wangyulie 已提交
204
    ffrt_task_attr_set_delay(&attr, 1000);
W
wangyulie 已提交
205 206
    ffrt_task_attr_get_delay(&attr);
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "qos is %{public}d", ffrt_task_attr_get_qos(&attr));
W
wangyulie 已提交
207
    ffrt_task_attr_set_qos(&attr, static_cast<ffrt_qos_t>(ffrt_qos_user_initiated));
W
wangyulie 已提交
208 209
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "qos2 is %{public}d", ffrt_task_attr_get_qos(&attr));
    ffrt_submit_c(my_print, NULL, NULL, NULL, NULL, &attr);
W
wangyulie 已提交
210
    int result = ffrt_this_task_update_qos(static_cast<ffrt_qos_t>(ffrt_qos_default));
W
wangyulie 已提交
211 212 213
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "update_qos result is %{public}d", result);
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "qos3 is %{public}d", ffrt_task_attr_get_qos(&attr));
    ffrt_this_task_get_id();
W
wangyulie 已提交
214 215 216 217 218 219 220 221 222 223 224 225
    ffrt_usleep(10000);
    ffrt_yield();
    ffrt_task_attr_destroy(&attr);
    ffrt_wait();
    napi_value flag = nullptr;
    napi_create_double(env, 1, &flag);
    return flag;
}

static napi_value SubmitCondFfrtTask(napi_env env, napi_callback_info info)
{
    int a = 0;
W
wangyulie 已提交
226 227
    ffrt_submit_c(ffrt_cv_task, NULL, &a, NULL, NULL, NULL);
    ffrt_task_handle_t task1 = ffrt_submit_h_c(my_print, NULL, NULL, NULL, NULL, NULL);
W
wangyulie 已提交
228 229
    ffrt_wait_deps(nullptr);
    ffrt_wait();
W
wangyulie 已提交
230
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "cond task a is %{public}d", a);
W
wangyulie 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243
    napi_value flag = nullptr;
    napi_create_double(env, a, &flag);
    ffrt_task_handle_destroy(task1);
    return flag;
}

static napi_value SubmitQueueFfrtTask(napi_env env, napi_callback_info info)
{
    int a = 0;
    int b = 0;
    ffrt_queue_attr_t queue_attr;
    (void)ffrt_queue_attr_init(&queue_attr);
    ffrt_queue_attr_set_qos(&queue_attr, ffrt_qos_default);
W
wangyulie 已提交
244
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "queue task qos is %{public}d", ffrt_queue_attr_get_qos(&queue_attr));
W
wangyulie 已提交
245
    ffrt_queue_attr_set_timeout(&queue_attr, 10000);
W
wangyulie 已提交
246 247
    ffrt_queue_attr_get_timeout(&queue_attr);
    ffrt_queue_attr_set_callback(&queue_attr, ffrt_create_function_wrapper(OnePlusForTest, NULL, &b, ffrt_function_kind_queue));
W
wangyulie 已提交
248 249
    ffrt_queue_attr_get_callback(&queue_attr);
    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
W
wangyulie 已提交
250
    ffrt_task_handle_t task1 = ffrt_queue_submit_h(queue_handle, ffrt_create_function_wrapper(OnePlusForTest, NULL, &a, ffrt_function_kind_queue), nullptr);
W
wangyulie 已提交
251 252
    ffrt_queue_cancel(task1);
    ffrt_queue_wait(task1);
W
wangyulie 已提交
253 254
    ffrt_queue_submit(queue_handle, ffrt_create_function_wrapper(MulipleForTest, nullptr, &a, ffrt_function_kind_queue), nullptr);
    ffrt_queue_submit(queue_handle, ffrt_create_function_wrapper(SubForTest, nullptr, &a, ffrt_function_kind_queue), nullptr);
W
wangyulie 已提交
255
    sleep(2);
W
wangyulie 已提交
256 257
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "queue task a is %{public}d", a);
    HiLogPrint(LOG_APP, LOG_INFO, 1, "testFFRT", "queue task b is %{public}d", b);
W
wangyulie 已提交
258 259 260 261 262 263 264 265
    napi_value flag = nullptr;
    napi_create_double(env, a, &flag);
    ffrt_task_handle_destroy(task1);
    ffrt_queue_attr_destroy(&queue_attr);
    ffrt_queue_destroy(queue_handle);
    return flag;
}

W
wangyulie 已提交
266 267 268 269 270 271
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "submitSimpleFfrtTask", nullptr, SubmitSimpleFfrtTask, nullptr, nullptr, nullptr, napi_default, nullptr },
        { "submitCondFfrtTask", nullptr, SubmitCondFfrtTask, nullptr, nullptr, nullptr, napi_default, nullptr },
W
wangyulie 已提交
272
        { "submitQueueFfrtTask", nullptr, SubmitQueueFfrtTask, nullptr, nullptr, nullptr, napi_default, nullptr }
W
wangyulie 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version =1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "ffrtndk",
    .nm_priv = ((void*)0),
    .reserved = { 0 },
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{
    napi_module_register(&demoModule);
}