renguangxuan 54bd8d1735 Add runtime_core ut to GGW
Issue: IAYWOR

Signed-off-by: renguangxuan <renguangxuan@huawei.com>
Change-Id: If037e50de44100cbad99bef21bc6047919849f7c
2024-10-22 15:00:32 +08:00

196 lines
4.9 KiB
C++

/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* 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 <pthread.h>
#include "gtest/gtest.h"
#include "os/mutex.h"
#include "os/thread.h"
namespace panda::test {
class MutexTest : public testing::Test {};
constexpr size_t N = 10;
constexpr size_t WRITE_LOCK_SLEEP_TIME = 50;
constexpr size_t READ_LOCK_SLEEP_TIME = 1000;
struct ThreadRWLockArgs {
os::memory::RWLock *rwlock;
size_t *index;
};
struct ThreadMutexArgs {
os::memory::Mutex *lock;
size_t *index;
};
static void *TestThread1(void *input)
{
ASSERT(input != nullptr);
ThreadRWLockArgs *arg = reinterpret_cast<ThreadRWLockArgs *>(input);
arg->rwlock->WriteLock();
(*(arg->index))++;
os::thread::NativeSleep(WRITE_LOCK_SLEEP_TIME);
arg->rwlock->Unlock();
return nullptr;
}
static void *TestThread2(void *input)
{
ASSERT(input != nullptr);
ThreadRWLockArgs *arg = reinterpret_cast<ThreadRWLockArgs *>(input);
arg->rwlock->ReadLock();
os::thread::NativeSleep(READ_LOCK_SLEEP_TIME);
arg->rwlock->Unlock();
return nullptr;
}
static void *TestThread3(void *input)
{
ASSERT(input != nullptr);
ThreadRWLockArgs *arg = reinterpret_cast<ThreadRWLockArgs *>(input);
bool res = arg->rwlock->TryReadLock();
if (res) {
(*(arg->index))++;
arg->rwlock->Unlock();
}
res = arg->rwlock->TryWriteLock();
if (res) {
(*(arg->index))++;
arg->rwlock->Unlock();
}
return nullptr;
}
static void *TestThread4(void *input)
{
ASSERT(input != nullptr);
ThreadMutexArgs *arg = reinterpret_cast<ThreadMutexArgs *>(input);
bool res = arg->lock->TryLockWithSpinning();
if (res) {
(*(arg->index))++;
arg->lock->Unlock();
}
return nullptr;
}
static void *TestThread5(void *input)
{
ASSERT(input != nullptr);
ThreadRWLockArgs *arg = reinterpret_cast<ThreadRWLockArgs *>(input);
arg->rwlock->WriteLock();
arg->rwlock->Unlock();
return nullptr;
}
HWTEST_F(MutexTest, RWLockTest, testing::ext::TestSize.Level0)
{
size_t res = 0;
auto *rwlock = new os::memory::RWLock();
ThreadRWLockArgs arg = {rwlock, &res};
pthread_t t[N + N];
for (size_t i = 0; i < N; i++) {
pthread_create(&t[i], nullptr, TestThread1, reinterpret_cast<void *>(&arg));
}
for (size_t i = 0; i < N; i++) {
pthread_create(&t[i + N], nullptr, TestThread2, reinterpret_cast<void *>(&arg));
}
for (size_t i = 0; i < N; i++) {
pthread_join(t[i], nullptr);
pthread_join(t[i + N], nullptr);
}
rwlock->WriteLock();
rwlock->Unlock();
ASSERT_EQ(res, N);
delete rwlock;
}
HWTEST_F(MutexTest, TryLockTest, testing::ext::TestSize.Level0)
{
auto *rwlock = new os::memory::RWLock();
size_t res = 0;
ThreadRWLockArgs arg = {rwlock, &res};
pthread_t t1;
rwlock->WriteLock();
pthread_create(&t1, nullptr, TestThread3, reinterpret_cast<void *>(&arg));
pthread_join(t1, nullptr);
rwlock->Unlock();
ASSERT_EQ(res, 0U);
pthread_t t2;
rwlock->ReadLock();
res = 0;
pthread_create(&t2, nullptr, TestThread3, reinterpret_cast<void *>(&arg));
pthread_join(t2, nullptr);
rwlock->Unlock();
ASSERT_EQ(res, 1U);
pthread_t t3;
res = 0;
pthread_create(&t3, nullptr, TestThread3, reinterpret_cast<void *>(&arg));
pthread_join(t3, nullptr);
ASSERT_EQ(res, 2U);
delete rwlock;
}
HWTEST_F(MutexTest, TryLockWithSpiningTest, testing::ext::TestSize.Level0)
{
auto *lock = new os::memory::Mutex();
bool res = lock->TryLockWithSpinning();
ASSERT_TRUE(res);
size_t index = 0;
ThreadMutexArgs arg = {lock, &index};
pthread_t t;
pthread_create(&t, nullptr, TestThread4, reinterpret_cast<void *>(&arg));
pthread_join(t, nullptr);
ASSERT_EQ(index, 0U);
if (res) {
lock->Unlock();
}
delete lock;
}
HWTEST_F(MutexTest, LockForOtherTest, testing::ext::TestSize.Level0)
{
auto *rwlock = new os::memory::RWLock();
ThreadRWLockArgs arg = {rwlock, nullptr};
rwlock->WriteLock();
auto *lock = new os::memory::Mutex();
pthread_t t;
pthread_create(&t, nullptr, TestThread5, reinterpret_cast<void *>(&arg));
lock->LockForOther(t);
bool res = lock->TryLock();
if (res) {
lock->Unlock();
}
lock->UnlockForOther(t);
rwlock->Unlock();
ASSERT_FALSE(res);
pthread_join(t, nullptr);
delete lock;
}
} // namespace panda