blob: c281ae02422ff8a9a0892e9b795c9503741ebfe6 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/allocator/partition_allocator/spin_lock.h"
#include <memory>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
static constexpr size_t kBufferSize = 16;
static subtle::SpinLock g_lock;
static void FillBuffer(volatile char* buffer, char fill_pattern) {
for (size_t i = 0; i < kBufferSize; ++i)
buffer[i] = fill_pattern;
}
static void ChangeAndCheckBuffer(volatile char* buffer) {
FillBuffer(buffer, '\0');
int total = 0;
for (size_t i = 0; i < kBufferSize; ++i)
total += buffer[i];
EXPECT_EQ(0, total);
// This will mess with the other thread's calculation if we accidentally get
// concurrency.
FillBuffer(buffer, '!');
}
static void ThreadMain(volatile char* buffer) {
for (int i = 0; i < 500000; ++i) {
subtle::SpinLock::Guard guard(g_lock);
ChangeAndCheckBuffer(buffer);
}
}
TEST(SpinLockTest, Torture) {
char shared_buffer[kBufferSize];
Thread thread1("thread1");
Thread thread2("thread2");
thread1.StartAndWaitForTesting();
thread2.StartAndWaitForTesting();
thread1.task_runner()->PostTask(
FROM_HERE,
BindOnce(&ThreadMain, Unretained(static_cast<char*>(shared_buffer))));
thread2.task_runner()->PostTask(
FROM_HERE,
BindOnce(&ThreadMain, Unretained(static_cast<char*>(shared_buffer))));
}
} // namespace base