Compare commits

...

2 Commits
main ... miao

Author SHA1 Message Date
mjh a18b6e44de 123
7 months ago
mjh 2fa6b5a541 1231
7 months ago

@ -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,56 +29,77 @@
* 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 volatile int g_count = 0; // 定义全局变量
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; static volatile int g_count = 0; // 用于计数的全局变量
static int g_testAtforkCount = 0; static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; // 初始化互斥锁
static int g_testAtforkPrepare = 0; static int g_testAtforkCount = 0; // 用于跟踪fork调用次数
static int g_testAtforkParent = 0; static int g_testAtforkPrepare = 0; // 用于跟踪Prepare函数调用次数
static int g_testAtforkChild = 0; static int g_testAtforkParent = 0; // 用于跟踪Parent函数调用次数
static const int SLEEP_TIME = 2; static int g_testAtforkChild = 0; // 用于跟踪child函数调用次数
static const int SLEEP_TIME = 2; // 休眠时间常量
// Prepare函数fork之前调用
static void Prepare() static void Prepare()
{ {
int err; int err;
// 断言g_testAtforkCount等于1
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount);
// 加锁
err = pthread_mutex_lock(&g_lock); err = pthread_mutex_lock(&g_lock);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
// 增加Prepare函数调用次数
g_testAtforkPrepare++; g_testAtforkPrepare++;
} }
// Parent函数fork之后在父进程中调用
static void Parent() static void Parent()
{ {
int err; int err;
// 断言g_testAtforkCount等于1
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount);
// 解锁
err = pthread_mutex_unlock(&g_lock); err = pthread_mutex_unlock(&g_lock);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
// 增加Parent函数调用次数
g_testAtforkParent++; g_testAtforkParent++;
} }
// child函数fork之后在子进程中调用
static void child() static void child()
{ {
int err; int err;
// 断言g_testAtforkCount等于1
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount);
// 解锁
err = pthread_mutex_unlock(&g_lock); err = pthread_mutex_unlock(&g_lock);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
// 增加child函数调用次数
g_testAtforkChild++; g_testAtforkChild++;
} }
// 线程函数
static void *ThreadProc(void *arg) static void *ThreadProc(void *arg)
{ {
int err; int err;
while (g_count < 5) { // 5, wait until g_count == 5. // 循环直到g_count等于5
while (g_count < 5) {
// 加锁
err = pthread_mutex_lock(&g_lock); err = pthread_mutex_lock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 增加计数
g_count++; g_count++;
// 休眠并让出CPU
SLEEP_AND_YIELD(SLEEP_TIME); SLEEP_AND_YIELD(SLEEP_TIME);
// 解锁
err = pthread_mutex_unlock(&g_lock); err = pthread_mutex_unlock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 休眠并让出CPU
SLEEP_AND_YIELD(SLEEP_TIME); SLEEP_AND_YIELD(SLEEP_TIME);
} }
@ -85,6 +107,7 @@ EXIT:
return NULL; return NULL;
} }
// 测试pthread_atfork的函数
static void *PthreadAtforkTest(void *arg) static void *PthreadAtforkTest(void *arg)
{ {
int err; int err;
@ -92,44 +115,60 @@ static void *PthreadAtforkTest(void *arg)
pthread_t tid; pthread_t tid;
int status = 0; int status = 0;
// 初始化全局变量
g_count = 0; g_count = 0;
g_testAtforkCount = 0; g_testAtforkCount = 0;
g_testAtforkPrepare = 0; g_testAtforkPrepare = 0;
g_testAtforkParent = 0; g_testAtforkParent = 0;
g_testAtforkChild = 0; g_testAtforkChild = 0;
// 创建线程
err = pthread_create(&tid, NULL, ThreadProc, NULL); err = pthread_create(&tid, NULL, ThreadProc, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 设置pthread_atfork
err = pthread_atfork(Prepare, Parent, child); err = pthread_atfork(Prepare, Parent, child);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 增加fork调用次数
g_testAtforkCount++; g_testAtforkCount++;
// 休眠并让出CPU
SLEEP_AND_YIELD(SLEEP_TIME); SLEEP_AND_YIELD(SLEEP_TIME);
// fork进程
pid = fork(); pid = fork();
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000. ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000.
ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT); ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT);
// 子进程中执行
if (pid == 0) { if (pid == 0) {
ICUNIT_GOTO_EQUAL(g_testAtforkChild, 1, g_testAtforkChild, EXIT); ICUNIT_GOTO_EQUAL(g_testAtforkChild, 1, g_testAtforkChild, EXIT);
int status; int status;
while (g_count < 5) { // 5, wait until g_count == 5. // 循环直到g_count等于5
while (g_count < 5) {
// 加锁
err = pthread_mutex_lock(&g_lock); err = pthread_mutex_lock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 增加计数
g_count++; g_count++;
// 休眠并让出CPU
SLEEP_AND_YIELD(SLEEP_TIME); SLEEP_AND_YIELD(SLEEP_TIME);
// 解锁
err = pthread_mutex_unlock(&g_lock); err = pthread_mutex_unlock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 休眠并让出CPU
SLEEP_AND_YIELD(SLEEP_TIME); SLEEP_AND_YIELD(SLEEP_TIME);
} }
exit(15); // 15, set exit status exit(15); // 15, set exit status
} }
// 父进程中执行
ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT); ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT);
// 等待线程结束
err = pthread_join(tid, NULL); err = pthread_join(tid, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT);
// 等待子进程结束
err = waitpid(pid, &status, 0); err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status); status = WEXITSTATUS(status);
ICUNIT_GOTO_EQUAL(err, pid, err, EXIT); ICUNIT_GOTO_EQUAL(err, pid, err, EXIT);
@ -143,6 +182,7 @@ EXIT_WAIT:
return NULL; return NULL;
} }
// 测试用例函数
static int Testcase() static int Testcase()
{ {
int ret; int ret;
@ -151,25 +191,34 @@ static int Testcase()
pthread_attr_t a = { 0 }; pthread_attr_t a = { 0 };
struct sched_param param = { 0 }; struct sched_param param = { 0 };
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param); ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
// 获取当前线程的优先级
curThreadPri = param.sched_priority; curThreadPri = param.sched_priority;
// 初始化线程属性
ret = pthread_attr_init(&a); ret = pthread_attr_init(&a);
// 设置线程属性,明确调度策略
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
// 设置线程优先级
param.sched_priority = curThreadPri + 2; // 2, adjust the priority. param.sched_priority = curThreadPri + 2; // 2, adjust the priority.
pthread_attr_setschedparam(&a, &param); pthread_attr_setschedparam(&a, &param);
// 创建线程
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0); ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 等待线程结束
ret = pthread_join(newPthread, NULL); ret = pthread_join(newPthread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0; return 0;
} }
// 测试函数注册
void ItTestPthreadAtfork001(void) void ItTestPthreadAtfork001(void)
{ {
// 注册测试用例
TEST_ADD_CASE("IT_PTHREAD_ATFORK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); TEST_ADD_CASE("IT_PTHREAD_ATFORK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
} }

@ -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,27 +29,35 @@
* 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"
#include <time.h> #include <time.h>
// 声明外部函数nanosleep用于线程休眠
extern int nanosleep(const struct timespec *req, struct timespec *rem); extern int nanosleep(const struct timespec *req, struct timespec *rem);
// 定义全局互斥锁和测试变量
static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER;
static volatile int g_testAtforkCount = 0; static volatile int g_testAtforkCount = 0;
static int g_testAtforkPrepare = 0; static int g_testAtforkPrepare = 0;
static int g_testAtforkParent = 0; static int g_testAtforkParent = 0;
// 线程函数Doit用于测试pthread_atfork
static void *Doit(void *arg) static void *Doit(void *arg)
{ {
int err; int err;
struct timespec ts = { 2, 0 }; // 2, set time 2s. struct timespec ts = { 2, 0 }; // 设置休眠时间为2秒
// 断言g_testAtforkCount为1
ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT); ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT);
// 尝试获取互斥锁
err = pthread_mutex_lock(&g_mux); err = pthread_mutex_lock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 休眠2秒
(void)nanosleep(&ts, NULL); (void)nanosleep(&ts, NULL);
// 释放互斥锁
err = pthread_mutex_unlock(&g_mux); err = pthread_mutex_unlock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
@ -56,17 +65,22 @@ EXIT:
return NULL; return NULL;
} }
// 线程函数Doit1与Doit类似用于测试pthread_atfork
static void *Doit1(void *arg) static void *Doit1(void *arg)
{ {
int err; int err;
struct timespec ts = { 2, 0 }; // 2, set time 2s. struct timespec ts = { 2, 0 }; // 设置休眠时间为2秒
// 断言g_testAtforkCount为1
ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT); ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT);
// 尝试获取互斥锁
err = pthread_mutex_lock(&g_mux); err = pthread_mutex_lock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 休眠2秒
(void)nanosleep(&ts, NULL); (void)nanosleep(&ts, NULL);
// 释放互斥锁
err = pthread_mutex_unlock(&g_mux); err = pthread_mutex_unlock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
@ -74,15 +88,19 @@ EXIT:
return NULL; return NULL;
} }
// Prepare函数在fork之前调用
static void Prepare(void) static void Prepare(void)
{ {
int err; int err;
// 释放互斥锁
err = pthread_mutex_unlock(&g_mux); err = pthread_mutex_unlock(&g_mux);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
// 增加Prepare函数的调用次数
g_testAtforkPrepare++; g_testAtforkPrepare++;
} }
// Parent函数在fork之后在父进程中调用
static void Parent(void) static void Parent(void)
{ {
int err = pthread_mutex_lock(&g_mux); int err = pthread_mutex_lock(&g_mux);
@ -90,79 +108,56 @@ static void Parent(void)
g_testAtforkParent++; g_testAtforkParent++;
} }
// 测试pthread_atfork的函数
static void *PthreadAtforkTest(void *arg) static void *PthreadAtforkTest(void *arg)
{ {
int err, ret; int err, ret;
int pid; int pid;
int status = 0; int status = 0;
struct timespec ts = { 1, 0 }; struct timespec ts = { 1, 0 }; // 设置休眠时间为1秒
pthread_t tid; pthread_t tid;
// 初始化测试变量
g_testAtforkCount = 0; g_testAtforkCount = 0;
g_testAtforkPrepare = 0; g_testAtforkPrepare = 0;
g_testAtforkParent = 0; g_testAtforkParent = 0;
// 设置fork时的回调函数
err = pthread_atfork(Prepare, Parent, NULL); err = pthread_atfork(Prepare, Parent, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 增加fork调用次数
g_testAtforkCount++; g_testAtforkCount++;
// 创建线程Doit
err = pthread_create(&tid, NULL, Doit, NULL); err = pthread_create(&tid, NULL, Doit, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 休眠1秒
nanosleep(&ts, NULL); nanosleep(&ts, NULL);
// 执行fork
pid = fork(); pid = fork();
ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT); ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT);
if (pid == 0) { if (pid == 0) {
// 子进程中执行Doit1
Doit1(NULL); Doit1(NULL);
exit(10); // 10, set exit status. // 设置退出状态
exit(10); // 设置退出状态为10
} }
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT_WAIT); // 100000, The pid will never exceed 100000. // 父进程等待子进程结束
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT_WAIT); // 确保pid不会超过100000
ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT); ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT);
// 等待线程Doit结束
err = pthread_join(tid, NULL); err = pthread_join(tid, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT);
// 等待子进程结束并获取退出状态
err = waitpid(pid, &status, 0); err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status); status = WEXITSTATUS(status);
ICUNIT_GOTO_EQUAL(err, pid, err, EXIT); ICUNIT_GOTO_EQUAL(err, pid, err, EXIT);
ICUNIT_GOTO_EQUAL(status, 10, status, EXIT); // 10, get exit status. ICUNIT_GOTO_EQUAL(status, 10, status, EXIT); // 获取子进程的退出状态
EXIT: EXIT:
return NULL; return NULL;
EXIT_WAIT: EXIT
(void)waitpid(pid, 0, 0);
return NULL;
}
static int Testcase(void)
{
int ret;
pthread_t newPthread;
int curThreadPri, curThreadPolicy;
pthread_attr_t a = { 0 };
struct sched_param param = { 0 };
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
curThreadPri = param.sched_priority;
ret = pthread_attr_init(&a);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 2, adjust the priority.
pthread_attr_setschedparam(&a, &param);
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_join(newPthread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
}
void ItTestPthreadAtfork002(void)
{
TEST_ADD_CASE("IT_PTHREAD_ATFORK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
}

@ -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,27 +29,33 @@
* 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_mutex_t g_pthreadMuxTest1; // 全局变量声明
static pthread_cond_t g_pthdCondTest1; static pthread_mutex_t g_pthreadMuxTest1; // 全局互斥锁
static pthread_cond_t g_pthdCondTest1; // 全局条件变量
// 线程函数PthreadF01
static void *PthreadF01(void *t) static void *PthreadF01(void *t)
{ {
int rc; int rc; // 用于存储函数返回值
// 加锁
rc = pthread_mutex_lock(&g_pthreadMuxTest1); rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 增加测试计数器
g_testCount++; g_testCount++;
LosTaskDelay(100); LosTaskDelay(100); // 延迟100ms
ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result. ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 断言测试计数器值为2
g_testCount++;
g_testCount++; // 增加测试计数器
// 等待条件变量
rc = pthread_cond_wait(&g_pthdCondTest1, &g_pthreadMuxTest1); rc = pthread_cond_wait(&g_pthdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result. ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 断言测试计数器值为5
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
@ -56,6 +63,7 @@ EXIT:
return NULL; return NULL;
} }
// 线程函数PthreadF02
static void *PthreadF02(void *t) static void *PthreadF02(void *t)
{ {
int i; int i;
@ -66,50 +74,56 @@ static void *PthreadF02(void *t)
rc = pthread_mutex_lock(&g_pthreadMuxTest1); rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result. ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 断言测试计数器值为3
g_testCount++; g_testCount++;
rc = pthread_cond_signal(&g_pthdCondTest1); rc = pthread_cond_signal(&g_pthdCondTest1); // 发送条件变量信号
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result. ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 断言测试计数器值为4
g_testCount++; g_testCount++;
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
LosTaskDelay(2); // 2, delay for Timing control. LosTaskDelay(2); // 延迟2ms用于时间控制
EXIT: EXIT:
pthread_exit(NULL); pthread_exit(NULL); // 退出线程
return NULL;
} }
// 测试用例函数
static unsigned int TestCase(void) static unsigned int TestCase(void)
{ {
int i; int i;
long t1 = 1; long t1 = 1;
long t2 = 2; long t2 = 2;
int rc; int rc;
pthread_t threads[3]; // 3, need 3 pthread for test. pthread_t threads[3]; // 创建3个线程用于测试
pthread_attr_t attr; pthread_attr_t attr;
const int loopNum = 2; const int loopNum = 2;
g_testCount = 0; g_testCount = 0; // 初始化测试计数器
pthread_mutex_init(&g_pthreadMuxTest1, NULL); pthread_mutex_init(&g_pthreadMuxTest1, NULL); // 初始化互斥锁
pthread_cond_init(&g_pthdCondTest1, NULL); pthread_cond_init(&g_pthdCondTest1, NULL); // 初始化条件变量
// 创建线程
rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1); rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2); rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 等待线程结束
for (i = 0; i < loopNum; i++) { for (i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL); rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
} }
// 销毁线程属性对象
rc = pthread_attr_destroy(&attr); rc = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 销毁互斥锁和条件变量
rc = pthread_mutex_destroy(&g_pthreadMuxTest1); rc = pthread_mutex_destroy(&g_pthreadMuxTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_cond_destroy(&g_pthdCondTest1); rc = pthread_cond_destroy(&g_pthdCondTest1);
@ -118,7 +132,8 @@ static unsigned int TestCase(void)
return 0; return 0;
} }
// 测试函数注册
void ItTestPthreadCond001(void) void ItTestPthreadCond001(void)
{ {
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_001", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_001", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
} }

@ -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,83 +29,102 @@
* 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_mutex_t g_pthreadMuxTest1; // 声明全局变量
static pthread_cond_t g_pthrdCondTest1; static pthread_mutex_t g_pthreadMuxTest1; // 全局互斥锁
static unsigned int g_pthreadExit = 0; static pthread_cond_t g_pthrdCondTest1; // 全局条件变量
static unsigned int g_pthreadExit = 0; // 用于控制线程退出的全局标志
// 线程函数PthreadF01
static void *PthreadF01(void *t) static void *PthreadF01(void *t)
{ {
int rc; int rc; // 用于存储函数返回值
unsigned int count = 0; unsigned int count = 0; // 计数器
const int testLoop = 2000; const int testLoop = 2000; // 循环次数
// 循环2000次
while (count < testLoop) { while (count < testLoop) {
// 加锁
rc = pthread_mutex_lock(&g_pthreadMuxTest1); rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 等待条件变量
rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1); rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 解锁
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
count++; count++;
} }
// 设置退出标志
g_pthreadExit = 1; g_pthreadExit = 1;
EXIT: EXIT:
return NULL; return NULL;
} }
// 线程函数PthreadF02
static void *PthreadF02(void *t) static void *PthreadF02(void *t)
{ {
int i; int i;
int rc; int rc;
// 循环直到PthreadF01线程设置退出标志
while (g_pthreadExit != 1) { while (g_pthreadExit != 1) {
// 加锁
rc = pthread_mutex_lock(&g_pthreadMuxTest1); rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 发送条件变量信号
rc = pthread_cond_signal(&g_pthrdCondTest1); rc = pthread_cond_signal(&g_pthrdCondTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 解锁
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
} }
EXIT: EXIT:
pthread_exit(NULL); pthread_exit(NULL); // 退出线程
return NULL;
} }
// 测试用例函数
static unsigned int TestCase(void) static unsigned int TestCase(void)
{ {
int i; int i;
long t1 = 1; long t1 = 1;
long t2 = 2; long t2 = 2;
int rc; int rc;
pthread_t threads[3]; pthread_t threads[3]; // 创建3个线程用于测试
pthread_attr_t attr; pthread_attr_t attr;
const int loopNum = 2; const int loopNum = 2;
g_pthreadExit = 0; g_pthreadExit = 0; // 初始化退出标志
g_testCount = 0; g_testCount = 0; // 初始化测试计数器
pthread_mutex_init(&g_pthreadMuxTest1, NULL); pthread_mutex_init(&g_pthreadMuxTest1, NULL); // 初始化互斥锁
pthread_cond_init(&g_pthrdCondTest1, NULL); pthread_cond_init(&g_pthrdCondTest1, NULL); // 初始化条件变量
// 创建线程
rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1); rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2); rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 等待线程结束
for (i = 0; i < loopNum; i++) { for (i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL); rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
} }
// 销毁线程属性对象
rc = pthread_attr_destroy(&attr); rc = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 销毁互斥锁和条件变量
rc = pthread_mutex_destroy(&g_pthreadMuxTest1); rc = pthread_mutex_destroy(&g_pthreadMuxTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_cond_destroy(&g_pthrdCondTest1); rc = pthread_cond_destroy(&g_pthrdCondTest1);
@ -113,7 +133,8 @@ static unsigned int TestCase(void)
return 0; return 0;
} }
// 测试函数注册
void ItTestPthreadCond002(void) void ItTestPthreadCond002(void)
{ {
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
} }

