patch 4.0
This commit is contained in:
@ -17,35 +17,37 @@
|
||||
#include "lib/restore/ob_storage.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
class TestObDynamicThreadPool : public ::testing::Test {
|
||||
class TestObDynamicThreadPool: public ::testing::Test
|
||||
{
|
||||
public:
|
||||
TestObDynamicThreadPool()
|
||||
{}
|
||||
virtual ~TestObDynamicThreadPool()
|
||||
{}
|
||||
TestObDynamicThreadPool() {}
|
||||
virtual ~TestObDynamicThreadPool(){}
|
||||
virtual void SetUp()
|
||||
{}
|
||||
{
|
||||
}
|
||||
virtual void TearDown()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{}
|
||||
|
||||
{
|
||||
}
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(TestObDynamicThreadPool);
|
||||
|
||||
protected:
|
||||
// function members
|
||||
protected:
|
||||
};
|
||||
|
||||
class SimpleTask : public ObDynamicThreadTask {
|
||||
class SimpleTask: public ObDynamicThreadTask
|
||||
{
|
||||
public:
|
||||
int process(const bool& is_stop)
|
||||
int process(const bool &is_stop)
|
||||
{
|
||||
UNUSED(is_stop);
|
||||
ATOMIC_INC(&count_);
|
||||
@ -56,6 +58,7 @@ public:
|
||||
|
||||
int64_t SimpleTask::count_ = 0;
|
||||
|
||||
|
||||
TEST_F(TestObDynamicThreadPool, normal)
|
||||
{
|
||||
ObDynamicThreadPool pool;
|
||||
@ -95,13 +98,15 @@ TEST_F(TestObDynamicThreadPool, test_change_thread_num)
|
||||
pool.stop();
|
||||
pool.destroy();
|
||||
ASSERT_EQ(task_count, SimpleTask::count_);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
mallopt(M_ARENA_MAX, 1); // disable malloc multiple arena pool
|
||||
OB_LOGGER.set_log_level("INFO");
|
||||
OB_LOGGER.set_file_name("test_dynamic_thread_pool.log", true);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
|
||||
270
deps/oblib/unittest/lib/thread/test_protected_stack_allocator.cpp
vendored
Normal file
270
deps/oblib/unittest/lib/thread/test_protected_stack_allocator.cpp
vendored
Normal file
@ -0,0 +1,270 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "lib/ob_errno.h"
|
||||
#include "lib/oblog/ob_log.h"
|
||||
#include "lib/time/ob_time_utility.h"
|
||||
#include "lib/resource/ob_resource_mgr.h"
|
||||
#include "lib/coro/testing.h"
|
||||
#define private public
|
||||
#include "lib/thread/protected_stack_allocator.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace oceanbase::lib;
|
||||
using namespace oceanbase::common;
|
||||
|
||||
static constexpr int64_t DEFAULT_STACK_SIZE = (1 << 20) * 2; // 2M
|
||||
static constexpr int64_t MAX_STACK_SIZE = (1 << 20) * 16; // 16M
|
||||
using CPSA = ProtectedStackAllocator;
|
||||
#define PAGE_SIZE CPSA::page_size()
|
||||
#define ALLOC(size) g_stack_allocer.alloc(1, size)
|
||||
#define DEALLOC(ptr) g_stack_allocer.dealloc(ptr)
|
||||
|
||||
|
||||
//struct MhuGuard
|
||||
//{
|
||||
// MhuGuard(CPSA::IMemHoldUpdater &mhu)
|
||||
// {
|
||||
// orig_mhu_ = CPSA::ref_mhu_;
|
||||
// CPSA::ref_mhu_ = &mhu;
|
||||
// }
|
||||
// ~MhuGuard() { CPSA::ref_mhu_ = orig_mhu_; }
|
||||
// CPSA::IMemHoldUpdater *orig_mhu_;
|
||||
//};
|
||||
|
||||
class DoNothingMhu //: public CPSA::IMemHoldUpdater
|
||||
{
|
||||
public:
|
||||
virtual int update_hold(const uint64_t tenant_id ,const ssize_t size, bool &updated)
|
||||
{
|
||||
UNUSED(tenant_id);
|
||||
UNUSED(size);
|
||||
updated = true;
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
class TestHoldMhu //: public CPSA::IMemHoldUpdater
|
||||
{
|
||||
public:
|
||||
TestHoldMhu()
|
||||
: hold_(0), limit_(0)
|
||||
{}
|
||||
void reset()
|
||||
{
|
||||
hold_ = 0;
|
||||
limit_ = 0;
|
||||
}
|
||||
virtual int update_hold(const uint64_t tenant_id, const ssize_t size, bool &updated)
|
||||
{
|
||||
UNUSED(tenant_id);
|
||||
updated = false;
|
||||
if (hold_ + size <= limit_) {
|
||||
hold_ += size;
|
||||
updated = true;
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
int64_t hold_;
|
||||
int64_t limit_;
|
||||
|
||||
};
|
||||
|
||||
DoNothingMhu my_mhu;
|
||||
|
||||
void test_fixed_size(const int64_t size)
|
||||
{
|
||||
cout << "size: " << size << endl;
|
||||
//MhuGuard guard(my_mhu);
|
||||
void *buf = ALLOC(size);
|
||||
ASSERT_NE(buf, nullptr);
|
||||
memset(buf, '1', size);
|
||||
char *str = new char[size];
|
||||
memset(str, '1', size);
|
||||
int cmp = memcmp(buf, str, size);
|
||||
EXPECT_EQ(cmp, 0);
|
||||
DEALLOC(buf);
|
||||
delete []str;
|
||||
}
|
||||
|
||||
TEST(TestCPSA, Main)
|
||||
{
|
||||
auto size = DEFAULT_STACK_SIZE;
|
||||
test_fixed_size(size);
|
||||
size = DEFAULT_STACK_SIZE - (4 << 10);
|
||||
test_fixed_size(size);
|
||||
size = DEFAULT_STACK_SIZE + (4 << 10);
|
||||
test_fixed_size(size);
|
||||
size = MAX_STACK_SIZE;
|
||||
test_fixed_size(size);
|
||||
size = PAGE_SIZE;
|
||||
test_fixed_size(size);
|
||||
}
|
||||
|
||||
TEST(TestCPSA, EXCEPTION)
|
||||
{
|
||||
//MhuGuard guard(my_mhu);
|
||||
// not page_size align is allowed
|
||||
ASSERT_NE(nullptr, ALLOC(DEFAULT_STACK_SIZE - 1));
|
||||
ASSERT_EQ(nullptr, ALLOC(-1));
|
||||
ASSERT_EQ(nullptr, ALLOC(0));
|
||||
ASSERT_EQ(nullptr, ALLOC(INT64_MAX));
|
||||
|
||||
void *buf = nullptr;
|
||||
ASSERT_NE(nullptr, buf = ALLOC(-UINT64_MAX + DEFAULT_STACK_SIZE - 1));
|
||||
DEALLOC(buf);
|
||||
|
||||
// nullptr ptr will be ignored
|
||||
DEALLOC(nullptr);
|
||||
}
|
||||
|
||||
TEST(TestCPSA, DISABLED_HOLD_MOCK)
|
||||
{
|
||||
TestHoldMhu mhu;
|
||||
//MhuGuard guard(mhu);
|
||||
|
||||
mhu.limit_ = 1 << 20;
|
||||
ASSERT_EQ(nullptr, ALLOC(DEFAULT_STACK_SIZE));
|
||||
|
||||
mhu.reset();
|
||||
mhu.limit_ = 1 << 30;
|
||||
mhu.hold_ = (1 << 30) - DEFAULT_STACK_SIZE;
|
||||
ASSERT_EQ(nullptr, ALLOC(DEFAULT_STACK_SIZE));
|
||||
|
||||
mhu.reset();
|
||||
mhu.limit_ = 1 << 30;
|
||||
mhu.hold_ = (1 << 30) - DEFAULT_STACK_SIZE - PAGE_SIZE;
|
||||
void *buf = NULL;
|
||||
ASSERT_NE(nullptr, buf = ALLOC(DEFAULT_STACK_SIZE));
|
||||
ASSERT_EQ(nullptr, ALLOC(DEFAULT_STACK_SIZE));
|
||||
DEALLOC(buf);
|
||||
|
||||
mhu.reset();
|
||||
int64_t size = 8 << 20;
|
||||
int64_t N = 100;
|
||||
mhu.limit_ = (size + PAGE_SIZE) * 100;
|
||||
vector<void *> bufs;
|
||||
for (int64_t i = 0; i < N; ++i) {
|
||||
void *buf = ALLOC(size);
|
||||
ASSERT_NE(nullptr, buf);
|
||||
memset(buf, '1', size);
|
||||
bufs.push_back(buf);
|
||||
}
|
||||
ASSERT_EQ(nullptr, ALLOC(size));
|
||||
for (int64_t i = 0; i < N; ++i) {
|
||||
DEALLOC(bufs[i]);
|
||||
}
|
||||
for (int64_t i = 0; i < N; ++i) {
|
||||
void *buf = ALLOC(size);
|
||||
ASSERT_NE(nullptr, buf);
|
||||
memset(buf, '1', size);
|
||||
DEALLOC(buf);
|
||||
}
|
||||
}
|
||||
|
||||
using LimitFunc = std::function<void(ObTenantResourceMgrHandle &, const uint64_t)>;
|
||||
|
||||
void test_hold(LimitFunc func)
|
||||
{
|
||||
const uint64_t tenant_id = 100;
|
||||
|
||||
int64_t size = 8 << 20;
|
||||
const uint64_t limit = (size + PAGE_SIZE * 2) * 100;
|
||||
|
||||
int ret = OB_SUCCESS;
|
||||
ObTenantResourceMgrHandle resource_handle;
|
||||
if (OB_FAIL(ObResourceMgr::get_instance().get_tenant_resource_mgr(
|
||||
tenant_id, resource_handle))) {
|
||||
LIB_LOG(ERROR, "get_tenant_resource_mgr failed", K(ret), K(tenant_id));
|
||||
return;
|
||||
} else {
|
||||
func(resource_handle, limit);
|
||||
}
|
||||
int64_t N = 100;
|
||||
vector<void *> bufs;
|
||||
for (int64_t i = 0; i < N; ++i) {
|
||||
void *buf = g_stack_allocer.alloc(tenant_id, size);
|
||||
ASSERT_NE(nullptr, buf);
|
||||
bufs.push_back(buf);
|
||||
}
|
||||
//ASSERT_EQ(nullptr, CPSA::alloc(tenant_id, size));
|
||||
for (int64_t i = 0; i < N; ++i) {
|
||||
DEALLOC(bufs[i]);
|
||||
}
|
||||
for (int64_t i = 0; i < N; ++i) {
|
||||
void *buf = g_stack_allocer.alloc(tenant_id, size);
|
||||
ASSERT_NE(nullptr, buf);
|
||||
DEALLOC(buf);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TestCPSA, HOLD)
|
||||
{
|
||||
test_hold(
|
||||
[](ObTenantResourceMgrHandle &resource_handle, const uint64_t limit)
|
||||
{
|
||||
resource_handle.get_memory_mgr()->set_limit(limit);
|
||||
}
|
||||
);
|
||||
test_hold(
|
||||
[](ObTenantResourceMgrHandle &resource_handle, const uint64_t limit)
|
||||
{
|
||||
resource_handle.get_memory_mgr()->set_ctx_limit(ObCtxIds::CO_STACK, limit);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
TEST(TestCPSA, bench)
|
||||
{
|
||||
auto begin_ts = ObTimeUtility::current_time();
|
||||
const auto CNT = 1000L * 10 ;
|
||||
for (auto i = 0; i < CNT; ++i) {
|
||||
auto buf = ALLOC(DEFAULT_STACK_SIZE);
|
||||
{
|
||||
int64_t interval = 512 * (1 << 10);
|
||||
int64_t access_len = 1 << 10;
|
||||
for (int64_t j = 0; j < DEFAULT_STACK_SIZE; j+= interval) {
|
||||
memset((char *)buf + j, 'a', std::min(access_len, DEFAULT_STACK_SIZE - j + 1));
|
||||
}
|
||||
}
|
||||
if (nullptr == buf) {
|
||||
cout << i << endl;
|
||||
break;
|
||||
} else {
|
||||
DEALLOC(buf);
|
||||
}
|
||||
}
|
||||
auto end_ts = ObTimeUtility::current_time();
|
||||
cout << "alloc bench: " << CNT * 1000 / (end_ts - begin_ts) << "Kps" << endl;
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(TestCPSA, ACCESS_GUARD)
|
||||
{
|
||||
CPSA ca;
|
||||
void *buf = ca.alloc(DEFAULT_STACK_SIZE);
|
||||
ASSERT_NE(nullptr, buf);
|
||||
char *p = (char *) buf;
|
||||
cout << p[0] << endl;
|
||||
cout << p[-PAGE_SIZE - 1] << endl;
|
||||
cout << p[-1] << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
OB_LOGGER.set_log_level(3);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@ -19,12 +19,10 @@ using namespace oceanbase::common;
|
||||
TEST(DISABLED_TestSimpleThreadPool, Basic)
|
||||
{
|
||||
class : public ObSimpleThreadPool {
|
||||
void handle(void* task)
|
||||
{
|
||||
void handle(void *task) {
|
||||
UNUSED(task);
|
||||
ATOMIC_INC(&handle_cnt_);
|
||||
}
|
||||
|
||||
public:
|
||||
int handle_cnt_ = 0;
|
||||
} pool;
|
||||
@ -37,11 +35,11 @@ TEST(DISABLED_TestSimpleThreadPool, Basic)
|
||||
// When routine without coro push items into this pool, there may be
|
||||
// at most 100ms(default timeout) before a item to be processing.
|
||||
//
|
||||
// Update: co_futex has fixed problem of thread waking up co-routine
|
||||
// Update: ob_futex has fixed problem of thread waking up co-routine
|
||||
TIME_LESS(10000, [&pool] {
|
||||
pool.handle_cnt_ = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, pool.init(1, 10));
|
||||
this_routine::usleep(1000); // wait for handler waiting for queue
|
||||
::usleep(1000); // wait for handler waiting for queue
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
@ -49,7 +47,7 @@ TEST(DISABLED_TestSimpleThreadPool, Basic)
|
||||
if (pool.handle_cnt_ == 3) {
|
||||
break;
|
||||
}
|
||||
this_routine::usleep(1000);
|
||||
::usleep(1000);
|
||||
}
|
||||
ASSERT_EQ(3, pool.handle_cnt_);
|
||||
});
|
||||
@ -58,29 +56,27 @@ TEST(DISABLED_TestSimpleThreadPool, Basic)
|
||||
// When routine with coro push items into this pool, it would be
|
||||
// processed ASAP.
|
||||
TIME_LESS(10000, [&pool] {
|
||||
cotesting::FlexPool(
|
||||
[&pool] {
|
||||
pool.handle_cnt_ = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, pool.init(1, 10));
|
||||
this_routine::usleep(1000); // wait for handler waiting for queue
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (pool.handle_cnt_ == 3) {
|
||||
break;
|
||||
}
|
||||
this_routine::usleep(1000);
|
||||
}
|
||||
ASSERT_EQ(3, pool.handle_cnt_);
|
||||
},
|
||||
1)
|
||||
.start();
|
||||
cotesting::FlexPool([&pool] {
|
||||
pool.handle_cnt_ = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, pool.init(1, 10));
|
||||
::usleep(1000); // wait for handler waiting for queue
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
ASSERT_EQ(OB_SUCCESS, pool.push((void*)1));
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (pool.handle_cnt_ == 3) {
|
||||
break;
|
||||
}
|
||||
::usleep(1000);
|
||||
}
|
||||
ASSERT_EQ(3, pool.handle_cnt_);
|
||||
}, 1).start();
|
||||
});
|
||||
pool.destroy();
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
173
deps/oblib/unittest/lib/thread/test_tg_mgr.cpp
vendored
173
deps/oblib/unittest/lib/thread/test_tg_mgr.cpp
vendored
@ -17,16 +17,16 @@ using namespace oceanbase;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::lib;
|
||||
|
||||
class TestTimerTask : public ObTimerTask {
|
||||
class TestTimerTask : public ObTimerTask
|
||||
{
|
||||
public:
|
||||
TestTimerTask() : running_(false), task_run_count_(0)
|
||||
{}
|
||||
TestTimerTask() : running_(false), task_run_count_(0) {}
|
||||
|
||||
void runTimerTask()
|
||||
{
|
||||
running_ = true;
|
||||
++task_run_count_;
|
||||
this_routine::usleep(50000);
|
||||
::usleep(50000);
|
||||
running_ = false;
|
||||
}
|
||||
|
||||
@ -41,38 +41,39 @@ TEST(TG, timer)
|
||||
// start
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SCHEDULE(tg_id, task, 0, true));
|
||||
this_routine::usleep(40000);
|
||||
::usleep(40000);
|
||||
ASSERT_TRUE(task.running_);
|
||||
this_routine::usleep(60000);
|
||||
::usleep(60000);
|
||||
ASSERT_EQ(1, task.task_run_count_);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
|
||||
// restart
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SCHEDULE(tg_id, task, 0, true));
|
||||
this_routine::usleep(40000);
|
||||
::usleep(40000);
|
||||
ASSERT_TRUE(task.running_);
|
||||
this_routine::usleep(60000);
|
||||
::usleep(60000);
|
||||
ASSERT_EQ(2, task.task_run_count_);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
|
||||
ASSERT_TRUE(TG_EXIST(tg_id));
|
||||
TG_DESTROY(tg_id);
|
||||
ASSERT_FALSE(TG_EXIST(tg_id));
|
||||
}
|
||||
|
||||
class Handler : public TGTaskHandler {
|
||||
class Handler : public TGTaskHandler
|
||||
{
|
||||
public:
|
||||
void handle(void* task) override
|
||||
void handle(void *task) override
|
||||
{
|
||||
UNUSED(task);
|
||||
++handle_count_;
|
||||
this_routine::usleep(50000);
|
||||
::usleep(50000);
|
||||
}
|
||||
|
||||
int64_t handle_count_ = 0;
|
||||
int64_t handle_count_=0;
|
||||
};
|
||||
|
||||
TEST(TG, queue_thread)
|
||||
@ -83,18 +84,18 @@ TEST(TG, queue_thread)
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SET_HANDLER(tg_id, handler));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_PUSH_TASK(tg_id, &tg_id));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(1, handler.handle_count_);
|
||||
|
||||
// restart
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SET_HANDLER(tg_id, handler));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_PUSH_TASK(tg_id, &tg_id));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(2, handler.handle_count_);
|
||||
|
||||
ASSERT_TRUE(TG_EXIST(tg_id));
|
||||
@ -102,31 +103,22 @@ TEST(TG, queue_thread)
|
||||
ASSERT_FALSE(TG_EXIST(tg_id));
|
||||
}
|
||||
|
||||
class MyDTask : public common::IObDedupTask {
|
||||
class MyDTask: public common::IObDedupTask
|
||||
{
|
||||
public:
|
||||
MyDTask() : common::IObDedupTask(common::T_BLOOMFILTER)
|
||||
{}
|
||||
virtual int64_t hash() const
|
||||
{
|
||||
return reinterpret_cast<int64_t>(this);
|
||||
}
|
||||
virtual bool operator==(const IObDedupTask& task) const
|
||||
{
|
||||
return this == &task;
|
||||
}
|
||||
MyDTask() : common::IObDedupTask(common::T_BLOOMFILTER) {}
|
||||
virtual int64_t hash() const { return reinterpret_cast<int64_t>(this); }
|
||||
virtual bool operator ==(const IObDedupTask &task) const { return this == &task; }
|
||||
virtual int64_t get_deep_copy_size() const
|
||||
{
|
||||
return sizeof(*this);
|
||||
}
|
||||
virtual IObDedupTask* deep_copy(char* buffer, const int64_t buf_size) const
|
||||
virtual IObDedupTask *deep_copy(char *buffer, const int64_t buf_size) const
|
||||
{
|
||||
UNUSED(buf_size);
|
||||
return new (buffer) MyDTask;
|
||||
}
|
||||
virtual int64_t get_abs_expired_time() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual int64_t get_abs_expired_time() const { return 0; }
|
||||
virtual int process()
|
||||
{
|
||||
handle_count_++;
|
||||
@ -144,17 +136,17 @@ TEST(TG, dedup_queue)
|
||||
// start
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_PUSH_TASK(tg_id, task));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(1, task.handle_count_);
|
||||
|
||||
// restart
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_PUSH_TASK(tg_id, task));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(2, task.handle_count_);
|
||||
|
||||
ASSERT_TRUE(TG_EXIST(tg_id));
|
||||
@ -162,16 +154,18 @@ TEST(TG, dedup_queue)
|
||||
ASSERT_FALSE(TG_EXIST(tg_id));
|
||||
}
|
||||
|
||||
class MyRunnable : public TGRunnable {
|
||||
class MyRunnable : public TGRunnable
|
||||
{
|
||||
public:
|
||||
void run1() override
|
||||
{
|
||||
|
||||
run_count_++;
|
||||
while (!has_set_stop()) {
|
||||
this_routine::usleep(50000);
|
||||
::usleep(50000);
|
||||
}
|
||||
}
|
||||
int64_t run_count_ = 0;
|
||||
int64_t run_count_=0;
|
||||
};
|
||||
|
||||
TEST(TG, thread_pool)
|
||||
@ -181,17 +175,17 @@ TEST(TG, thread_pool)
|
||||
// start
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SET_RUNNABLE(tg_id, runnable));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(1, runnable.run_count_);
|
||||
|
||||
// restart
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SET_RUNNABLE(tg_id, runnable));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(2, runnable.run_count_);
|
||||
|
||||
ASSERT_TRUE(TG_EXIST(tg_id));
|
||||
@ -199,21 +193,51 @@ TEST(TG, thread_pool)
|
||||
ASSERT_FALSE(TG_EXIST(tg_id));
|
||||
}
|
||||
|
||||
class MyTask : public share::ObAsyncTask {
|
||||
TEST(TG, reentrant_thread_pool)
|
||||
{
|
||||
int tg_id = TGDefIDs::TEST7;
|
||||
MyRunnable runnable;
|
||||
// start
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SET_RUNNABLE(tg_id, runnable));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_REENTRANT_LOGICAL_START(tg_id));
|
||||
::usleep(50000);
|
||||
TG_REENTRANT_LOGICAL_STOP(tg_id);
|
||||
::usleep(50000);
|
||||
TG_REENTRANT_LOGICAL_WAIT(tg_id);
|
||||
ASSERT_EQ(1, runnable.run_count_);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_REENTRANT_LOGICAL_START(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(2, runnable.run_count_);
|
||||
// restart
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SET_RUNNABLE(tg_id, runnable));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(2, runnable.run_count_);
|
||||
|
||||
ASSERT_TRUE(TG_EXIST(tg_id));
|
||||
TG_DESTROY(tg_id);
|
||||
ASSERT_FALSE(TG_EXIST(tg_id));
|
||||
}
|
||||
class MyTask : public share::ObAsyncTask
|
||||
{
|
||||
public:
|
||||
virtual int process() override
|
||||
{
|
||||
handle_count_++;
|
||||
this_routine::usleep(50000);
|
||||
::usleep(50000);
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
virtual int64_t get_deep_copy_size() const override
|
||||
{
|
||||
return sizeof(*this);
|
||||
}
|
||||
{ return sizeof(*this); }
|
||||
|
||||
virtual ObAsyncTask* deep_copy(char* buf, const int64_t buf_size) const override
|
||||
virtual ObAsyncTask *deep_copy(char *buf, const int64_t buf_size) const override
|
||||
{
|
||||
UNUSED(buf_size);
|
||||
return new (buf) MyTask();
|
||||
@ -229,17 +253,17 @@ TEST(TG, async_task_queue)
|
||||
// start
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_PUSH_TASK(tg_id, task));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(1, task.handle_count_);
|
||||
|
||||
// restart
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_PUSH_TASK(tg_id, task));
|
||||
this_routine::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
::usleep(50000);
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
ASSERT_EQ(2, task.handle_count_);
|
||||
|
||||
ASSERT_TRUE(TG_EXIST(tg_id));
|
||||
@ -256,39 +280,38 @@ TEST(TG, timer_group)
|
||||
for (int i = 0; i < ARRAYSIZEOF(tasks); i++) {
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SCHEDULE(tg_id, i, tasks[i], 0, true));
|
||||
}
|
||||
this_routine::usleep(40000);
|
||||
::usleep(40000);
|
||||
for (int i = 0; i < ARRAYSIZEOF(tasks); i++) {
|
||||
ASSERT_TRUE(tasks[i].running_);
|
||||
}
|
||||
this_routine::usleep(60000);
|
||||
::usleep(60000);
|
||||
for (int i = 0; i < ARRAYSIZEOF(tasks); i++) {
|
||||
ASSERT_EQ(1, tasks[i].task_run_count_);
|
||||
}
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
|
||||
// restart
|
||||
ASSERT_EQ(OB_SUCCESS, TG_START(tg_id));
|
||||
for (int i = 0; i < ARRAYSIZEOF(tasks); i++) {
|
||||
ASSERT_EQ(OB_SUCCESS, TG_SCHEDULE(tg_id, i, tasks[i], 0, true));
|
||||
}
|
||||
this_routine::usleep(40000);
|
||||
::usleep(40000);
|
||||
for (int i = 0; i < ARRAYSIZEOF(tasks); i++) {
|
||||
ASSERT_TRUE(tasks[i].running_);
|
||||
}
|
||||
this_routine::usleep(60000);
|
||||
::usleep(60000);
|
||||
for (int i = 0; i < ARRAYSIZEOF(tasks); i++) {
|
||||
ASSERT_EQ(2, tasks[i].task_run_count_);
|
||||
}
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_STOP_R(tg_id));
|
||||
ASSERT_EQ(OB_SUCCESS, TG_WAIT_R(tg_id));
|
||||
|
||||
ASSERT_TRUE(TG_EXIST(tg_id));
|
||||
TG_DESTROY(tg_id);
|
||||
ASSERT_FALSE(TG_EXIST(tg_id));
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
|
||||
OB_LOGGER.set_log_level("INFO");
|
||||
|
||||
@ -14,27 +14,28 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace oceanbase::common;
|
||||
class TestObThreadLease : public ::testing::Test {
|
||||
class TestObThreadLease: public ::testing::Test
|
||||
{
|
||||
public:
|
||||
TestObThreadLease()
|
||||
{}
|
||||
virtual ~TestObThreadLease()
|
||||
{}
|
||||
TestObThreadLease() {}
|
||||
virtual ~TestObThreadLease(){}
|
||||
virtual void SetUp()
|
||||
{}
|
||||
{
|
||||
}
|
||||
virtual void TearDown()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{}
|
||||
|
||||
{
|
||||
}
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(TestObThreadLease);
|
||||
|
||||
protected:
|
||||
// function members
|
||||
protected:
|
||||
@ -50,7 +51,7 @@ TEST_F(TestObThreadLease, smoke_test)
|
||||
ASSERT_EQ(true, lease.revoke());
|
||||
ASSERT_EQ(ObThreadLease::IDLE, lease.value());
|
||||
|
||||
// Revoke directly, expect to return success
|
||||
// 直接revoke,期望返回成功
|
||||
ASSERT_EQ(true, lease.revoke());
|
||||
ASSERT_EQ(ObThreadLease::IDLE, lease.value());
|
||||
}
|
||||
@ -64,42 +65,43 @@ TEST_F(TestObThreadLease, simulate_multi_thread)
|
||||
ASSERT_EQ(true, lease.acquire());
|
||||
ASSERT_EQ(ObThreadLease::HANDLING, lease.value());
|
||||
|
||||
// Acquire again, expect to return failed, status change to READY
|
||||
// 再次acquire,期望失败,状态变更为READY
|
||||
ASSERT_EQ(false, lease.acquire());
|
||||
ASSERT_EQ(ObThreadLease::READY, lease.value());
|
||||
|
||||
// Acquire again, expect to return failed, status change to READY
|
||||
// 再次acquire,期望失败,状态变更为READY
|
||||
ASSERT_EQ(false, lease.acquire());
|
||||
ASSERT_EQ(ObThreadLease::READY, lease.value());
|
||||
|
||||
// Acquire again, expect to return failed, status change to READY
|
||||
// 再次acquire,期望失败,状态变更为READY
|
||||
ASSERT_EQ(false, lease.acquire());
|
||||
ASSERT_EQ(ObThreadLease::READY, lease.value());
|
||||
|
||||
// Revoke once, expect to return failed, status change to HANDLING
|
||||
// revoke一次,期望失败,状态变更为HANDLING
|
||||
ASSERT_EQ(false, lease.revoke());
|
||||
ASSERT_EQ(ObThreadLease::HANDLING, lease.value());
|
||||
|
||||
// Acquire again, expect to return failed, status change to READY
|
||||
// 再次acquire,期望失败,状态变更为READY
|
||||
ASSERT_EQ(false, lease.acquire());
|
||||
ASSERT_EQ(ObThreadLease::READY, lease.value());
|
||||
|
||||
// Acquire again, expect to return failed, status change to READY
|
||||
// 再次acquire,期望失败,状态变更为READY
|
||||
ASSERT_EQ(false, lease.acquire());
|
||||
ASSERT_EQ(ObThreadLease::READY, lease.value());
|
||||
|
||||
// Revoke once, expect to return failed, status change to HANDLING
|
||||
// revoke一次,期望失败,状态变更为HANDLING
|
||||
ASSERT_EQ(false, lease.revoke());
|
||||
ASSERT_EQ(ObThreadLease::HANDLING, lease.value());
|
||||
|
||||
// Revoke again, expect to return success, status change to IDLE
|
||||
// 再次revoke,期望成功,状态变更为IDLE
|
||||
ASSERT_EQ(true, lease.revoke());
|
||||
ASSERT_EQ(ObThreadLease::IDLE, lease.value());
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
|
||||
@ -13,20 +13,22 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "lib/thread/thread_pool.h"
|
||||
#include "lib/time/ob_time_utility.h"
|
||||
#include "../coro/testing.h"
|
||||
|
||||
using namespace oceanbase::lib;
|
||||
using namespace oceanbase::common;
|
||||
using namespace std;
|
||||
|
||||
TEST(TestThreadPool, Submit1)
|
||||
TEST(TestThreadPool, DISABLED_Submit1)
|
||||
{
|
||||
// construct thread pool.
|
||||
class : public ThreadPool {
|
||||
class : public ThreadPool
|
||||
{
|
||||
void run1() override
|
||||
{
|
||||
while (!has_set_stop()) {
|
||||
this_routine::usleep(100L * 1000L);
|
||||
::usleep(100L * 1000L);
|
||||
}
|
||||
}
|
||||
} tp;
|
||||
@ -38,7 +40,7 @@ TEST(TestThreadPool, Submit1)
|
||||
int ret = OB_SUCCESS;
|
||||
ret = tp.submit([] {
|
||||
cout << "ok2" << endl;
|
||||
this_routine::usleep(1 * 1000L * 1000L);
|
||||
::usleep(1 * 1000L * 1000L);
|
||||
});
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
|
||||
@ -49,15 +51,15 @@ TEST(TestThreadPool, Submit1)
|
||||
|
||||
// after 2s, previous task would be finished so that new task should
|
||||
// be accepted.
|
||||
this_routine::usleep(2 * 1000L * 1000L);
|
||||
::usleep(2 * 1000L * 1000L);
|
||||
ret = tp.submit([] { cout << "ok4" << endl; });
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
|
||||
this_routine::usleep(1 * 1000L * 1000L);
|
||||
::usleep(1 * 1000L * 1000L);
|
||||
ret = tp.submit([] { cout << "ok5" << endl; });
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
|
||||
this_routine::usleep(1 * 1000L * 1000L);
|
||||
::usleep(1 * 1000L * 1000L);
|
||||
ret = tp.submit([] { cout << "ok6" << endl; });
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
|
||||
@ -69,11 +71,12 @@ TEST(TestThreadPool, Submit1)
|
||||
TEST(TestThreadPool, DISABLED_SubmitX)
|
||||
{
|
||||
// construct thread pool.
|
||||
class : public ThreadPool {
|
||||
class : public ThreadPool
|
||||
{
|
||||
void run1() override
|
||||
{
|
||||
while (!has_set_stop()) {
|
||||
this_routine::usleep(100L * 1000L);
|
||||
::usleep(100L * 1000L);
|
||||
}
|
||||
}
|
||||
} tp;
|
||||
@ -81,24 +84,28 @@ TEST(TestThreadPool, DISABLED_SubmitX)
|
||||
tp.set_thread_max_tasks(1);
|
||||
tp.start();
|
||||
|
||||
TIME_LESS(100 * 1000L, [&tp] {
|
||||
this_routine::usleep(10L * 1000L);
|
||||
cout << co_current_time() << endl;
|
||||
tp.submit([] { cout << co_current_time() << endl; });
|
||||
TIME_LESS(100*1000L, [&tp] {
|
||||
::usleep(10L * 1000L);
|
||||
cout << ObTimeUtility::current_time() << endl;
|
||||
tp.submit([] {
|
||||
cout << ObTimeUtility::current_time() << endl;
|
||||
});
|
||||
});
|
||||
|
||||
tp.stop();
|
||||
tp.wait();
|
||||
tp.destroy();
|
||||
|
||||
}
|
||||
|
||||
TEST(TestThreadPool, Submit2)
|
||||
TEST(TestThreadPool, DISABLED_Submit2)
|
||||
{
|
||||
// construct thread pool.
|
||||
class : public ThreadPool {
|
||||
class : public ThreadPool
|
||||
{
|
||||
void run1() override
|
||||
{
|
||||
this_routine::usleep(3 * 1000L * 1000L);
|
||||
::usleep(3 * 1000L * 1000L);
|
||||
}
|
||||
} tp;
|
||||
tp.init();
|
||||
@ -109,12 +116,12 @@ TEST(TestThreadPool, Submit2)
|
||||
int ret = OB_SUCCESS;
|
||||
ret = tp.submit([] {
|
||||
cout << "ok2" << endl;
|
||||
this_routine::usleep(1 * 1000L * 1000L);
|
||||
::usleep(1 * 1000L * 1000L);
|
||||
});
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
ret = tp.submit([] {
|
||||
cout << "ok2" << endl;
|
||||
this_routine::usleep(1 * 1000L * 1000L);
|
||||
::usleep(1 * 1000L * 1000L);
|
||||
});
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
|
||||
@ -125,7 +132,7 @@ TEST(TestThreadPool, Submit2)
|
||||
|
||||
// after 2s, previous task would be finished so that new task should
|
||||
// be accepted.
|
||||
this_routine::usleep(2 * 1000L * 1000L);
|
||||
::usleep(2 * 1000L * 1000L);
|
||||
ret = tp.submit([] { cout << "ok4" << endl; });
|
||||
EXPECT_EQ(OB_SUCCESS, ret);
|
||||
|
||||
@ -134,13 +141,14 @@ TEST(TestThreadPool, Submit2)
|
||||
tp.destroy();
|
||||
}
|
||||
|
||||
TEST(TestThreadPool, SubmitN)
|
||||
TEST(TestThreadPool, DISABLED_SubmitN)
|
||||
{
|
||||
// construct thread pool.
|
||||
class : public ThreadPool {
|
||||
class : public ThreadPool
|
||||
{
|
||||
void run1() override
|
||||
{
|
||||
this_routine::usleep(3 * 1000L * 1000L);
|
||||
::usleep(3 * 1000L * 1000L);
|
||||
}
|
||||
} tp;
|
||||
tp.init();
|
||||
@ -153,40 +161,41 @@ TEST(TestThreadPool, SubmitN)
|
||||
for (i = 0; i < 100; i++) {
|
||||
ret = tp.submit([] {
|
||||
cout << "ok2" << endl;
|
||||
this_routine::usleep(1 * 1000L * 1000L);
|
||||
::usleep(1 * 1000L * 1000L);
|
||||
});
|
||||
if (OB_FAIL(ret)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(8, i); // 2 * 4
|
||||
EXPECT_EQ(8, i); // 2 * 4
|
||||
|
||||
// wait 2s for previous tasks finishing.
|
||||
this_routine::usleep(2 * 1000L * 1000L);
|
||||
::usleep(2 * 1000L * 1000L);
|
||||
tp.set_thread_count(5);
|
||||
for (i = 0; i < 100; i++) {
|
||||
ret = tp.submit([] {
|
||||
cout << "ok2" << endl;
|
||||
this_routine::usleep(1 * 1000L * 1000L);
|
||||
::usleep(1 * 1000L * 1000L);
|
||||
});
|
||||
if (OB_FAIL(ret)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(10, i); // 2 * 5
|
||||
EXPECT_EQ(10, i); // 2 * 5
|
||||
|
||||
// tp.stop();
|
||||
tp.wait();
|
||||
tp.destroy();
|
||||
}
|
||||
|
||||
TEST(TestThreadPool, LoopCheckConcurrency)
|
||||
TEST(TestThreadPool, DISABLED_LoopCheckConcurrency)
|
||||
{
|
||||
class : public ThreadPool {
|
||||
class : public ThreadPool
|
||||
{
|
||||
void run1() override
|
||||
{
|
||||
while (!has_set_stop()) {
|
||||
this_routine::usleep(3 * 1000L * 1000L);
|
||||
::usleep(3 * 1000L * 1000L);
|
||||
}
|
||||
}
|
||||
} tp;
|
||||
@ -202,7 +211,7 @@ TEST(TestThreadPool, LoopCheckConcurrency)
|
||||
ASSERT_EQ(OB_SUCCESS, tp.submit([&n] { ATOMIC_INC(&n); }));
|
||||
ASSERT_EQ(OB_SUCCESS, tp.submit([&n] { ATOMIC_INC(&n); }));
|
||||
while (ATOMIC_LOAD(&n) != 3) {
|
||||
this_routine::usleep(1 * 1000L);
|
||||
::usleep(1*1000L);
|
||||
}
|
||||
cout << "loop: " << i << endl;
|
||||
}
|
||||
@ -212,7 +221,7 @@ TEST(TestThreadPool, LoopCheckConcurrency)
|
||||
tp.destroy();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
@ -19,7 +19,8 @@ using namespace std;
|
||||
|
||||
TEST(TestThreadPool, Submit)
|
||||
{
|
||||
class : public ThreadPool {
|
||||
class : public ThreadPool
|
||||
{
|
||||
void run1() override()
|
||||
{
|
||||
cout << "ok" << endl;
|
||||
@ -29,7 +30,7 @@ TEST(TestThreadPool, Submit)
|
||||
tp.start();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
104
deps/oblib/unittest/lib/thread/test_threads.cpp
vendored
Normal file
104
deps/oblib/unittest/lib/thread/test_threads.cpp
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "atomic"
|
||||
#include "lib/thread/threads.h"
|
||||
|
||||
using namespace oceanbase::lib;
|
||||
|
||||
TEST(TestThreads, CanRun)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
val = 0;
|
||||
class Thread: public Threads {
|
||||
public:
|
||||
Thread(int &val) : val_(val) {}
|
||||
virtual void run(int64_t idx) override
|
||||
{
|
||||
val_++;
|
||||
}
|
||||
int &val_;
|
||||
} th(val);
|
||||
th.start();
|
||||
th.wait();
|
||||
ASSERT_EQ(1, val);
|
||||
}
|
||||
|
||||
TEST(TestThreads, CanRunMulti)
|
||||
{
|
||||
static std::atomic<int64_t> val;
|
||||
class Thread: public Threads
|
||||
{
|
||||
public:
|
||||
Thread(std::atomic<int64_t>&val) : val_(val) {}
|
||||
void run(int64_t idx) final
|
||||
{
|
||||
val += idx;
|
||||
while (!ATOMIC_LOAD(&has_set_stop()))
|
||||
;
|
||||
}
|
||||
std::atomic<int64_t> &val_;
|
||||
} th(val);
|
||||
|
||||
val = 0;
|
||||
th.set_thread_count(7);
|
||||
th.start();
|
||||
th.stop();
|
||||
th.wait();
|
||||
ASSERT_EQ(21, val); // 0+1+2+3+4+5+6
|
||||
}
|
||||
|
||||
TEST(TestThreads, DynamicThread)
|
||||
{
|
||||
static std::atomic<int64_t> starts;
|
||||
static std::atomic<int64_t> exits;
|
||||
class: public Threads
|
||||
{
|
||||
std::atomic<int64_t> n_threads_;
|
||||
public:
|
||||
int set_thread_count(int64_t n_threads)
|
||||
{
|
||||
n_threads_ = n_threads;
|
||||
return Threads::set_thread_count(n_threads);
|
||||
}
|
||||
void run(int64_t idx) final
|
||||
{
|
||||
starts++;
|
||||
while (idx < n_threads_ && !has_set_stop())
|
||||
;
|
||||
exits++;
|
||||
}
|
||||
} th;
|
||||
th.set_thread_count(1);
|
||||
th.start();
|
||||
while (starts != 1) { ::usleep(10); }
|
||||
th.set_thread_count(2);
|
||||
while (starts != 2) { ::usleep(10); }
|
||||
th.set_thread_count(4);
|
||||
while (starts != 4) { ::usleep(10); }
|
||||
th.set_thread_count(1);
|
||||
while (exits != 3) { ::usleep(10); }
|
||||
th.submit([]{});
|
||||
//ASSERT_EQ(1, th.get_cur_tasks());
|
||||
th.stop();
|
||||
th.wait();
|
||||
ASSERT_EQ(4, starts);
|
||||
ASSERT_EQ(4, exits);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user