Motr  M0
nucleus.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
29 #include "ut/ut.h"
30 
31 #include "lib/misc.h" /* M0_SET0, ARRAY_SIZE */
32 
33 #include "dtm/dtm_internal.h"
34 #include "dtm/nucleus.h"
35 
36 enum {
37  HI_MAX = 32,
38  OP_MAX = 32,
39  UP_MAX = 1024
40 };
41 
42 static struct ctx {
43  struct m0_dtm_nu c_nu;
47  int c_idx;
48 } cc;
49 
50 static void (*c_ready) (struct m0_dtm_op *op);
51 static void (*c_miser) (struct m0_dtm_op *op);
52 static void (*c_late) (struct m0_dtm_op *op);
53 
54 static void ready(struct m0_dtm_op *op)
55 {
56  if (c_ready != NULL)
57  c_ready(op);
58 }
59 
60 static void miser(struct m0_dtm_op *op)
61 {
62  if (c_miser != NULL)
63  c_miser(op);
64 }
65 
66 static void late(struct m0_dtm_op *op)
67 {
68  if (c_late != NULL)
69  c_late(op);
70 }
71 
72 static const struct m0_dtm_op_ops op_ops = {
73  .doo_ready = ready,
74  .doo_late = late,
75  .doo_miser = miser
76 };
77 
78 static void h_release(struct m0_dtm_hi *hi)
79 {
80 }
81 
82 static const struct m0_dtm_hi_ops hi_ops = {
84 };
85 
86 
87 static void nu(void)
88 {
91 }
92 
93 static void hi(void)
94 {
95  struct m0_dtm_hi hi;
96 
98  nu_lock(&cc.c_nu);
100  m0_dtm_hi_fini(&hi);
101  nu_unlock(&cc.c_nu);
103 }
104 
105 static void op(void)
106 {
107  struct m0_dtm_op op;
108 
110  nu_lock(&cc.c_nu);
111  m0_dtm_op_init(&op, &cc.c_nu);
112  m0_dtm_op_fini(&op);
113  nu_unlock(&cc.c_nu);
115 }
116 
117 static void ctx_init(void)
118 {
119  int i;
120 
121  M0_SET0(&cc);
123  nu_lock(&cc.c_nu);
124  for (i = 0; i < ARRAY_SIZE(cc.c_hi); ++i) {
125  m0_dtm_hi_init(&cc.c_hi[i], &cc.c_nu);
126  cc.c_hi[i].hi_ver = 1;
127  cc.c_hi[i].hi_ops = &hi_ops;
129  }
130  for (i = 0; i < ARRAY_SIZE(cc.c_op); ++i) {
131  m0_dtm_op_init(&cc.c_op[i], &cc.c_nu);
132  cc.c_op[i].op_ops = &op_ops;
133  }
134  cc.c_idx = 0;
135 }
136 
137 static void ctx_fini(void)
138 {
139  int i;
140 
141  for (i = 0; i < ARRAY_SIZE(cc.c_op); ++i)
142  m0_dtm_op_fini(&cc.c_op[i]);
143  for (i = 0; i < ARRAY_SIZE(cc.c_hi); ++i)
144  m0_dtm_hi_fini(&cc.c_hi[i]);
145  nu_unlock(&cc.c_nu);
147 }
148 
149 static void ctx_add(int hi, int op, enum m0_dtm_up_rule rule,
150  m0_dtm_ver_t ver, m0_dtm_ver_t orig_ver)
151 {
155 
157  rule, ver, orig_ver);
158  cc.c_idx++;
159 }
160 
161 M0_INTERNAL void up_print(const struct m0_dtm_up *up);
162 M0_INTERNAL void op_print(const struct m0_dtm_op *op);
163 M0_INTERNAL void hi_print(const struct m0_dtm_hi *hi);
164 
165 static void __attribute__((unused)) ctx_print(void)
166 {
167  int i;
168 
169  for (i = 0; i < ARRAY_SIZE(cc.c_hi); ++i)
170  hi_print(&cc.c_hi[i]);
171  for (i = 0; i < ARRAY_SIZE(cc.c_op); ++i)
172  op_print(&cc.c_op[i]);
173 }
174 
175 static void ctx_check(void)
176 {
177  int i;
178 
179  for (i = 0; i < ARRAY_SIZE(cc.c_hi); ++i)
181  for (i = 0; i < ARRAY_SIZE(cc.c_op); ++i)
183  for (i = 0; i < cc.c_idx; ++i)
185 }
186 
187 static void fail(struct m0_dtm_op *op)
188 {
189  M0_UT_ASSERT(1 == 0);
190 }
191 
192 static void ctx_op_add(int i)
193 {
194  c_late = c_miser = fail;
196  c_late = c_miser = NULL;
197 }
198 
199 static void ctx_state(int i, enum m0_dtm_state state)
200 {
201  M0_UT_ASSERT(op_state(&cc.c_op[i], state));
202 }
203 
204 static void up_init(void)
205 {
206  ctx_init();
207  ctx_add(0, 0, M0_DUR_NOT, 0, 0);
208  ctx_fini();
209 }
210 
211 static void op_add(void)
212 {
213  enum {
214  OP_NR = 10,
215  UP_NR = 5
216  };
217 
218  int i;
219  int j;
220 
221  ctx_init();
222  for (i = 0; i < OP_NR; ++i) {
223  ctx_add(0, i, M0_DUR_INC, i + 2, i + 1);
224  for (j = 1; j < UP_NR; ++j)
225  ctx_add(j, i, M0_DUR_INC, 0, 0);
226  }
227  ctx_check();
228  for (i = 0; i < OP_NR; ++i) {
229  ctx_op_add(i);
230  M0_UT_ASSERT(m0_forall(k, OP_NR,
231  op_state(&cc.c_op[k],
232  (k < i ? M0_DOS_INPROGRESS :
233  k == i ? M0_DOS_PREPARE :
234  M0_DOS_LIMBO))));
236  M0_UT_ASSERT(m0_forall(k, OP_NR,
237  op_state(&cc.c_op[k],
238  (k <= i ? M0_DOS_INPROGRESS :
239  M0_DOS_LIMBO))));
240  }
241  for (i = 0; i < OP_NR * UP_NR; ++i)
242  M0_UT_ASSERT(cc.c_up[i].up_ver != 0 &&
243  cc.c_up[i].up_orig_ver != 0);
244  ctx_check();
245  ctx_fini();
246 }
247 
248 static void op_gap(void)
249 {
250  ctx_init();
251  ctx_add(0, 0, M0_DUR_INC, 3, 2);
252  ctx_op_add(0);
254  ctx_add(0, 1, M0_DUR_INC, 2, 1);
255  ctx_op_add(1);
262  ctx_check();
263  ctx_fini();
264 }
265 
266 static bool flag;
267 
268 static void set_flag(struct m0_dtm_op *op)
269 {
270  M0_UT_ASSERT(!flag);
271  flag = true;
272 }
273 
274 static void op_late(void)
275 {
276  ctx_init();
277  ctx_add(0, 0, M0_DUR_SET, 3, 1);
278  ctx_op_add(0);
282  ctx_add(0, 1, M0_DUR_INC, 2, 1);
283  c_late = set_flag;
284  flag = false;
285  m0_dtm_op_close(&cc.c_op[1]);
287  c_late = NULL;
288  ctx_check();
289  ctx_fini();
290 }
291 
292 static void op_miser(void)
293 {
294  ctx_init();
295  ctx_add(0, 0, M0_DUR_SET, 3, 1);
296  ctx_add(1, 0, M0_DUR_SET, 2, 1);
297  ctx_op_add(0);
301 
302  ctx_add(0, 1, M0_DUR_SET, 2, 1);
303  ctx_add(1, 1, M0_DUR_SET, 3, 2);
304  c_miser = set_flag;
305  flag = false;
306  m0_dtm_op_close(&cc.c_op[1]);
308  c_miser = NULL;
309  ctx_check();
310  ctx_fini();
311 }
312 
313 static void op_miser_delayed(void)
314 {
315  ctx_init();
316  ctx_add(0, 0, M0_DUR_INC, 2, 1);
317  ctx_add(1, 0, M0_DUR_INC, 0, 0);
318 
319  ctx_add(0, 1, M0_DUR_INC, 3, 2);
320  ctx_add(1, 1, M0_DUR_INC, 0, 0);
321 
322  ctx_add(0, 2, M0_DUR_INC, 4, 3);
323  ctx_add(1, 2, M0_DUR_INC, 2, 1);
324 
325  ctx_op_add(2);
329  ctx_op_add(0);
333  ctx_op_add(1);
337 
338  c_miser = set_flag;
339  flag = false;
345  c_miser = NULL;
347  ctx_check();
348  ctx_fini();
349 }
350 
351 static void op_done(void)
352 {
353  ctx_init();
354  ctx_add(0, 0, M0_DUR_INC, 2, 1);
355  ctx_add(1, 0, M0_DUR_INC, 0, 0);
356 
357  ctx_add(0, 1, M0_DUR_INC, 3, 2);
358  ctx_add(1, 1, M0_DUR_INC, 0, 0);
359 
360  ctx_op_add(0);
362  ctx_op_add(1);
366 
367  m0_dtm_op_done(&cc.c_op[0]);
368  m0_dtm_op_done(&cc.c_op[1]);
371 
372  ctx_check();
373  ctx_fini();
374 }
375 
377  .ts_name = "dtm-nucleus-ut",
378  .ts_tests = {
379  { "nu", nu },
380  { "hi", hi },
381  { "op", op },
382  { "up", up_init },
383  { "op-add", op_add },
384  { "gap", op_gap },
385  { "late", op_late },
386  { "miser", op_miser },
387  { "miser-delayed", op_miser_delayed },
388  { "done", op_done },
389  { NULL, NULL }
390  }
391 };
392 M0_EXPORTED(dtm_nucleus_ut);
393 
396 /*
397  * Local variables:
398  * c-indentation-style: "K&R"
399  * c-basic-offset: 8
400  * tab-width: 8
401  * fill-column: 80
402  * scroll-step: 1
403  * End:
404  */
405 /*
406  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
407  */
M0_INTERNAL void m0_dtm_op_init(struct m0_dtm_op *op, struct m0_dtm_nu *nu)
Definition: nucleus.c:77
static struct ctx cc
static const struct m0_dtm_hi_ops hi_ops
Definition: nucleus.c:82
struct m0_ut_suite dtm_nucleus_ut
Definition: nucleus.c:376
static void op_done(void)
Definition: nucleus.c:351
static const struct m0_dtm_op_ops op_ops
Definition: nucleus.c:72
m0_dtm_ver_t up_orig_ver
Definition: nucleus.h:97
M0_INTERNAL void m0_dtm_op_done(const struct m0_dtm_op *op)
Definition: nucleus.c:108
m0_dtm_up_rule
Definition: nucleus.h:84
static void h_release(struct m0_dtm_hi *hi)
Definition: nucleus.c:78
#define NULL
Definition: misc.h:38
M0_INTERNAL bool m0_dtm_hi_invariant(const struct m0_dtm_hi *hi)
Definition: nucleus.c:436
static void(* c_miser)(struct m0_dtm_op *op)
Definition: nucleus.c:51
struct m0_dtm_nu c_nu
Definition: nucleus.c:43
uint64_t hi_flags
Definition: nucleus.h:65
static void op(void)
Definition: nucleus.c:105
static void ctx_check(void)
Definition: nucleus.c:175
static void ctx_fini(void)
Definition: nucleus.c:137
M0_INTERNAL bool m0_dtm_up_invariant(const struct m0_dtm_up *up)
Definition: nucleus.c:448
static void(* c_late)(struct m0_dtm_op *op)
Definition: nucleus.c:52
static void fail(struct m0_dtm_op *op)
Definition: nucleus.c:187
static void op_late(void)
Definition: nucleus.c:274
#define M0_SET0(obj)
Definition: misc.h:64
Definition: ut.h:77
static void set_flag(struct m0_dtm_op *op)
Definition: nucleus.c:268
struct m0_dtm_hi c_hi[HI_MAX]
Definition: nucleus.c:44
m0_dtm_ver_t up_ver
Definition: nucleus.h:96
int c_idx
Definition: nucleus.c:47
void(* dho_release)(struct m0_dtm_hi *hi)
Definition: nucleus.h:81
struct m0_dtm_op c_op[OP_MAX]
Definition: nucleus.c:45
op
Definition: libdemo.c:64
static void(* c_ready)(struct m0_dtm_op *op)
Definition: nucleus.c:50
static void ready(struct m0_dtm_op *op)
Definition: nucleus.c:54
static void up_init(void)
Definition: nucleus.c:204
int i
Definition: dir.c:1033
M0_INTERNAL void up_print(const struct m0_dtm_up *up)
Definition: nucleus.c:548
static void op_gap(void)
Definition: nucleus.c:248
M0_INTERNAL void m0_dtm_nu_init(struct m0_dtm_nu *nu)
Definition: nucleus.c:365
const struct m0_dtm_op_ops * op_ops
Definition: nucleus.h:108
uint64_t m0_dtm_ver_t
Definition: nucleus.h:48
M0_INTERNAL void op_print(const struct m0_dtm_op *op)
Definition: nucleus.c:555
static void nu(void)
Definition: nucleus.c:87
M0_INTERNAL bool m0_dtm_op_invariant(const struct m0_dtm_op *op)
Definition: nucleus.c:470
Definition: nucleus.c:39
M0_INTERNAL void m0_dtm_hi_fini(struct m0_dtm_hi *hi)
Definition: nucleus.c:277
static void ctx_state(int i, enum m0_dtm_state state)
Definition: nucleus.c:199
M0_INTERNAL void nu_lock(struct m0_dtm_nu *nu)
Definition: nucleus.c:538
M0_INTERNAL void m0_dtm_op_close(const struct m0_dtm_op *op)
Definition: nucleus.c:84
void(* doo_ready)(struct m0_dtm_op *op)
Definition: nucleus.h:113
static void __attribute__((unused))
Definition: nucleus.c:165
static void miser(struct m0_dtm_op *op)
Definition: nucleus.c:60
M0_INTERNAL void m0_dtm_op_fini(struct m0_dtm_op *op)
Definition: nucleus.c:135
#define m0_forall(var, nr,...)
Definition: misc.h:112
M0_INTERNAL void nu_unlock(struct m0_dtm_nu *nu)
Definition: nucleus.c:543
static void ctx_op_add(int i)
Definition: nucleus.c:192
const char * ts_name
Definition: ut.h:99
m0_dtm_ver_t hi_ver
Definition: nucleus.h:66
static bool flag
Definition: nucleus.c:266
M0_INTERNAL bool op_state(const struct m0_dtm_op *op, enum m0_dtm_state state)
Definition: nucleus.c:511
static void op_add(void)
Definition: nucleus.c:211
M0_INTERNAL void hi_print(const struct m0_dtm_hi *hi)
Definition: nucleus.c:563
M0_INTERNAL void m0_dtm_up_init(struct m0_dtm_up *up, struct m0_dtm_hi *hi, struct m0_dtm_op *op, enum m0_dtm_up_rule rule, m0_dtm_ver_t ver, m0_dtm_ver_t orig_ver)
Definition: nucleus.c:286
static void ctx_init(void)
Definition: nucleus.c:117
M0_INTERNAL void m0_dtm_hi_init(struct m0_dtm_hi *hi, struct m0_dtm_nu *nu)
Definition: nucleus.c:268
static void ctx_add(int hi, int op, enum m0_dtm_up_rule rule, m0_dtm_ver_t ver, m0_dtm_ver_t orig_ver)
Definition: nucleus.c:149
Definition: nucleus.c:42
M0_INTERNAL void m0_dtm_nu_fini(struct m0_dtm_nu *nu)
Definition: nucleus.c:370
Definition: nucleus.c:37
m0_dtm_state
Definition: nucleus.h:52
static void op_miser_delayed(void)
Definition: nucleus.c:313
Definition: nucleus.c:38
struct m0_dtm_up c_up[UP_MAX]
Definition: nucleus.c:46
static void hi(void)
Definition: nucleus.c:93
#define ARRAY_SIZE(a)
Definition: misc.h:45
static void late(struct m0_dtm_op *op)
Definition: nucleus.c:66
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL void m0_dtm_op_prepared(const struct m0_dtm_op *op)
Definition: nucleus.c:97
const struct m0_dtm_hi_ops * hi_ops
Definition: nucleus.h:67
static void op_miser(void)
Definition: nucleus.c:292