@ -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秒
// 检查测试计数器是否为55个线程
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);
} }

@ -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,116 +29,142 @@
* 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;
#define TEST_THREAD_COUNT 5
// 声明全局变量
static pthread_cond_t g_pthread_cond; // 全局条件变量
static pthread_mutex_t g_pthread_mutex; // 全局互斥锁
#define TEST_THREAD_COUNT 5 // 测试线程数量
// 线程函数pthread_cond_func002
static void *pthread_cond_func002(void *arg) static void *pthread_cond_func002(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);
// 获取当前时间并设置超时时间为2秒
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 2; /* 2: wait 2 seconds */ ts.tv_sec += 2; /* 2: wait 2 seconds */
// 等待条件变量超时时间为2秒
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, ETIMEDOUT, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); // 期望超时返回ETIMEDOUT
// 解锁
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_f07
static VOID *pthread_f07(void *argument) static VOID *pthread_f07(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_func002, NULL); ret = pthread_create(&thread[i], &attr, pthread_cond_func002, NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
} }
sleep(1); sleep(1); // 等待1秒确保所有线程都有机会执行并超时
// 检查测试计数器是否为55个线程
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */ ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
// 等待测试线程结束
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_f07, NULL); ret = pthread_create(&newTh, &attr, pthread_f07, 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 ItTestPthreadCond004(void) void ItTestPthreadCond004(void)
{ {
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_004", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_004", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
} }

@ -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,83 +29,94 @@
* 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 int g_number = 0; // 定义全局变量
static int g_okStatus = 777; // 777, a special number indicate the status is ok. static int g_number = 0; // 用于计数的全局变量
static pthread_once_t g_onceCtrl = PTHREAD_ONCE_INIT; static int g_okStatus = 777; // 777, 一个特殊的数字,表示状态正常
static pthread_once_t g_onceCtrl = PTHREAD_ONCE_INIT; // 用于控制只执行一次的初始化
// 初始化例程,只执行一次的函数
static void InitRoutine(void) static void InitRoutine(void)
{ {
g_number++; g_number++; // 每次调用时增加计数器
} }
// 线程函数Threadfunc
static void *Threadfunc(void *parm) static void *Threadfunc(void *parm)
{ {
int err; int err; // 用于存储函数返回值
err = pthread_once(&g_onceCtrl, InitRoutine); err = pthread_once(&g_onceCtrl, InitRoutine); // 确保InitRoutine只执行一次
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 断言返回值为0
return reinterpret_cast<void *>(g_okStatus); return reinterpret_cast<void *>(g_okStatus); // 返回状态值
EXIT: EXIT:
return NULL; return NULL; // 出错时返回NULL
} }
// 线程函数ThreadFuncTest
static void *ThreadFuncTest(void *arg) static void *ThreadFuncTest(void *arg)
{ {
pthread_t thread[3]; pthread_t thread[3]; // 线程数组
int rc = 0; int rc = 0; // 返回码
int i = 3; int i = 3; // 循环变量
void *status; void *status; // 线程返回状态
const int threadsNum = 3; const int threadsNum = 3; // 线程数量
g_number = 0; g_number = 0; // 初始化计数器
// 创建3个线程
for (i = 0; i < threadsNum; ++i) { for (i = 0; i < threadsNum; ++i) {
rc = pthread_create(&thread[i], NULL, Threadfunc, NULL); rc = pthread_create(&thread[i], NULL, Threadfunc, NULL);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
} }
// 等待3个线程结束并检查返回状态
for (i = 0; i < threadsNum; ++i) { for (i = 0; i < threadsNum; ++i) {
rc = pthread_join(thread[i], &status); rc = pthread_join(thread[i], &status);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ICUNIT_GOTO_EQUAL((unsigned int)status, (unsigned int)g_okStatus, status, EXIT); ICUNIT_GOTO_EQUAL((unsigned int)status, (unsigned int)g_okStatus, status, EXIT);
} }
// 断言InitRoutine只执行了一次
ICUNIT_GOTO_EQUAL(g_number, 1, g_number, EXIT); ICUNIT_GOTO_EQUAL(g_number, 1, g_number, EXIT);
EXIT: EXIT:
return NULL; return NULL; // 出错时返回NULL
} }
// 测试用例函数
static int Testcase(void) static int Testcase(void)
{ {
int ret; int ret; // 返回码
pthread_t newPthread; pthread_t newPthread; // 新线程
int curThreadPri, curThreadPolicy; int curThreadPri, curThreadPolicy; // 当前线程的优先级和策略
pthread_attr_t a = { 0 }; pthread_attr_t a = { 0 }; // 线程属性
struct sched_param param = { 0 }; struct sched_param param = { 0 }; // 调度参数
g_onceCtrl = PTHREAD_ONCE_INIT; g_onceCtrl = PTHREAD_ONCE_INIT; // 重置控制变量
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param); ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
curThreadPri = param.sched_priority; curThreadPri = param.sched_priority; // 获取当前优先级
// 初始化线程属性
ret = pthread_attr_init(&a); ret = pthread_attr_init(&a);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); // 设置继承调度策略
param.sched_priority = curThreadPri + 2; // 2, adjust the priority. param.sched_priority = curThreadPri + 2; // 调整优先级
pthread_attr_setschedparam(&a, &param); pthread_attr_setschedparam(&a, &param); // 设置调度参数
ret = pthread_create(&newPthread, &a, ThreadFuncTest, 0); ret = pthread_create(&newPthread, &a, ThreadFuncTest, 0); // 创建新线程
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_join(newPthread, NULL); ret = pthread_join(newPthread, NULL); // 等待新线程结束
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0; return 0; // 返回成功
} }
// 测试函数注册
void ItTestPthreadOnce001(void) void ItTestPthreadOnce001(void)
{ {
TEST_ADD_CASE("IT_PTHREAD_ONCE_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); TEST_ADD_CASE("IT_PTHREAD_ONCE_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
} }
Loading…
Cancel
Save