libuv-svace-build

Форк
0
/
test-barrier.c 
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

28
typedef struct {
29
  uv_barrier_t barrier;
30
  unsigned delay;
31
  unsigned niter;
32
  unsigned main_barrier_wait_rval;
33
  unsigned worker_barrier_wait_rval;
34
} worker_config;
35

36

37
static void worker(void* arg) {
38
  worker_config* c = arg;
39
  unsigned i;
40

41
  if (c->delay)
42
    uv_sleep(c->delay);
43

44
  for (i = 0; i < c->niter; i++)
45
    c->worker_barrier_wait_rval += uv_barrier_wait(&c->barrier);
46
}
47

48

49
TEST_IMPL(barrier_1) {
50
  uv_thread_t thread;
51
  worker_config wc;
52

53
  memset(&wc, 0, sizeof(wc));
54
  wc.niter = 1;
55

56
  ASSERT_OK(uv_barrier_init(&wc.barrier, 2));
57
  ASSERT_OK(uv_thread_create(&thread, worker, &wc));
58

59
  uv_sleep(100);
60
  wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier);
61

62
  ASSERT_OK(uv_thread_join(&thread));
63
  uv_barrier_destroy(&wc.barrier);
64

65
  ASSERT_EQ(1, (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval));
66

67
  return 0;
68
}
69

70

71
TEST_IMPL(barrier_2) {
72
  uv_thread_t thread;
73
  worker_config wc;
74

75
  memset(&wc, 0, sizeof(wc));
76
  wc.delay = 100;
77
  wc.niter = 1;
78

79
  ASSERT_OK(uv_barrier_init(&wc.barrier, 2));
80
  ASSERT_OK(uv_thread_create(&thread, worker, &wc));
81

82
  wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier);
83

84
  ASSERT_OK(uv_thread_join(&thread));
85
  uv_barrier_destroy(&wc.barrier);
86

87
  ASSERT_EQ(1, (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval));
88

89
  return 0;
90
}
91

92

93
TEST_IMPL(barrier_3) {
94
  uv_thread_t thread;
95
  worker_config wc;
96
  unsigned i;
97

98
  memset(&wc, 0, sizeof(wc));
99
  wc.niter = 5;
100

101
  ASSERT_OK(uv_barrier_init(&wc.barrier, 2));
102
  ASSERT_OK(uv_thread_create(&thread, worker, &wc));
103

104
  for (i = 0; i < wc.niter; i++)
105
    wc.main_barrier_wait_rval += uv_barrier_wait(&wc.barrier);
106

107
  ASSERT_OK(uv_thread_join(&thread));
108
  uv_barrier_destroy(&wc.barrier);
109

110
  ASSERT_EQ(wc.niter, wc.main_barrier_wait_rval + wc.worker_barrier_wait_rval);
111

112
  return 0;
113
}
114

115
static void serial_worker(void* data) {
116
  uv_barrier_t* barrier;
117
  unsigned i;
118

119
  barrier = data;
120
  for (i = 0; i < 5; i++)
121
    uv_barrier_wait(barrier);
122
  if (uv_barrier_wait(barrier) > 0)
123
    uv_barrier_destroy(barrier);
124

125
  uv_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. */
131
TEST_IMPL(barrier_serial_thread) {
132
  uv_thread_t threads[4];
133
  uv_barrier_t barrier;
134
  unsigned i;
135

136
  ASSERT_OK(uv_barrier_init(&barrier, ARRAY_SIZE(threads) + 1));
137

138
  for (i = 0; i < ARRAY_SIZE(threads); ++i)
139
    ASSERT_OK(uv_thread_create(&threads[i], serial_worker, &barrier));
140

141
  for (i = 0; i < 5; i++)
142
    uv_barrier_wait(&barrier);
143
  if (uv_barrier_wait(&barrier) > 0)
144
    uv_barrier_destroy(&barrier);
145

146
  for (i = 0; i < ARRAY_SIZE(threads); ++i)
147
    ASSERT_OK(uv_thread_join(&threads[i]));
148

149
  return 0;
150
}
151

152
/* Single thread uv_barrier_wait should return correct return value. */
153
TEST_IMPL(barrier_serial_thread_single) {
154
  uv_barrier_t barrier;
155

156
  ASSERT_OK(uv_barrier_init(&barrier, 1));
157
  ASSERT_LT(0, uv_barrier_wait(&barrier));
158
  uv_barrier_destroy(&barrier);
159
  return 0;
160
}
161

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.