1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
3*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
4*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
5*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
6*25da2beaSAndroid Build Coastguard Worker #include <string.h>
7*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
8*25da2beaSAndroid Build Coastguard Worker #include <sys/uio.h>
9*25da2beaSAndroid Build Coastguard Worker #include <stdbool.h>
10*25da2beaSAndroid Build Coastguard Worker
11*25da2beaSAndroid Build Coastguard Worker #include "helpers.h"
12*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
13*25da2beaSAndroid Build Coastguard Worker
14*25da2beaSAndroid Build Coastguard Worker #define RING_SIZE 128
15*25da2beaSAndroid Build Coastguard Worker enum {
16*25da2beaSAndroid Build Coastguard Worker OP_NOP,
17*25da2beaSAndroid Build Coastguard Worker OP_REMOVE_BUFFERS
18*25da2beaSAndroid Build Coastguard Worker };
19*25da2beaSAndroid Build Coastguard Worker
20*25da2beaSAndroid Build Coastguard Worker struct test_context {
21*25da2beaSAndroid Build Coastguard Worker struct io_uring *ring;
22*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe **sqes;
23*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqes;
24*25da2beaSAndroid Build Coastguard Worker int nr;
25*25da2beaSAndroid Build Coastguard Worker };
26*25da2beaSAndroid Build Coastguard Worker
free_context(struct test_context * ctx)27*25da2beaSAndroid Build Coastguard Worker static void free_context(struct test_context *ctx)
28*25da2beaSAndroid Build Coastguard Worker {
29*25da2beaSAndroid Build Coastguard Worker free(ctx->sqes);
30*25da2beaSAndroid Build Coastguard Worker free(ctx->cqes);
31*25da2beaSAndroid Build Coastguard Worker memset(ctx, 0, sizeof(*ctx));
32*25da2beaSAndroid Build Coastguard Worker }
33*25da2beaSAndroid Build Coastguard Worker
init_context(struct test_context * ctx,struct io_uring * ring,int nr,int op)34*25da2beaSAndroid Build Coastguard Worker static int init_context(struct test_context *ctx, struct io_uring *ring, int nr,
35*25da2beaSAndroid Build Coastguard Worker int op)
36*25da2beaSAndroid Build Coastguard Worker {
37*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
38*25da2beaSAndroid Build Coastguard Worker int i;
39*25da2beaSAndroid Build Coastguard Worker
40*25da2beaSAndroid Build Coastguard Worker memset(ctx, 0, sizeof(*ctx));
41*25da2beaSAndroid Build Coastguard Worker ctx->nr = nr;
42*25da2beaSAndroid Build Coastguard Worker ctx->ring = ring;
43*25da2beaSAndroid Build Coastguard Worker ctx->sqes = t_malloc(nr * sizeof(*ctx->sqes));
44*25da2beaSAndroid Build Coastguard Worker ctx->cqes = t_malloc(nr * sizeof(*ctx->cqes));
45*25da2beaSAndroid Build Coastguard Worker
46*25da2beaSAndroid Build Coastguard Worker if (!ctx->sqes || !ctx->cqes)
47*25da2beaSAndroid Build Coastguard Worker goto err;
48*25da2beaSAndroid Build Coastguard Worker
49*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++) {
50*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
51*25da2beaSAndroid Build Coastguard Worker if (!sqe)
52*25da2beaSAndroid Build Coastguard Worker goto err;
53*25da2beaSAndroid Build Coastguard Worker switch (op) {
54*25da2beaSAndroid Build Coastguard Worker case OP_NOP:
55*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
56*25da2beaSAndroid Build Coastguard Worker break;
57*25da2beaSAndroid Build Coastguard Worker case OP_REMOVE_BUFFERS:
58*25da2beaSAndroid Build Coastguard Worker io_uring_prep_remove_buffers(sqe, 10, 1);
59*25da2beaSAndroid Build Coastguard Worker break;
60*25da2beaSAndroid Build Coastguard Worker };
61*25da2beaSAndroid Build Coastguard Worker sqe->user_data = i;
62*25da2beaSAndroid Build Coastguard Worker ctx->sqes[i] = sqe;
63*25da2beaSAndroid Build Coastguard Worker }
64*25da2beaSAndroid Build Coastguard Worker
65*25da2beaSAndroid Build Coastguard Worker return 0;
66*25da2beaSAndroid Build Coastguard Worker err:
67*25da2beaSAndroid Build Coastguard Worker free_context(ctx);
68*25da2beaSAndroid Build Coastguard Worker printf("init context failed\n");
69*25da2beaSAndroid Build Coastguard Worker return 1;
70*25da2beaSAndroid Build Coastguard Worker }
71*25da2beaSAndroid Build Coastguard Worker
wait_cqes(struct test_context * ctx)72*25da2beaSAndroid Build Coastguard Worker static int wait_cqes(struct test_context *ctx)
73*25da2beaSAndroid Build Coastguard Worker {
74*25da2beaSAndroid Build Coastguard Worker int ret, i;
75*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
76*25da2beaSAndroid Build Coastguard Worker
77*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < ctx->nr; i++) {
78*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ctx->ring, &cqe);
79*25da2beaSAndroid Build Coastguard Worker
80*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
81*25da2beaSAndroid Build Coastguard Worker printf("wait_cqes: wait completion %d\n", ret);
82*25da2beaSAndroid Build Coastguard Worker return 1;
83*25da2beaSAndroid Build Coastguard Worker }
84*25da2beaSAndroid Build Coastguard Worker memcpy(&ctx->cqes[i], cqe, sizeof(*cqe));
85*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ctx->ring, cqe);
86*25da2beaSAndroid Build Coastguard Worker }
87*25da2beaSAndroid Build Coastguard Worker
88*25da2beaSAndroid Build Coastguard Worker return 0;
89*25da2beaSAndroid Build Coastguard Worker }
90*25da2beaSAndroid Build Coastguard Worker
test_cancelled_userdata(struct io_uring * ring)91*25da2beaSAndroid Build Coastguard Worker static int test_cancelled_userdata(struct io_uring *ring)
92*25da2beaSAndroid Build Coastguard Worker {
93*25da2beaSAndroid Build Coastguard Worker struct test_context ctx;
94*25da2beaSAndroid Build Coastguard Worker int ret, i, nr = 100;
95*25da2beaSAndroid Build Coastguard Worker
96*25da2beaSAndroid Build Coastguard Worker if (init_context(&ctx, ring, nr, OP_NOP))
97*25da2beaSAndroid Build Coastguard Worker return 1;
98*25da2beaSAndroid Build Coastguard Worker
99*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++)
100*25da2beaSAndroid Build Coastguard Worker ctx.sqes[i]->flags |= IOSQE_IO_LINK;
101*25da2beaSAndroid Build Coastguard Worker
102*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
103*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
104*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
105*25da2beaSAndroid Build Coastguard Worker goto err;
106*25da2beaSAndroid Build Coastguard Worker }
107*25da2beaSAndroid Build Coastguard Worker
108*25da2beaSAndroid Build Coastguard Worker if (wait_cqes(&ctx))
109*25da2beaSAndroid Build Coastguard Worker goto err;
110*25da2beaSAndroid Build Coastguard Worker
111*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++) {
112*25da2beaSAndroid Build Coastguard Worker if (i != ctx.cqes[i].user_data) {
113*25da2beaSAndroid Build Coastguard Worker printf("invalid user data\n");
114*25da2beaSAndroid Build Coastguard Worker goto err;
115*25da2beaSAndroid Build Coastguard Worker }
116*25da2beaSAndroid Build Coastguard Worker }
117*25da2beaSAndroid Build Coastguard Worker
118*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
119*25da2beaSAndroid Build Coastguard Worker return 0;
120*25da2beaSAndroid Build Coastguard Worker err:
121*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
122*25da2beaSAndroid Build Coastguard Worker return 1;
123*25da2beaSAndroid Build Coastguard Worker }
124*25da2beaSAndroid Build Coastguard Worker
test_thread_link_cancel(struct io_uring * ring)125*25da2beaSAndroid Build Coastguard Worker static int test_thread_link_cancel(struct io_uring *ring)
126*25da2beaSAndroid Build Coastguard Worker {
127*25da2beaSAndroid Build Coastguard Worker struct test_context ctx;
128*25da2beaSAndroid Build Coastguard Worker int ret, i, nr = 100;
129*25da2beaSAndroid Build Coastguard Worker
130*25da2beaSAndroid Build Coastguard Worker if (init_context(&ctx, ring, nr, OP_REMOVE_BUFFERS))
131*25da2beaSAndroid Build Coastguard Worker return 1;
132*25da2beaSAndroid Build Coastguard Worker
133*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++)
134*25da2beaSAndroid Build Coastguard Worker ctx.sqes[i]->flags |= IOSQE_IO_LINK;
135*25da2beaSAndroid Build Coastguard Worker
136*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
137*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
138*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
139*25da2beaSAndroid Build Coastguard Worker goto err;
140*25da2beaSAndroid Build Coastguard Worker }
141*25da2beaSAndroid Build Coastguard Worker
142*25da2beaSAndroid Build Coastguard Worker if (wait_cqes(&ctx))
143*25da2beaSAndroid Build Coastguard Worker goto err;
144*25da2beaSAndroid Build Coastguard Worker
145*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++) {
146*25da2beaSAndroid Build Coastguard Worker bool fail = false;
147*25da2beaSAndroid Build Coastguard Worker
148*25da2beaSAndroid Build Coastguard Worker if (i == 0)
149*25da2beaSAndroid Build Coastguard Worker fail = (ctx.cqes[i].res != -ENOENT);
150*25da2beaSAndroid Build Coastguard Worker else
151*25da2beaSAndroid Build Coastguard Worker fail = (ctx.cqes[i].res != -ECANCELED);
152*25da2beaSAndroid Build Coastguard Worker
153*25da2beaSAndroid Build Coastguard Worker if (fail) {
154*25da2beaSAndroid Build Coastguard Worker printf("invalid status %d\n", ctx.cqes[i].res);
155*25da2beaSAndroid Build Coastguard Worker goto err;
156*25da2beaSAndroid Build Coastguard Worker }
157*25da2beaSAndroid Build Coastguard Worker }
158*25da2beaSAndroid Build Coastguard Worker
159*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
160*25da2beaSAndroid Build Coastguard Worker return 0;
161*25da2beaSAndroid Build Coastguard Worker err:
162*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
163*25da2beaSAndroid Build Coastguard Worker return 1;
164*25da2beaSAndroid Build Coastguard Worker }
165*25da2beaSAndroid Build Coastguard Worker
test_drain_with_linked_timeout(struct io_uring * ring)166*25da2beaSAndroid Build Coastguard Worker static int test_drain_with_linked_timeout(struct io_uring *ring)
167*25da2beaSAndroid Build Coastguard Worker {
168*25da2beaSAndroid Build Coastguard Worker const int nr = 3;
169*25da2beaSAndroid Build Coastguard Worker struct __kernel_timespec ts = { .tv_sec = 1, .tv_nsec = 0, };
170*25da2beaSAndroid Build Coastguard Worker struct test_context ctx;
171*25da2beaSAndroid Build Coastguard Worker int ret, i;
172*25da2beaSAndroid Build Coastguard Worker
173*25da2beaSAndroid Build Coastguard Worker if (init_context(&ctx, ring, nr * 2, OP_NOP))
174*25da2beaSAndroid Build Coastguard Worker return 1;
175*25da2beaSAndroid Build Coastguard Worker
176*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++) {
177*25da2beaSAndroid Build Coastguard Worker io_uring_prep_timeout(ctx.sqes[2 * i], &ts, 0, 0);
178*25da2beaSAndroid Build Coastguard Worker ctx.sqes[2 * i]->flags |= IOSQE_IO_LINK | IOSQE_IO_DRAIN;
179*25da2beaSAndroid Build Coastguard Worker io_uring_prep_link_timeout(ctx.sqes[2 * i + 1], &ts, 0);
180*25da2beaSAndroid Build Coastguard Worker }
181*25da2beaSAndroid Build Coastguard Worker
182*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
183*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
184*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
185*25da2beaSAndroid Build Coastguard Worker goto err;
186*25da2beaSAndroid Build Coastguard Worker }
187*25da2beaSAndroid Build Coastguard Worker
188*25da2beaSAndroid Build Coastguard Worker if (wait_cqes(&ctx))
189*25da2beaSAndroid Build Coastguard Worker goto err;
190*25da2beaSAndroid Build Coastguard Worker
191*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
192*25da2beaSAndroid Build Coastguard Worker return 0;
193*25da2beaSAndroid Build Coastguard Worker err:
194*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
195*25da2beaSAndroid Build Coastguard Worker return 1;
196*25da2beaSAndroid Build Coastguard Worker }
197*25da2beaSAndroid Build Coastguard Worker
run_drained(struct io_uring * ring,int nr)198*25da2beaSAndroid Build Coastguard Worker static int run_drained(struct io_uring *ring, int nr)
199*25da2beaSAndroid Build Coastguard Worker {
200*25da2beaSAndroid Build Coastguard Worker struct test_context ctx;
201*25da2beaSAndroid Build Coastguard Worker int ret, i;
202*25da2beaSAndroid Build Coastguard Worker
203*25da2beaSAndroid Build Coastguard Worker if (init_context(&ctx, ring, nr, OP_NOP))
204*25da2beaSAndroid Build Coastguard Worker return 1;
205*25da2beaSAndroid Build Coastguard Worker
206*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++)
207*25da2beaSAndroid Build Coastguard Worker ctx.sqes[i]->flags |= IOSQE_IO_DRAIN;
208*25da2beaSAndroid Build Coastguard Worker
209*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
210*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
211*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
212*25da2beaSAndroid Build Coastguard Worker goto err;
213*25da2beaSAndroid Build Coastguard Worker }
214*25da2beaSAndroid Build Coastguard Worker
215*25da2beaSAndroid Build Coastguard Worker if (wait_cqes(&ctx))
216*25da2beaSAndroid Build Coastguard Worker goto err;
217*25da2beaSAndroid Build Coastguard Worker
218*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
219*25da2beaSAndroid Build Coastguard Worker return 0;
220*25da2beaSAndroid Build Coastguard Worker err:
221*25da2beaSAndroid Build Coastguard Worker free_context(&ctx);
222*25da2beaSAndroid Build Coastguard Worker return 1;
223*25da2beaSAndroid Build Coastguard Worker }
224*25da2beaSAndroid Build Coastguard Worker
test_overflow_hung(struct io_uring * ring)225*25da2beaSAndroid Build Coastguard Worker static int test_overflow_hung(struct io_uring *ring)
226*25da2beaSAndroid Build Coastguard Worker {
227*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
228*25da2beaSAndroid Build Coastguard Worker int ret, nr = 10;
229*25da2beaSAndroid Build Coastguard Worker
230*25da2beaSAndroid Build Coastguard Worker while (*ring->cq.koverflow != 1000) {
231*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
232*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
233*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
234*25da2beaSAndroid Build Coastguard Worker return 1;
235*25da2beaSAndroid Build Coastguard Worker }
236*25da2beaSAndroid Build Coastguard Worker
237*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
238*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
239*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
240*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
241*25da2beaSAndroid Build Coastguard Worker return 1;
242*25da2beaSAndroid Build Coastguard Worker }
243*25da2beaSAndroid Build Coastguard Worker }
244*25da2beaSAndroid Build Coastguard Worker
245*25da2beaSAndroid Build Coastguard Worker return run_drained(ring, nr);
246*25da2beaSAndroid Build Coastguard Worker }
247*25da2beaSAndroid Build Coastguard Worker
test_dropped_hung(struct io_uring * ring)248*25da2beaSAndroid Build Coastguard Worker static int test_dropped_hung(struct io_uring *ring)
249*25da2beaSAndroid Build Coastguard Worker {
250*25da2beaSAndroid Build Coastguard Worker int nr = 10;
251*25da2beaSAndroid Build Coastguard Worker
252*25da2beaSAndroid Build Coastguard Worker *ring->sq.kdropped = 1000;
253*25da2beaSAndroid Build Coastguard Worker return run_drained(ring, nr);
254*25da2beaSAndroid Build Coastguard Worker }
255*25da2beaSAndroid Build Coastguard Worker
main(int argc,char * argv[])256*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
257*25da2beaSAndroid Build Coastguard Worker {
258*25da2beaSAndroid Build Coastguard Worker struct io_uring ring, poll_ring, sqthread_ring;
259*25da2beaSAndroid Build Coastguard Worker struct io_uring_params p;
260*25da2beaSAndroid Build Coastguard Worker int ret;
261*25da2beaSAndroid Build Coastguard Worker
262*25da2beaSAndroid Build Coastguard Worker if (argc > 1)
263*25da2beaSAndroid Build Coastguard Worker return 0;
264*25da2beaSAndroid Build Coastguard Worker
265*25da2beaSAndroid Build Coastguard Worker memset(&p, 0, sizeof(p));
266*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init_params(RING_SIZE, &ring, &p);
267*25da2beaSAndroid Build Coastguard Worker if (ret) {
268*25da2beaSAndroid Build Coastguard Worker printf("ring setup failed %i\n", ret);
269*25da2beaSAndroid Build Coastguard Worker return 1;
270*25da2beaSAndroid Build Coastguard Worker }
271*25da2beaSAndroid Build Coastguard Worker
272*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(RING_SIZE, &poll_ring, IORING_SETUP_IOPOLL);
273*25da2beaSAndroid Build Coastguard Worker if (ret) {
274*25da2beaSAndroid Build Coastguard Worker printf("poll_ring setup failed\n");
275*25da2beaSAndroid Build Coastguard Worker return 1;
276*25da2beaSAndroid Build Coastguard Worker }
277*25da2beaSAndroid Build Coastguard Worker
278*25da2beaSAndroid Build Coastguard Worker
279*25da2beaSAndroid Build Coastguard Worker ret = test_cancelled_userdata(&poll_ring);
280*25da2beaSAndroid Build Coastguard Worker if (ret) {
281*25da2beaSAndroid Build Coastguard Worker printf("test_cancelled_userdata failed\n");
282*25da2beaSAndroid Build Coastguard Worker return ret;
283*25da2beaSAndroid Build Coastguard Worker }
284*25da2beaSAndroid Build Coastguard Worker
285*25da2beaSAndroid Build Coastguard Worker if (!(p.features & IORING_FEAT_NODROP)) {
286*25da2beaSAndroid Build Coastguard Worker ret = test_overflow_hung(&ring);
287*25da2beaSAndroid Build Coastguard Worker if (ret) {
288*25da2beaSAndroid Build Coastguard Worker printf("test_overflow_hung failed\n");
289*25da2beaSAndroid Build Coastguard Worker return ret;
290*25da2beaSAndroid Build Coastguard Worker }
291*25da2beaSAndroid Build Coastguard Worker }
292*25da2beaSAndroid Build Coastguard Worker
293*25da2beaSAndroid Build Coastguard Worker ret = test_dropped_hung(&ring);
294*25da2beaSAndroid Build Coastguard Worker if (ret) {
295*25da2beaSAndroid Build Coastguard Worker printf("test_dropped_hung failed\n");
296*25da2beaSAndroid Build Coastguard Worker return ret;
297*25da2beaSAndroid Build Coastguard Worker }
298*25da2beaSAndroid Build Coastguard Worker
299*25da2beaSAndroid Build Coastguard Worker ret = test_drain_with_linked_timeout(&ring);
300*25da2beaSAndroid Build Coastguard Worker if (ret) {
301*25da2beaSAndroid Build Coastguard Worker printf("test_drain_with_linked_timeout failed\n");
302*25da2beaSAndroid Build Coastguard Worker return ret;
303*25da2beaSAndroid Build Coastguard Worker }
304*25da2beaSAndroid Build Coastguard Worker
305*25da2beaSAndroid Build Coastguard Worker ret = t_create_ring(RING_SIZE, &sqthread_ring,
306*25da2beaSAndroid Build Coastguard Worker IORING_SETUP_SQPOLL | IORING_SETUP_IOPOLL);
307*25da2beaSAndroid Build Coastguard Worker if (ret == T_SETUP_SKIP)
308*25da2beaSAndroid Build Coastguard Worker return 0;
309*25da2beaSAndroid Build Coastguard Worker else if (ret < 0)
310*25da2beaSAndroid Build Coastguard Worker return 1;
311*25da2beaSAndroid Build Coastguard Worker
312*25da2beaSAndroid Build Coastguard Worker ret = test_thread_link_cancel(&sqthread_ring);
313*25da2beaSAndroid Build Coastguard Worker if (ret) {
314*25da2beaSAndroid Build Coastguard Worker printf("test_thread_link_cancel failed\n");
315*25da2beaSAndroid Build Coastguard Worker return ret;
316*25da2beaSAndroid Build Coastguard Worker }
317*25da2beaSAndroid Build Coastguard Worker
318*25da2beaSAndroid Build Coastguard Worker return 0;
319*25da2beaSAndroid Build Coastguard Worker }
320