1/*
2 * Copyright (c) 2022 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 <stdbool.h>
17#include <threads.h>
18#include "test.h"
19
20static cnd_t cond;
21static mtx_t mutex;
22static unsigned int waiting_threads;
23
24#define N 3
25
26static int child_wait(void *data)
27{
28    mtx_lock(&mutex);
29    ++waiting_threads;
30    cnd_wait(&cond, &mutex);
31    mtx_unlock(&mutex);
32
33    thrd_exit(thrd_success);
34}
35
36/**
37 * @tc.name      : cnd_broadcast_0100
38 * @tc.desc      :
39 * @tc.level     : Level 0
40 */
41void cnd_broadcast_0100(void)
42{
43    thrd_t ids[N];
44    unsigned char i;
45
46    if (cnd_init(&cond) != thrd_success) {
47        t_error("%s cnd_init failed\n", __func__);
48    }
49
50    if (mtx_init(&mutex, mtx_plain) != thrd_success) {
51        t_error("%s mtx_init failed\n", __func__);
52    }
53
54    for (i = 0; i < N; ++i) {
55        if (thrd_create(&ids[i], child_wait, NULL) != thrd_success) {
56            t_error("%s thrd_create failed\n", __func__);
57        }
58    }
59
60    while (true) {
61        mtx_lock(&mutex);
62        if (waiting_threads > N) {
63            t_error("%s ", __func__);
64        }
65        bool done_waiting = waiting_threads == N;
66        mtx_unlock(&mutex);
67        if (done_waiting) {
68            break;
69        }
70        thrd_sleep(&((struct timespec){.tv_nsec = 100 * 1000 * 1000}), NULL);
71    }
72
73    mtx_lock(&mutex);
74    if (cnd_broadcast(&cond) != thrd_success) {
75        t_error("%s cnd_broadcast failed\n", __func__);
76    }
77    mtx_unlock(&mutex);
78
79    for (i = 0; i < N; ++i) {
80        if (thrd_join(ids[i], NULL) != thrd_success) {
81            t_error("%s thrd_join failed\n", __func__);
82        }
83    }
84
85    mtx_destroy(&mutex);
86    cnd_destroy(&cond);
87}
88
89int main(int argc, char *argv[])
90{
91    cnd_broadcast_0100();
92    return t_status;
93}