|
|
@ -1,3 +1,4 @@
|
|
|
|
|
|
|
|
// 版权声明
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
|
|
|
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
|
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
|
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
|
|
@ -28,124 +29,153 @@
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#include "it_pthread_test.h"
|
|
|
|
#include "it_pthread_test.h" // 包含测试框架头文件
|
|
|
|
|
|
|
|
|
|
|
|
static pthread_cond_t g_pthread_cond;
|
|
|
|
// 声明全局变量
|
|
|
|
static pthread_mutex_t g_pthread_mutex;
|
|
|
|
static pthread_cond_t g_pthread_cond; // 全局条件变量
|
|
|
|
#define TEST_THREAD_COUNT 5
|
|
|
|
static pthread_mutex_t g_pthread_mutex; // 全局互斥锁
|
|
|
|
|
|
|
|
#define TEST_THREAD_COUNT 5 // 测试线程数量
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 线程函数pthread_cond_func001
|
|
|
|
static void *pthread_cond_func001(void *arg)
|
|
|
|
static void *pthread_cond_func001(void *arg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int ret; // 用于存储函数返回值
|
|
|
|
struct timespec ts;
|
|
|
|
struct timespec ts; // 时间结构体
|
|
|
|
|
|
|
|
|
|
|
|
g_testCount++;
|
|
|
|
g_testCount++; // 增加测试计数器
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 加锁
|
|
|
|
ret = pthread_mutex_lock(&g_pthread_mutex);
|
|
|
|
ret = pthread_mutex_lock(&g_pthread_mutex);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前时间并设置超时时间为1分钟
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
|
ts.tv_sec += 60; /* 60: wait 1 minute */
|
|
|
|
ts.tv_sec += 60; /* 60: wait 1 minute */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 等待条件变量,超时时间为1分钟
|
|
|
|
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
|
|
|
|
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 解锁
|
|
|
|
ret = pthread_mutex_unlock(&g_pthread_mutex);
|
|
|
|
ret = pthread_mutex_unlock(&g_pthread_mutex);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
g_testCount++;
|
|
|
|
g_testCount++; // 增加测试计数器
|
|
|
|
EXIT:
|
|
|
|
EXIT:
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 线程函数pthread_f06
|
|
|
|
static VOID *pthread_f06(void *argument)
|
|
|
|
static VOID *pthread_f06(void *argument)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int policy;
|
|
|
|
int policy; // 调度策略
|
|
|
|
int ret;
|
|
|
|
int ret; // 用于存储函数返回值
|
|
|
|
int i;
|
|
|
|
int i; // 循环变量
|
|
|
|
pthread_attr_t attr;
|
|
|
|
pthread_attr_t attr; // 线程属性
|
|
|
|
struct sched_param schedParam = { 0 };
|
|
|
|
struct sched_param schedParam = { 0 }; // 调度参数
|
|
|
|
pthread_t thread[TEST_THREAD_COUNT];
|
|
|
|
pthread_t thread[TEST_THREAD_COUNT]; // 线程数组
|
|
|
|
|
|
|
|
|
|
|
|
g_testCount = 0;
|
|
|
|
g_testCount = 0; // 初始化测试计数器
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化线程属性
|
|
|
|
ret = pthread_attr_init(&attr);
|
|
|
|
ret = pthread_attr_init(&attr);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前线程的调度参数
|
|
|
|
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
|
|
|
|
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置新线程的优先级
|
|
|
|
schedParam.sched_priority -= 1;
|
|
|
|
schedParam.sched_priority -= 1;
|
|
|
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
|
|
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置线程的调度策略
|
|
|
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建测试线程
|
|
|
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
|
|
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
|
|
|
ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL);
|
|
|
|
ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sleep(1);
|
|
|
|
sleep(1); // 等待1秒
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查测试计数器是否为5(5个线程)
|
|
|
|
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
|
|
|
|
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 加锁
|
|
|
|
ret = pthread_mutex_lock(&g_pthread_mutex);
|
|
|
|
ret = pthread_mutex_lock(&g_pthread_mutex);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 发送条件变量广播信号
|
|
|
|
ret = pthread_cond_broadcast(&g_pthread_cond);
|
|
|
|
ret = pthread_cond_broadcast(&g_pthread_cond);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 解锁
|
|
|
|
ret = pthread_mutex_unlock(&g_pthread_mutex);
|
|
|
|
ret = pthread_mutex_unlock(&g_pthread_mutex);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 等待测试线程结束
|
|
|
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
|
|
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
|
|
|
ret = pthread_join(thread[i], NULL);
|
|
|
|
ret = pthread_join(thread[i], NULL);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查测试计数器是否为10(每个线程两次)
|
|
|
|
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
|
|
|
|
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
|
|
|
|
EXIT:
|
|
|
|
EXIT:
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 测试用例函数
|
|
|
|
static int TestCase(void)
|
|
|
|
static int TestCase(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int policy;
|
|
|
|
int policy; // 调度策略
|
|
|
|
pthread_attr_t attr;
|
|
|
|
pthread_attr_t attr; // 线程属性
|
|
|
|
pthread_t newTh;
|
|
|
|
pthread_t newTh; // 新线程
|
|
|
|
struct sched_param schedParam = { 0 };
|
|
|
|
struct sched_param schedParam = { 0 }; // 调度参数
|
|
|
|
int ret;
|
|
|
|
int ret; // 用于存储函数返回值
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化互斥锁
|
|
|
|
ret = pthread_mutex_init(&g_pthread_mutex, NULL);
|
|
|
|
ret = pthread_mutex_init(&g_pthread_mutex, NULL);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化条件变量
|
|
|
|
ret = pthread_cond_init(&g_pthread_cond, NULL);
|
|
|
|
ret = pthread_cond_init(&g_pthread_cond, NULL);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化线程属性
|
|
|
|
ret = pthread_attr_init(&attr);
|
|
|
|
ret = pthread_attr_init(&attr);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前线程的调度参数
|
|
|
|
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
|
|
|
|
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置新线程的优先级
|
|
|
|
schedParam.sched_priority -= 1;
|
|
|
|
schedParam.sched_priority -= 1;
|
|
|
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
|
|
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置线程的调度策略
|
|
|
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建新线程
|
|
|
|
ret = pthread_create(&newTh, &attr, pthread_f06, NULL);
|
|
|
|
ret = pthread_create(&newTh, &attr, pthread_f06, NULL);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 等待新线程结束
|
|
|
|
ret = pthread_join(newTh, NULL);
|
|
|
|
ret = pthread_join(newTh, NULL);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 测试函数注册
|
|
|
|
void ItTestPthreadCond003(void)
|
|
|
|
void ItTestPthreadCond003(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_003", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
|
|
|
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_003", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
|
|
|
|
}
|
|
|
|
}
|