blob: 5b3be9bee880d2bfdb0c19a4b1ab8ce0d1fba66c [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 "starboard/nplb/thread_helpers.h"
#include "starboard/condition_variable.h"
#include "starboard/mutex.h"
#include "starboard/thread.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace starboard {
namespace nplb {
void DoNotYield() {
// Nope.
}
// Adds 1 to the input.
void* AddOneEntryPoint(void* context) {
return ToVoid(FromVoid(context) + 1);
}
void* WaiterEntryPoint(void* context) {
WaiterContext* real_context = static_cast<WaiterContext*>(context);
real_context->Wait();
return NULL;
}
void* TakeThenSignalEntryPoint(void* context) {
TakeThenSignalContext* test_context =
static_cast<TakeThenSignalContext*>(context);
// Don't signal the condition variable until we are asked.
test_context->do_signal.Take();
if (test_context->delay_after_signal > 0) {
SbThreadSleep(test_context->delay_after_signal);
}
// Signal the condition variable.
EXPECT_TRUE(SbMutexIsSuccess(SbMutexAcquire(&test_context->mutex)));
EXPECT_TRUE(SbConditionVariableSignal(&test_context->condition));
EXPECT_TRUE(SbMutexRelease(&test_context->mutex));
return NULL;
}
WaiterContext::WaiterContext() : unreturned_waiters(0) {
EXPECT_TRUE(SbMutexCreate(&mutex));
EXPECT_TRUE(SbConditionVariableCreate(&condition, &mutex));
EXPECT_TRUE(SbConditionVariableCreate(&return_condition, &mutex));
}
WaiterContext::~WaiterContext() {
EXPECT_TRUE(SbConditionVariableDestroy(&return_condition));
EXPECT_TRUE(SbConditionVariableDestroy(&condition));
EXPECT_TRUE(SbMutexDestroy(&mutex));
}
void WaiterContext::Wait() {
EXPECT_TRUE(SbMutexIsSuccess(SbMutexAcquire(&mutex)));
++unreturned_waiters;
EXPECT_TRUE(SbConditionVariableSignal(&return_condition));
EXPECT_TRUE(SbConditionVariableIsSignaled(
SbConditionVariableWait(&condition, &mutex)));
EXPECT_TRUE(SbMutexRelease(&mutex));
}
void WaiterContext::WaitForReturnSignal() {
EXPECT_TRUE(SbMutexIsSuccess(SbMutexAcquire(&mutex)));
while (unreturned_waiters == 0) {
EXPECT_TRUE(SbConditionVariableIsSignaled(
SbConditionVariableWait(&return_condition, &mutex)));
}
--unreturned_waiters;
EXPECT_TRUE(SbMutexRelease(&mutex));
}
} // namespace nplb
} // namespace starboard