blob: c581c850e4ef15a87bee6246bae7b099e7ade04c [file] [log] [blame]
// Copyright 2016 The Fuchsia 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 <chrono>
#include <thread>
#include "platform_futex.h"
#include "gtest/gtest.h"
static inline uint64_t timeout_from_ms(uint64_t timeout_ms) { return timeout_ms * 1000000ull; }
class TestPlatformFutex {
public:
static void Test()
{
value = 10;
magma::PlatformFutex::WaitResult result;
EXPECT_TRUE(magma::PlatformFutex::WaitForever(&value, value + 1, &result));
EXPECT_EQ(result, magma::PlatformFutex::RETRY);
auto start = std::chrono::high_resolution_clock::now();
EXPECT_TRUE(
magma::PlatformFutex::Wait(&value, value, timeout_from_ms(timeout_ms), &result));
EXPECT_EQ(result, magma::PlatformFutex::TIMED_OUT);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
EXPECT_GT(elapsed.count(), (uint32_t)timeout_ms);
uint32_t starting_value = value;
std::thread thread([]() {
magma::PlatformFutex::WaitResult result;
EXPECT_TRUE(magma::PlatformFutex::WaitForever(&value, value, &result));
EXPECT_EQ(result, magma::PlatformFutex::AWOKE);
value++;
});
constexpr uint32_t max_retry = 100;
uint32_t retry = 0;
for (; retry < max_retry; retry++) {
magma::PlatformFutex::Wake(&value, 1);
if (value != starting_value) {
thread.join();
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
EXPECT_LT(retry, max_retry);
}
static constexpr uint32_t timeout_ms = 100;
static uint32_t value;
};
uint32_t TestPlatformFutex::value;
TEST(PlatformFutex, Test) { TestPlatformFutex::Test(); }