diff options
author | Craig Tiller <ctiller@google.com> | 2017-02-27 07:24:00 -0800 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2017-02-27 07:24:00 -0800 |
commit | edbf2b9d13445221c9d8858c00cea02435570fe0 (patch) | |
tree | 9cb8deb7f5cb9dc4855d4082b6581550fe455529 | |
parent | ca8de5c1c3aa47bff5ab83482ed4b33c8cbc3047 (diff) |
Add a spinlock type.
Useful for situations where we need to repeatedly trylock, not useful
for cases where we need to lock (due to spinning).
Add a variant of sync_test to test it (with the same tests we run for
gpr_mu).
Add a benchmark to bm_closure to demonstrate single threaded performance.
-rw-r--r-- | BUILD | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 26 | ||||
-rw-r--r-- | Makefile | 36 | ||||
-rw-r--r-- | build.yaml | 10 | ||||
-rw-r--r-- | gRPC-Core.podspec | 2 | ||||
-rwxr-xr-x | grpc.gemspec | 1 | ||||
-rw-r--r-- | package.xml | 1 | ||||
-rw-r--r-- | src/core/lib/iomgr/timer_generic.c | 9 | ||||
-rw-r--r-- | src/core/lib/support/spinlock.h | 50 | ||||
-rw-r--r-- | test/core/support/BUILD | 7 | ||||
-rw-r--r-- | test/core/support/spinlock_test.c | 158 | ||||
-rw-r--r-- | test/cpp/microbenchmarks/bm_closure.cc | 50 | ||||
-rw-r--r-- | tools/doxygen/Doxyfile.core.internal | 1 | ||||
-rw-r--r-- | tools/run_tests/generated/sources_and_headers.json | 17 | ||||
-rw-r--r-- | tools/run_tests/generated/tests.json | 22 | ||||
-rw-r--r-- | vsprojects/buildtests_c.sln | 25 | ||||
-rw-r--r-- | vsprojects/vcxproj/gpr/gpr.vcxproj | 1 | ||||
-rw-r--r-- | vsprojects/vcxproj/gpr/gpr.vcxproj.filters | 3 | ||||
-rw-r--r-- | vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj | 193 | ||||
-rw-r--r-- | vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj.filters | 21 |
20 files changed, 629 insertions, 5 deletions
@@ -359,6 +359,7 @@ grpc_cc_library( "src/core/lib/support/env.h", "src/core/lib/support/mpscq.h", "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/spinlock.h", "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.h", "src/core/lib/support/string_windows.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 383d575a34..29440f298a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -382,6 +382,7 @@ add_dependencies(buildtests_c gpr_histogram_test) add_dependencies(buildtests_c gpr_host_port_test) add_dependencies(buildtests_c gpr_log_test) add_dependencies(buildtests_c gpr_mpscq_test) +add_dependencies(buildtests_c gpr_spinlock_test) add_dependencies(buildtests_c gpr_stack_lockfree_test) add_dependencies(buildtests_c gpr_string_test) add_dependencies(buildtests_c gpr_sync_test) @@ -5104,6 +5105,31 @@ target_link_libraries(gpr_mpscq_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(gpr_spinlock_test + test/core/support/spinlock_test.c +) + + +target_include_directories(gpr_spinlock_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include +) + +target_link_libraries(gpr_spinlock_test + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr_test_util + gpr +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(gpr_stack_lockfree_test test/core/support/stack_lockfree_test.c ) @@ -946,6 +946,7 @@ gpr_histogram_test: $(BINDIR)/$(CONFIG)/gpr_histogram_test gpr_host_port_test: $(BINDIR)/$(CONFIG)/gpr_host_port_test gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test gpr_mpscq_test: $(BINDIR)/$(CONFIG)/gpr_mpscq_test +gpr_spinlock_test: $(BINDIR)/$(CONFIG)/gpr_spinlock_test gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test gpr_string_test: $(BINDIR)/$(CONFIG)/gpr_string_test gpr_sync_test: $(BINDIR)/$(CONFIG)/gpr_sync_test @@ -1310,6 +1311,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/gpr_host_port_test \ $(BINDIR)/$(CONFIG)/gpr_log_test \ $(BINDIR)/$(CONFIG)/gpr_mpscq_test \ + $(BINDIR)/$(CONFIG)/gpr_spinlock_test \ $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \ $(BINDIR)/$(CONFIG)/gpr_string_test \ $(BINDIR)/$(CONFIG)/gpr_sync_test \ @@ -1705,6 +1707,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/gpr_log_test || ( echo test gpr_log_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_mpscq_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_mpscq_test || ( echo test gpr_mpscq_test failed ; exit 1 ) + $(E) "[RUN] Testing gpr_spinlock_test" + $(Q) $(BINDIR)/$(CONFIG)/gpr_spinlock_test || ( echo test gpr_spinlock_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_stack_lockfree_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test || ( echo test gpr_stack_lockfree_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_string_test" @@ -9273,6 +9277,38 @@ endif endif +GPR_SPINLOCK_TEST_SRC = \ + test/core/support/spinlock_test.c \ + +GPR_SPINLOCK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_SPINLOCK_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/gpr_spinlock_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_spinlock_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/support/spinlock_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GPR_SPINLOCK_TEST_OBJS:.o=.dep) +endif +endif + + GPR_STACK_LOCKFREE_TEST_SRC = \ test/core/support/stack_lockfree_test.c \ diff --git a/build.yaml b/build.yaml index 19bdb796d7..524b8b92e3 100644 --- a/build.yaml +++ b/build.yaml @@ -90,6 +90,7 @@ filegroups: - src/core/lib/support/env.h - src/core/lib/support/mpscq.h - src/core/lib/support/murmur_hash.h + - src/core/lib/support/spinlock.h - src/core/lib/support/stack_lockfree.h - src/core/lib/support/string.h - src/core/lib/support/string_windows.h @@ -1895,6 +1896,15 @@ targets: deps: - gpr_test_util - gpr +- name: gpr_spinlock_test + cpu_cost: 10 + build: test + language: c + src: + - test/core/support/spinlock_test.c + deps: + - gpr_test_util + - gpr - name: gpr_stack_lockfree_test cpu_cost: 7 build: test diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 759310346f..beb72276d2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -201,6 +201,7 @@ Pod::Spec.new do |s| 'src/core/lib/support/env.h', 'src/core/lib/support/mpscq.h', 'src/core/lib/support/murmur_hash.h', + 'src/core/lib/support/spinlock.h', 'src/core/lib/support/stack_lockfree.h', 'src/core/lib/support/string.h', 'src/core/lib/support/string_windows.h', @@ -679,6 +680,7 @@ Pod::Spec.new do |s| 'src/core/lib/support/env.h', 'src/core/lib/support/mpscq.h', 'src/core/lib/support/murmur_hash.h', + 'src/core/lib/support/spinlock.h', 'src/core/lib/support/stack_lockfree.h', 'src/core/lib/support/string.h', 'src/core/lib/support/string_windows.h', diff --git a/grpc.gemspec b/grpc.gemspec index 5cc73915f3..8d5b7b2ab1 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -87,6 +87,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/support/env.h ) s.files += %w( src/core/lib/support/mpscq.h ) s.files += %w( src/core/lib/support/murmur_hash.h ) + s.files += %w( src/core/lib/support/spinlock.h ) s.files += %w( src/core/lib/support/stack_lockfree.h ) s.files += %w( src/core/lib/support/string.h ) s.files += %w( src/core/lib/support/string_windows.h ) diff --git a/package.xml b/package.xml index e4db6a7d2e..d82f2e49a8 100644 --- a/package.xml +++ b/package.xml @@ -96,6 +96,7 @@ <file baseinstalldir="/" name="src/core/lib/support/env.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/mpscq.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/support/spinlock.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" /> diff --git a/src/core/lib/iomgr/timer_generic.c b/src/core/lib/iomgr/timer_generic.c index 6d638bcbaa..09ff2d0c3c 100644 --- a/src/core/lib/iomgr/timer_generic.c +++ b/src/core/lib/iomgr/timer_generic.c @@ -42,6 +42,7 @@ #include <grpc/support/useful.h> #include "src/core/lib/iomgr/time_averaged_stats.h" #include "src/core/lib/iomgr/timer_heap.h" +#include "src/core/lib/support/spinlock.h" #define INVALID_HEAP_INDEX 0xffffffffu @@ -69,7 +70,7 @@ typedef struct { /* Protects g_shard_queue */ static gpr_mu g_mu; /* Allow only one run_some_expired_timers at once */ -static gpr_mu g_checker_mu; +static gpr_spinlock g_checker_mu = GPR_SPINLOCK_INITIALIZER; static gpr_clock_type g_clock_type; static shard_type g_shards[NUM_SHARDS]; /* Protected by g_mu */ @@ -90,7 +91,6 @@ void grpc_timer_list_init(gpr_timespec now) { g_initialized = true; gpr_mu_init(&g_mu); - gpr_mu_init(&g_checker_mu); g_clock_type = now.clock_type; for (i = 0; i < NUM_SHARDS; i++) { @@ -117,7 +117,6 @@ void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx) { grpc_timer_heap_destroy(&shard->heap); } gpr_mu_destroy(&g_mu); - gpr_mu_destroy(&g_checker_mu); g_initialized = false; } @@ -324,7 +323,7 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now, /* TODO(ctiller): verify that there are any timers (atomically) here */ - if (gpr_mu_trylock(&g_checker_mu)) { + if (gpr_spinlock_trylock(&g_checker_mu)) { gpr_mu_lock(&g_mu); while (gpr_time_cmp(g_shard_queue[0]->min_deadline, now) < 0) { @@ -350,7 +349,7 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now, } gpr_mu_unlock(&g_mu); - gpr_mu_unlock(&g_checker_mu); + gpr_spinlock_unlock(&g_checker_mu); } else if (next != NULL) { /* TODO(ctiller): this forces calling code to do an short poll, and then retry the timer check (because this time through the timer list was diff --git a/src/core/lib/support/spinlock.h b/src/core/lib/support/spinlock.h new file mode 100644 index 0000000000..aeb5622726 --- /dev/null +++ b/src/core/lib/support/spinlock.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_SUPPORT_SPINLOCK_H +#define GRPC_CORE_LIB_SUPPORT_SPINLOCK_H + +#include <grpc/support/atm.h> + +/* Simple spinlock. No backoff strategy, gpr_spinlock_lock is almost always + a concurrency code smell. */ +typedef struct { gpr_atm atm; } gpr_spinlock; + +#define GPR_SPINLOCK_INITIALIZER ((gpr_spinlock){0}) +#define gpr_spinlock_trylock(lock) (gpr_atm_acq_cas(&(lock)->atm, 0, 1)) +#define gpr_spinlock_unlock(lock) (gpr_atm_rel_store(&(lock)->atm, 0)) +#define gpr_spinlock_lock(lock) \ + do { \ + } while (!gpr_spinlock_trylock((lock))) + +#endif // GRPC_CORE_LIB_SUPPORT_SPINLOCK_H diff --git a/test/core/support/BUILD b/test/core/support/BUILD index dfe952eb37..08cee1441b 100644 --- a/test/core/support/BUILD +++ b/test/core/support/BUILD @@ -119,6 +119,13 @@ cc_test( ) cc_test( + name = "spinlock_test", + srcs = ["spinlock_test.c"], + deps = ["//:gpr", "//test/core/util:gpr_test_util"], + copts = ['-std=c99'] +) + +cc_test( name = "sync_test", srcs = ["sync_test.c"], deps = ["//:gpr", "//test/core/util:gpr_test_util"], diff --git a/test/core/support/spinlock_test.c b/test/core/support/spinlock_test.c new file mode 100644 index 0000000000..20b402a705 --- /dev/null +++ b/test/core/support/spinlock_test.c @@ -0,0 +1,158 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Test of gpr synchronization support. */ + +#include "src/core/lib/support/spinlock.h" +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> +#include <grpc/support/time.h> +#include <stdio.h> +#include <stdlib.h> +#include "test/core/util/test_config.h" + +/* ------------------------------------------------- */ +/* Tests for gpr_spinlock. */ +struct test { + int thread_count; /* number of threads */ + gpr_thd_id *threads; + + int64_t iterations; /* number of iterations per thread */ + int64_t counter; + int incr_step; /* how much to increment/decrement refcount each time */ + + gpr_spinlock mu; /* protects iterations, counter */ +}; + +/* Return pointer to a new struct test. */ +static struct test *test_new(int threads, int64_t iterations, int incr_step) { + struct test *m = gpr_malloc(sizeof(*m)); + m->thread_count = threads; + m->threads = gpr_malloc(sizeof(*m->threads) * (size_t)threads); + m->iterations = iterations; + m->counter = 0; + m->thread_count = 0; + m->incr_step = incr_step; + m->mu = GPR_SPINLOCK_INITIALIZER; + return m; +} + +/* Return pointer to a new struct test. */ +static void test_destroy(struct test *m) { gpr_free(m); } + +/* Create m->threads threads, each running (*body)(m) */ +static void test_create_threads(struct test *m, void (*body)(void *arg)) { + int i; + for (i = 0; i != m->thread_count; i++) { + gpr_thd_options opt = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&opt); + GPR_ASSERT(gpr_thd_new(&m->threads[i], body, m, &opt)); + } +} + +/* Wait until all threads report done. */ +static void test_wait(struct test *m) { + int i; + for (i = 0; i != m->thread_count; i++) { + gpr_thd_join(m->threads[i]); + } +} + +/* Test several threads running (*body)(struct test *m) for increasing settings + of m->iterations, until about timeout_s to 2*timeout_s seconds have elapsed. + If extra!=NULL, run (*extra)(m) in an additional thread. + incr_step controls by how much m->refcount should be incremented/decremented + (if at all) each time in the tests. + */ +static void test(const char *name, void (*body)(void *m), int timeout_s, + int incr_step) { + int64_t iterations = 1024; + struct test *m; + gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); + gpr_timespec time_taken; + gpr_timespec deadline = gpr_time_add( + start, gpr_time_from_micros((int64_t)timeout_s * 1000000, GPR_TIMESPAN)); + fprintf(stderr, "%s:", name); + while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) { + iterations <<= 1; + fprintf(stderr, " %ld", (long)iterations); + m = test_new(10, iterations, incr_step); + test_create_threads(m, body); + test_wait(m); + if (m->counter != m->thread_count * m->iterations * m->incr_step) { + fprintf(stderr, "counter %ld threads %d iterations %ld\n", + (long)m->counter, m->thread_count, (long)m->iterations); + GPR_ASSERT(0); + } + test_destroy(m); + } + time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start); + fprintf(stderr, " done %lld.%09d s\n", (long long)time_taken.tv_sec, + (int)time_taken.tv_nsec); +} + +/* Increment m->counter on each iteration; then mark thread as done. */ +static void inc(void *v /*=m*/) { + struct test *m = v; + int64_t i; + for (i = 0; i != m->iterations; i++) { + gpr_spinlock_lock(&m->mu); + m->counter++; + gpr_spinlock_unlock(&m->mu); + } +} + +/* Increment m->counter under lock acquired with trylock, m->iterations times; + then mark thread as done. */ +static void inctry(void *v /*=m*/) { + struct test *m = v; + int64_t i; + for (i = 0; i != m->iterations;) { + if (gpr_spinlock_trylock(&m->mu)) { + m->counter++; + gpr_spinlock_unlock(&m->mu); + i++; + } + } +} + +/* ------------------------------------------------- */ + +int main(int argc, char *argv[]) { + grpc_test_init(argc, argv); + test("spinlock", &inc, 1, 1); + test("spinlock try", &inctry, 1, 1); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc index 03aede35b2..1f54e8c8b1 100644 --- a/test/cpp/microbenchmarks/bm_closure.cc +++ b/test/cpp/microbenchmarks/bm_closure.cc @@ -39,6 +39,7 @@ extern "C" { #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/support/spinlock.h" } #include "third_party/benchmark/include/benchmark/benchmark.h" @@ -234,6 +235,55 @@ static void BM_AcquireMutex(benchmark::State& state) { } BENCHMARK(BM_AcquireMutex); +static void BM_TryAcquireMutex(benchmark::State& state) { + TrackCounters track_counters(state); + // for comparison with the combiner stuff below + gpr_mu mu; + gpr_mu_init(&mu); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + while (state.KeepRunning()) { + if (gpr_mu_trylock(&mu)) { + DoNothing(&exec_ctx, NULL, GRPC_ERROR_NONE); + gpr_mu_unlock(&mu); + } else { + abort(); + } + } + grpc_exec_ctx_finish(&exec_ctx); +} +BENCHMARK(BM_TryAcquireMutex); + +static void BM_AcquireSpinlock(benchmark::State& state) { + TrackCounters track_counters(state); + // for comparison with the combiner stuff below + gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + while (state.KeepRunning()) { + gpr_spinlock_lock(&mu); + DoNothing(&exec_ctx, NULL, GRPC_ERROR_NONE); + gpr_spinlock_unlock(&mu); + } + grpc_exec_ctx_finish(&exec_ctx); +} +BENCHMARK(BM_AcquireSpinlock); + +static void BM_TryAcquireSpinlock(benchmark::State& state) { + TrackCounters track_counters(state); + // for comparison with the combiner stuff below + gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + while (state.KeepRunning()) { + if (gpr_spinlock_trylock(&mu)) { + DoNothing(&exec_ctx, NULL, GRPC_ERROR_NONE); + gpr_spinlock_unlock(&mu); + } else { + abort(); + } + } + grpc_exec_ctx_finish(&exec_ctx); +} +BENCHMARK(BM_TryAcquireSpinlock); + static void BM_ClosureSchedOnCombiner(benchmark::State& state) { TrackCounters track_counters(state); grpc_combiner* combiner = grpc_combiner_create(NULL); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 10801254ef..04fd7bee22 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1249,6 +1249,7 @@ src/core/lib/support/mpscq.c \ src/core/lib/support/mpscq.h \ src/core/lib/support/murmur_hash.c \ src/core/lib/support/murmur_hash.h \ +src/core/lib/support/spinlock.h \ src/core/lib/support/stack_lockfree.c \ src/core/lib/support/stack_lockfree.h \ src/core/lib/support/string.c \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8cf282a389..6d9f3e79b5 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -739,6 +739,21 @@ "headers": [], "is_filegroup": false, "language": "c", + "name": "gpr_spinlock_test", + "src": [ + "test/core/support/spinlock_test.c" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "gpr_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", "name": "gpr_stack_lockfree_test", "src": [ "test/core/support/stack_lockfree_test.c" @@ -7009,6 +7024,7 @@ "src/core/lib/support/env.h", "src/core/lib/support/mpscq.h", "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/spinlock.h", "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.h", "src/core/lib/support/string_windows.h", @@ -7074,6 +7090,7 @@ "src/core/lib/support/mpscq.h", "src/core/lib/support/murmur_hash.c", "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/spinlock.h", "src/core/lib/support/stack_lockfree.c", "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.c", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 8e843d07c0..7796ac732b 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -845,6 +845,28 @@ "posix", "windows" ], + "cpu_cost": 10, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "gpr_spinlock_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], "cpu_cost": 7, "exclude_configs": [], "exclude_iomgrs": [], diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln index 12a45ee1f8..539ac930ca 100644 --- a/vsprojects/buildtests_c.sln +++ b/vsprojects/buildtests_c.sln @@ -424,6 +424,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_mpscq_test", "vcxproj\t {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_spinlock_test", "vcxproj\test\gpr_spinlock_test\gpr_spinlock_test.vcxproj", "{D8EDE51A-CBB2-0362-D59B-09AA92A94F45}" + ProjectSection(myProperties) = preProject + lib = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_stack_lockfree_test", "vcxproj\test\gpr_stack_lockfree_test\gpr_stack_lockfree_test.vcxproj", "{AD06B5CD-8D5C-A365-C46B-3CF32237A4F7}" ProjectSection(myProperties) = preProject lib = "False" @@ -2241,6 +2250,22 @@ Global {B3D7760B-8BEA-2EF6-F1D4-9F9020E166D6}.Release-DLL|Win32.Build.0 = Release|Win32 {B3D7760B-8BEA-2EF6-F1D4-9F9020E166D6}.Release-DLL|x64.ActiveCfg = Release|x64 {B3D7760B-8BEA-2EF6-F1D4-9F9020E166D6}.Release-DLL|x64.Build.0 = Release|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug|Win32.ActiveCfg = Debug|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug|x64.ActiveCfg = Debug|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release|Win32.ActiveCfg = Release|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release|x64.ActiveCfg = Release|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug|Win32.Build.0 = Debug|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug|x64.Build.0 = Debug|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release|Win32.Build.0 = Release|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release|x64.Build.0 = Release|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Debug-DLL|x64.Build.0 = Debug|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release-DLL|Win32.Build.0 = Release|Win32 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release-DLL|x64.ActiveCfg = Release|x64 + {D8EDE51A-CBB2-0362-D59B-09AA92A94F45}.Release-DLL|x64.Build.0 = Release|x64 {AD06B5CD-8D5C-A365-C46B-3CF32237A4F7}.Debug|Win32.ActiveCfg = Debug|Win32 {AD06B5CD-8D5C-A365-C46B-3CF32237A4F7}.Debug|x64.ActiveCfg = Debug|x64 {AD06B5CD-8D5C-A365-C46B-3CF32237A4F7}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj index c4f9c55308..44c21ddeb3 100644 --- a/vsprojects/vcxproj/gpr/gpr.vcxproj +++ b/vsprojects/vcxproj/gpr/gpr.vcxproj @@ -193,6 +193,7 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\env.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\mpscq.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.h" /> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\spinlock.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\stack_lockfree.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string_windows.h" /> diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters index 77a1ba64d6..a5924a624a 100644 --- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters +++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters @@ -269,6 +269,9 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.h"> <Filter>src\core\lib\support</Filter> </ClInclude> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\spinlock.h"> + <Filter>src\core\lib\support</Filter> + </ClInclude> <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\stack_lockfree.h"> <Filter>src\core\lib\support</Filter> </ClInclude> diff --git a/vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj b/vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj new file mode 100644 index 0000000000..a2f3d2ea52 --- /dev/null +++ b/vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj @@ -0,0 +1,193 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" /> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D8EDE51A-CBB2-0362-D59B-09AA92A94F45}</ProjectGuid> + <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected> + <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration"> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration"> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration"> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration"> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)\..\vsprojects\global.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)'=='Debug'"> + <TargetName>gpr_spinlock_test</TargetName> + <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib> + <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib> + <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl> + <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'"> + <TargetName>gpr_spinlock_test</TargetName> + <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib> + <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib> + <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl> + <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + + <ItemGroup> + <ClCompile Include="$(SolutionDir)\..\test\core\support\spinlock_test.c"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj"> + <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project> + </ProjectReference> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" /> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" /> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" /> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" /> + </ImportGroup> + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> + </PropertyGroup> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" /> + </Target> +</Project> + diff --git a/vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj.filters b/vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj.filters new file mode 100644 index 0000000000..3e9d06185f --- /dev/null +++ b/vsprojects/vcxproj/test/gpr_spinlock_test/gpr_spinlock_test.vcxproj.filters @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="$(SolutionDir)\..\test\core\support\spinlock_test.c"> + <Filter>test\core\support</Filter> + </ClCompile> + </ItemGroup> + + <ItemGroup> + <Filter Include="test"> + <UniqueIdentifier>{f79012a0-59dc-e99f-b27d-78bbccc328a1}</UniqueIdentifier> + </Filter> + <Filter Include="test\core"> + <UniqueIdentifier>{3aa9f8c4-b90f-3b8b-e967-900dbe335130}</UniqueIdentifier> + </Filter> + <Filter Include="test\core\support"> + <UniqueIdentifier>{51bef72c-ce73-a264-d69b-3711b6599f8c}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project> + |