Motr  M0
coroutine.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2017-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 
23 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_UT
24 #include "lib/trace.h"
25 #include "lib/coroutine.h"
26 #include "lib/string.h"
27 #include "ut/ut.h"
28 
29 #define F M0_CO_FRAME_DATA
30 
31 static void foo0(struct m0_co_context *context, int nr, int *ret);
32 static void foo1(struct m0_co_context *context, int *ret);
33 static void foo2(struct m0_co_context *context, int *ret);
34 
35 
36 static void foo0(struct m0_co_context *context, int nr, int *ret)
37 {
38  static const char *foo0_str = "FooBarBuzz";
39  M0_CO_REENTER(context,
40  int nr;
41  int a;
42  char b[100];
43  int rc;
44  int rc1;
45  int i;
46  int sum;
47  );
48  F(sum) = 0;
49  F(rc) = 101;
50  F(a) = 0x200;
51  F(nr) = nr;
52  strncpy(F(b), foo0_str, ARRAY_SIZE(F(b)));
53 
54  M0_CO_FUN(context, foo1(context, &F(rc1)));
55 
56  M0_UT_ASSERT(F(rc) == 101);
57  M0_UT_ASSERT(F(rc1) == 302);
58  M0_UT_ASSERT(F(a) == 0x200);
59  M0_UT_ASSERT(m0_streq(F(b), foo0_str));
60 
61  M0_CO_YIELD(context);
62 
63  M0_UT_ASSERT(F(rc) == 101);
64  M0_UT_ASSERT(F(rc1) == 302);
65  M0_UT_ASSERT(F(a) == 0x200);
66  M0_UT_ASSERT(m0_streq(F(b), foo0_str));
67 
68  for (F(i) = 0; F(i) < F(nr); F(i)++) {
69  M0_CO_FUN(context, foo1(context, &F(rc1)));
70  F(sum) += F(rc1);
71  }
72 
73  M0_UT_ASSERT(F(sum) == 302*F(nr));
74 
75  *ret = 301;
76 }
77 
78 static void foo1(struct m0_co_context *context, int *ret)
79 {
80  M0_CO_REENTER(context,
81  int d;
82  int rc;
83  int rc1;
84  );
85 
86  F(rc) = 102;
87  F(d) = 0x100;
88 
89  M0_CO_FUN(context, foo2(context, &F(rc1)));
90 
91  M0_UT_ASSERT(F(rc) == 102);
92  M0_UT_ASSERT(F(d) == 0x100);
93  M0_UT_ASSERT(F(rc1) == 303);
94 
95  M0_CO_FUN(context, foo2(context, &F(rc1)));
96 
97  M0_UT_ASSERT(F(rc) == 102);
98  M0_UT_ASSERT(F(rc1) == 303);
99  M0_UT_ASSERT(F(d) == 0x100);
100 
101  *ret = 302;
102 }
103 
104 static void foo2(struct m0_co_context *context, int *ret)
105 {
106  M0_CO_REENTER(context,
107  char *c;
108  int rc;
109  );
110 
111  F(rc) = 103;
112 
113  M0_CO_YIELD(context);
114 
115  M0_UT_ASSERT(F(rc) == 103);
116  F(rc) = 303;
117 
118  *ret = F(rc);
119 }
120 
122 {
123  struct m0_co_context context[10] = {};
124  int i;
125  int rc;
126  int ret;
127  int rcx[10];
128 
129  for (i = 0; i < ARRAY_SIZE(context); ++i) {
130  rc = m0_co_context_init(&context[i]);
131  M0_UT_ASSERT(rc == 0);
132  rcx[i] = -EAGAIN;
133  }
134 
135  rc = -EAGAIN;
136  while (rc == -EAGAIN) {
137  rc = 0;
138  for (i = 0; i < ARRAY_SIZE(context); ++i) {
139  if (rcx[i] == -EAGAIN) {
140  M0_CO_START(&context[i]);
141  foo0(&context[i], i+10, &ret);
142  rcx[i] = M0_CO_END(&context[i]);
143  }
144 
145  if (rcx[i] == -EAGAIN)
146  rc = -EAGAIN;
147  }
148  }
149 
150  for (i = 0; i < ARRAY_SIZE(context); ++i)
151  m0_co_context_fini(&context[i]);
152 
153  return 0;
154 }
155 
156 
157 /*
158  * Local variables:
159  * c-indentation-style: "K&R"
160  * c-basic-offset: 8
161  * tab-width: 8
162  * fill-column: 80
163  * scroll-step: 1
164  * End:
165  */
166 /*
167  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
168  */
static size_t nr
Definition: dump.c:1505
M0_INTERNAL void m0_co_context_fini(struct m0_co_context *context)
Definition: coroutine.c:136
static void foo2(struct m0_co_context *context, int *ret)
Definition: coroutine.c:104
static int sum
Definition: rwlock.c:53
#define M0_CO_START(context)
Definition: coroutine.h:157
#define M0_CO_END(context)
Definition: coroutine.h:167
int m0_test_coroutine(void)
Definition: coroutine.c:121
int i
Definition: dir.c:1033
static struct m0_addb2_callback c
Definition: consumer.c:41
#define m0_streq(a, b)
Definition: string.h:34
static void foo0(struct m0_co_context *context, int nr, int *ret)
Definition: coroutine.c:36
#define M0_CO_YIELD(context)
Definition: coroutine.h:266
#define M0_CO_FUN(context, function)
Definition: coroutine.h:183
M0_INTERNAL int m0_co_context_init(struct m0_co_context *context)
Definition: coroutine.c:130
#define M0_CO_REENTER(context,...)
Definition: coroutine.h:205
#define F
Definition: coroutine.c:29
static void foo1(struct m0_co_context *context, int *ret)
Definition: coroutine.c:78
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define M0_UT_ASSERT(a)
Definition: ut.h:46