blob: bc4d2af8ac43ab6454a45eebd77eaccc37a76c9d [file] [log] [blame]
Craig Tillera26637f2016-05-02 13:36:36 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tillerf7cade12016-07-07 21:41:10 -070034#include "src/core/lib/iomgr/combiner.h"
Craig Tillera26637f2016-05-02 13:36:36 -070035
36#include <grpc/grpc.h>
Craig Tiller9b22a462016-07-07 21:43:58 -070037#include <grpc/support/alloc.h>
Craig Tillera26637f2016-05-02 13:36:36 -070038#include <grpc/support/log.h>
39#include <grpc/support/thd.h>
40#include <grpc/support/useful.h>
41
42#include "test/core/util/test_config.h"
43
44static void test_no_op(void) {
45 gpr_log(GPR_DEBUG, "test_no_op");
Craig Tillere0221ff2016-07-11 15:56:08 -070046 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller3845e552017-02-09 15:19:28 -080047 GRPC_COMBINER_UNREF(&exec_ctx, grpc_combiner_create(NULL), "test_no_op");
Craig Tillere0221ff2016-07-11 15:56:08 -070048 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillera26637f2016-05-02 13:36:36 -070049}
50
Craig Tillerf7cade12016-07-07 21:41:10 -070051static void set_bool_to_true(grpc_exec_ctx *exec_ctx, void *value,
52 grpc_error *error) {
Craig Tillera26637f2016-05-02 13:36:36 -070053 *(bool *)value = true;
54}
55
56static void test_execute_one(void) {
57 gpr_log(GPR_DEBUG, "test_execute_one");
58
Craig Tillerf7cade12016-07-07 21:41:10 -070059 grpc_combiner *lock = grpc_combiner_create(NULL);
Craig Tillera26637f2016-05-02 13:36:36 -070060 bool done = false;
61 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller91031da2016-12-28 15:44:25 -080062 grpc_closure_sched(&exec_ctx,
63 grpc_closure_create(set_bool_to_true, &done,
64 grpc_combiner_scheduler(lock, false)),
65 GRPC_ERROR_NONE);
Craig Tillere0221ff2016-07-11 15:56:08 -070066 grpc_exec_ctx_flush(&exec_ctx);
Craig Tillera26637f2016-05-02 13:36:36 -070067 GPR_ASSERT(done);
Craig Tiller3845e552017-02-09 15:19:28 -080068 GRPC_COMBINER_UNREF(&exec_ctx, lock, "test_execute_one");
Craig Tillere0221ff2016-07-11 15:56:08 -070069 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillera26637f2016-05-02 13:36:36 -070070}
71
72typedef struct {
Craig Tiller2743ba92016-05-02 16:44:20 -070073 size_t ctr;
Craig Tillerf7cade12016-07-07 21:41:10 -070074 grpc_combiner *lock;
Craig Tiller2743ba92016-05-02 16:44:20 -070075} thd_args;
76
77typedef struct {
Craig Tillera26637f2016-05-02 13:36:36 -070078 size_t *ctr;
79 size_t value;
80} ex_args;
81
Craig Tillerf7cade12016-07-07 21:41:10 -070082static void check_one(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
Craig Tillera26637f2016-05-02 13:36:36 -070083 ex_args *args = a;
84 GPR_ASSERT(*args->ctr == args->value - 1);
85 *args->ctr = args->value;
Craig Tiller9b22a462016-07-07 21:43:58 -070086 gpr_free(a);
Craig Tillera26637f2016-05-02 13:36:36 -070087}
88
Craig Tiller2743ba92016-05-02 16:44:20 -070089static void execute_many_loop(void *a) {
90 thd_args *args = a;
Craig Tillera26637f2016-05-02 13:36:36 -070091 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller2743ba92016-05-02 16:44:20 -070092 size_t n = 1;
93 for (size_t i = 0; i < 10; i++) {
Craig Tiller765c5382016-07-07 21:25:04 -070094 for (size_t j = 0; j < 10000; j++) {
Craig Tillere0221ff2016-07-11 15:56:08 -070095 ex_args *c = gpr_malloc(sizeof(*c));
Craig Tiller9b22a462016-07-07 21:43:58 -070096 c->ctr = &args->ctr;
97 c->value = n++;
Craig Tiller91031da2016-12-28 15:44:25 -080098 grpc_closure_sched(
99 &exec_ctx, grpc_closure_create(check_one, c, grpc_combiner_scheduler(
100 args->lock, false)),
101 GRPC_ERROR_NONE);
Craig Tillera26637f2016-05-02 13:36:36 -0700102 grpc_exec_ctx_flush(&exec_ctx);
103 }
Craig Tillerf6b6d292016-09-02 09:27:26 -0700104 // sleep for a little bit, to test a combiner draining and another thread
105 // picking it up
Robbie Shadeca7effc2017-01-17 09:14:29 -0500106 gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
Craig Tillera26637f2016-05-02 13:36:36 -0700107 }
Craig Tiller2743ba92016-05-02 16:44:20 -0700108 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillera26637f2016-05-02 13:36:36 -0700109}
110
111static void test_execute_many(void) {
Craig Tiller2743ba92016-05-02 16:44:20 -0700112 gpr_log(GPR_DEBUG, "test_execute_many");
113
Craig Tillerf7cade12016-07-07 21:41:10 -0700114 grpc_combiner *lock = grpc_combiner_create(NULL);
Craig Tillera26637f2016-05-02 13:36:36 -0700115 gpr_thd_id thds[100];
Craig Tiller2743ba92016-05-02 16:44:20 -0700116 thd_args ta[GPR_ARRAY_SIZE(thds)];
Craig Tillera26637f2016-05-02 13:36:36 -0700117 for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
118 gpr_thd_options options = gpr_thd_options_default();
119 gpr_thd_options_set_joinable(&options);
Craig Tiller2743ba92016-05-02 16:44:20 -0700120 ta[i].ctr = 0;
Craig Tillercf600c92016-05-03 08:26:56 -0700121 ta[i].lock = lock;
Craig Tiller2743ba92016-05-02 16:44:20 -0700122 GPR_ASSERT(gpr_thd_new(&thds[i], execute_many_loop, &ta[i], &options));
Craig Tillera26637f2016-05-02 13:36:36 -0700123 }
124 for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
125 gpr_thd_join(thds[i]);
126 }
Craig Tillere0221ff2016-07-11 15:56:08 -0700127 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller3845e552017-02-09 15:19:28 -0800128 GRPC_COMBINER_UNREF(&exec_ctx, lock, "test_execute_many");
Craig Tillere0221ff2016-07-11 15:56:08 -0700129 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillera26637f2016-05-02 13:36:36 -0700130}
131
Craig Tiller8d8d0d32016-07-08 17:08:57 -0700132static bool got_in_finally = false;
133
134static void in_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
135 got_in_finally = true;
136}
137
138static void add_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
Craig Tiller91031da2016-12-28 15:44:25 -0800139 grpc_closure_sched(exec_ctx, grpc_closure_create(
140 in_finally, NULL,
141 grpc_combiner_finally_scheduler(arg, false)),
142 GRPC_ERROR_NONE);
Craig Tiller8d8d0d32016-07-08 17:08:57 -0700143}
144
Craig Tillera36857d2016-07-08 16:57:42 -0700145static void test_execute_finally(void) {
146 gpr_log(GPR_DEBUG, "test_execute_finally");
147
148 grpc_combiner *lock = grpc_combiner_create(NULL);
Craig Tillera36857d2016-07-08 16:57:42 -0700149 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller91031da2016-12-28 15:44:25 -0800150 grpc_closure_sched(&exec_ctx,
151 grpc_closure_create(add_finally, lock,
152 grpc_combiner_scheduler(lock, false)),
153 GRPC_ERROR_NONE);
Craig Tillere0221ff2016-07-11 15:56:08 -0700154 grpc_exec_ctx_flush(&exec_ctx);
Craig Tiller8d8d0d32016-07-08 17:08:57 -0700155 GPR_ASSERT(got_in_finally);
Craig Tiller3845e552017-02-09 15:19:28 -0800156 GRPC_COMBINER_UNREF(&exec_ctx, lock, "test_execute_finally");
Craig Tillere0221ff2016-07-11 15:56:08 -0700157 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillera36857d2016-07-08 16:57:42 -0700158}
159
Craig Tillera26637f2016-05-02 13:36:36 -0700160int main(int argc, char **argv) {
161 grpc_test_init(argc, argv);
162 grpc_init();
163 test_no_op();
164 test_execute_one();
Craig Tillera36857d2016-07-08 16:57:42 -0700165 test_execute_finally();
Craig Tiller8d8d0d32016-07-08 17:08:57 -0700166 test_execute_many();
Craig Tillera26637f2016-05-02 13:36:36 -0700167 grpc_shutdown();
168
169 return 0;
170}