diff options
Diffstat (limited to 'test/syscalls/linux/concurrency.cc')
-rw-r--r-- | test/syscalls/linux/concurrency.cc | 130 |
1 files changed, 0 insertions, 130 deletions
diff --git a/test/syscalls/linux/concurrency.cc b/test/syscalls/linux/concurrency.cc deleted file mode 100644 index f2daf49ee..000000000 --- a/test/syscalls/linux/concurrency.cc +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2018 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <signal.h> - -#include <atomic> - -#include "gtest/gtest.h" -#include "absl/strings/string_view.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" -#include "benchmark/benchmark.h" -#include "test/util/platform_util.h" -#include "test/util/test_util.h" -#include "test/util/thread_util.h" - -namespace gvisor { -namespace testing { -namespace { - -// Test that a thread that never yields to the OS does not prevent other threads -// from running. -TEST(ConcurrencyTest, SingleProcessMultithreaded) { - std::atomic<int> a(0); - - ScopedThread t([&a]() { - while (!a.load()) { - } - }); - - absl::SleepFor(absl::Seconds(1)); - - // We are still able to execute code in this thread. The other hasn't - // permanently hung execution in both threads. - a.store(1); -} - -// Test that multiple threads in this process continue to execute in parallel, -// even if an unrelated second process is spawned. Regression test for -// b/32119508. -TEST(ConcurrencyTest, MultiProcessMultithreaded) { - // In PID 1, start TIDs 1 and 2, and put both to sleep. - // - // Start PID 3, which spins for 5 seconds, then exits. - // - // TIDs 1 and 2 wake and attempt to Activate, which cannot occur until PID 3 - // exits. - // - // Both TIDs 1 and 2 should be woken. If they are not both woken, the test - // hangs. - // - // This is all fundamentally racy. If we are failing to wake all threads, the - // expectation is that this test becomes flaky, rather than consistently - // failing. - // - // If additional background threads fail to block, we may never schedule the - // child, at which point this test effectively becomes - // MultiProcessConcurrency. That's not expected to occur. - - std::atomic<int> a(0); - ScopedThread t([&a]() { - // Block so that PID 3 can execute and we can wait on its exit. - absl::SleepFor(absl::Seconds(1)); - while (!a.load()) { - } - }); - - pid_t child_pid = fork(); - if (child_pid == 0) { - // Busy wait without making any blocking syscalls. - auto end = absl::Now() + absl::Seconds(5); - while (absl::Now() < end) { - } - _exit(0); - } - ASSERT_THAT(child_pid, SyscallSucceeds()); - - absl::SleepFor(absl::Seconds(1)); - - // If only TID 1 is woken, thread.Join will hang. - // If only TID 2 is woken, both will hang. - a.store(1); - t.Join(); - - int status = 0; - EXPECT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds()); - EXPECT_TRUE(WIFEXITED(status)); - EXPECT_EQ(WEXITSTATUS(status), 0); -} - -// Test that multiple processes can execute concurrently, even if one process -// never yields. -TEST(ConcurrencyTest, MultiProcessConcurrency) { - SKIP_IF(PlatformSupportMultiProcess() == PlatformSupport::NotSupported); - - pid_t child_pid = fork(); - if (child_pid == 0) { - while (true) { - int x = 0; - benchmark::DoNotOptimize(x); // Don't optimize this loop away. - } - } - ASSERT_THAT(child_pid, SyscallSucceeds()); - - absl::SleepFor(absl::Seconds(5)); - - // We are still able to execute code in this process. The other hasn't - // permanently hung execution in both processes. - ASSERT_THAT(kill(child_pid, SIGKILL), SyscallSucceeds()); - int status = 0; - - ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds()); - ASSERT_TRUE(WIFSIGNALED(status)); - ASSERT_EQ(WTERMSIG(status), SIGKILL); -} - -} // namespace -} // namespace testing -} // namespace gvisor |