libuv-svace-build
160 строк · 4.2 Кб
1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2*
3* Permission is hereby granted, free of charge, to any person obtaining a copy
4* of this software and associated documentation files (the "Software"), to
5* deal in the Software without restriction, including without limitation the
6* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7* sell copies of the Software, and to permit persons to whom the Software is
8* furnished to do so, subject to the following conditions:
9*
10* The above copyright notice and this permission notice shall be included in
11* all copies or substantial portions of the Software.
12*
13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19* IN THE SOFTWARE.
20*/
21
22#include "uv.h"23#include "task.h"24
25#include <string.h>26#include <errno.h>27
28typedef struct {29uv_barrier_t barrier;30unsigned delay;31unsigned niter;32unsigned main_barrier_wait_rval;33unsigned worker_barrier_wait_rval;34} worker_config;35
36
37static void worker(void* arg) {38worker_config* c = arg;39unsigned i;40
41if (c->delay)42uv_sleep(c->delay);43
44for (i = 0; i < c->niter; i++)45c->worker_barrier_wait_rval += uv_barrier_wait(&c->barrier);46}
47
48
49TEST_IMPL(barrier_1) {50uv_thread_t thread;51worker_config wc;52
53memset(&wc, 0, sizeof(wc));54wc.niter = 1;55
56ASSERT_OK(uv_barrier_init(&wc.barrier, 2));57ASSERT_OK(uv_thread_create(&thread, worker, &wc));58
59uv_sleep(100);60wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier);61
62ASSERT_OK(uv_thread_join(&thread));63uv_barrier_destroy(&wc.barrier);64
65ASSERT_EQ(1, (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval));66
67return 0;68}
69
70
71TEST_IMPL(barrier_2) {72uv_thread_t thread;73worker_config wc;74
75memset(&wc, 0, sizeof(wc));76wc.delay = 100;77wc.niter = 1;78
79ASSERT_OK(uv_barrier_init(&wc.barrier, 2));80ASSERT_OK(uv_thread_create(&thread, worker, &wc));81
82wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier);83
84ASSERT_OK(uv_thread_join(&thread));85uv_barrier_destroy(&wc.barrier);86
87ASSERT_EQ(1, (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval));88
89return 0;90}
91
92
93TEST_IMPL(barrier_3) {94uv_thread_t thread;95worker_config wc;96unsigned i;97
98memset(&wc, 0, sizeof(wc));99wc.niter = 5;100
101ASSERT_OK(uv_barrier_init(&wc.barrier, 2));102ASSERT_OK(uv_thread_create(&thread, worker, &wc));103
104for (i = 0; i < wc.niter; i++)105wc.main_barrier_wait_rval += uv_barrier_wait(&wc.barrier);106
107ASSERT_OK(uv_thread_join(&thread));108uv_barrier_destroy(&wc.barrier);109
110ASSERT_EQ(wc.niter, wc.main_barrier_wait_rval + wc.worker_barrier_wait_rval);111
112return 0;113}
114
115static void serial_worker(void* data) {116uv_barrier_t* barrier;117unsigned i;118
119barrier = data;120for (i = 0; i < 5; i++)121uv_barrier_wait(barrier);122if (uv_barrier_wait(barrier) > 0)123uv_barrier_destroy(barrier);124
125uv_sleep(100); /* Wait a bit before terminating. */126}
127
128/* Ensure that uv_barrier_wait returns positive only after all threads have
129* exited the barrier. If this value is returned too early and the barrier is
130* destroyed prematurely, then this test may see a crash. */
131TEST_IMPL(barrier_serial_thread) {132uv_thread_t threads[4];133uv_barrier_t barrier;134unsigned i;135
136ASSERT_OK(uv_barrier_init(&barrier, ARRAY_SIZE(threads) + 1));137
138for (i = 0; i < ARRAY_SIZE(threads); ++i)139ASSERT_OK(uv_thread_create(&threads[i], serial_worker, &barrier));140
141for (i = 0; i < 5; i++)142uv_barrier_wait(&barrier);143if (uv_barrier_wait(&barrier) > 0)144uv_barrier_destroy(&barrier);145
146for (i = 0; i < ARRAY_SIZE(threads); ++i)147ASSERT_OK(uv_thread_join(&threads[i]));148
149return 0;150}
151
152/* Single thread uv_barrier_wait should return correct return value. */
153TEST_IMPL(barrier_serial_thread_single) {154uv_barrier_t barrier;155
156ASSERT_OK(uv_barrier_init(&barrier, 1));157ASSERT_LT(0, uv_barrier_wait(&barrier));158uv_barrier_destroy(&barrier);159return 0;160}
161