!366 feat: 支持pthread_condattr_setclock
Merge pull request !366 from zhushengle/cond
This commit is contained in:
commit
93c1eb54a0
|
@ -60,6 +60,7 @@ int pthread_condattr_destroy(pthread_condattr_t *attr)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(VOID)memset_s(attr, sizeof(pthread_condattr_t), 0, sizeof(pthread_condattr_t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +70,22 @@ int pthread_condattr_init(pthread_condattr_t *attr)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attr->clock = CLOCK_REALTIME;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clk)
|
||||||
|
{
|
||||||
|
if ((attr == NULL) || (clk < 0)) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((clk != CLOCK_REALTIME) && (clk != CLOCK_MONOTONIC) &&
|
||||||
|
(clk != CLOCK_PROCESS_CPUTIME_ID) && (clk != CLOCK_THREAD_CPUTIME_ID)) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr->clock = clk;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +101,17 @@ STATIC INLINE INT32 CondInitCheck(const pthread_cond_t *cond)
|
||||||
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
||||||
{
|
{
|
||||||
int ret = ENOERR;
|
int ret = ENOERR;
|
||||||
|
pthread_condattr_t condAttr;
|
||||||
|
|
||||||
if (cond == NULL) {
|
if (cond == NULL) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
(VOID)attr;
|
|
||||||
|
if (attr == NULL) {
|
||||||
|
pthread_condattr_init(&condAttr);
|
||||||
|
attr = &condAttr;
|
||||||
|
}
|
||||||
|
|
||||||
(VOID)LOS_EventInit(&(cond->event));
|
(VOID)LOS_EventInit(&(cond->event));
|
||||||
|
|
||||||
cond->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
cond->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||||
|
@ -101,6 +124,7 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
||||||
cond->value = 0;
|
cond->value = 0;
|
||||||
(VOID)pthread_mutex_lock(cond->mutex);
|
(VOID)pthread_mutex_lock(cond->mutex);
|
||||||
cond->count = 0;
|
cond->count = 0;
|
||||||
|
cond->clock = attr->clock;
|
||||||
(VOID)pthread_mutex_unlock(cond->mutex);
|
(VOID)pthread_mutex_unlock(cond->mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -202,12 +226,16 @@ STATIC INT32 ProcessReturnVal(pthread_cond_t *cond, INT32 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||||
const struct timespec *absTime)
|
const struct timespec *ts)
|
||||||
{
|
{
|
||||||
UINT32 absTicks;
|
|
||||||
INT32 ret;
|
INT32 ret;
|
||||||
|
UINT32 absTicks;
|
||||||
|
const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
|
||||||
|
struct timespec tp;
|
||||||
|
UINT64 nseconds;
|
||||||
|
UINT64 currTime;
|
||||||
|
|
||||||
if ((cond == NULL) || (mutex == NULL) || (absTime == NULL)) {
|
if ((cond == NULL) || (mutex == NULL) || (ts == NULL)) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,15 +250,21 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||||
cond->count++;
|
cond->count++;
|
||||||
(VOID)pthread_mutex_unlock(cond->mutex);
|
(VOID)pthread_mutex_unlock(cond->mutex);
|
||||||
|
|
||||||
if ((absTime->tv_sec == 0) && (absTime->tv_nsec == 0)) {
|
if (!ValidTimeSpec(ts)) {
|
||||||
return ETIMEDOUT;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ValidTimeSpec(absTime)) {
|
clock_gettime(cond->clock, &tp);
|
||||||
|
currTime = (UINT64)tp.tv_sec * OS_SYS_NS_PER_SECOND + tp.tv_nsec;
|
||||||
|
nseconds = (UINT64)ts->tv_sec * OS_SYS_NS_PER_SECOND + ts->tv_nsec;
|
||||||
|
if (currTime >= nseconds) {
|
||||||
|
return ETIMEDOUT;
|
||||||
|
}
|
||||||
|
absTicks = ((nseconds - currTime) + nsPerTick - 1) / nsPerTick + 1;
|
||||||
|
if (absTicks >= UINT32_MAX) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
absTicks = OsTimeSpec2Tick(absTime);
|
|
||||||
if (pthread_mutex_unlock(mutex) != ENOERR) {
|
if (pthread_mutex_unlock(mutex) != ENOERR) {
|
||||||
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
|
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,9 +159,10 @@ LITE_TEST_CASE(PthreadFuncTestSuite, testPthread002, Function | MediumTest | Lev
|
||||||
static VOID *pthread_join_f03(void *argument)
|
static VOID *pthread_join_f03(void *argument)
|
||||||
{
|
{
|
||||||
int ret = pthread_detach(pthread_self());
|
int ret = pthread_detach(pthread_self());
|
||||||
ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret);
|
ICUNIT_GOTO_EQUAL(ret, ESRCH, ret, EXIT);
|
||||||
|
|
||||||
g_testCount++;
|
g_testCount++;
|
||||||
|
EXIT:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,9 +206,10 @@ LITE_TEST_CASE(PthreadFuncTestSuite, testPthread003, Function | MediumTest | Lev
|
||||||
static VOID *pthread_join_f04(void *argument)
|
static VOID *pthread_join_f04(void *argument)
|
||||||
{
|
{
|
||||||
int ret = pthread_detach(pthread_self());
|
int ret = pthread_detach(pthread_self());
|
||||||
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
g_testCount++;
|
g_testCount++;
|
||||||
|
EXIT:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,9 +254,10 @@ LITE_TEST_CASE(PthreadFuncTestSuite, testPthread004, Function | MediumTest | Lev
|
||||||
static VOID *pthread_join_f05(void *argument)
|
static VOID *pthread_join_f05(void *argument)
|
||||||
{
|
{
|
||||||
int ret = pthread_detach(pthread_self());
|
int ret = pthread_detach(pthread_self());
|
||||||
ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
|
ICUNIT_GOTO_EQUAL(ret, EINVAL, ret, EXIT);
|
||||||
|
|
||||||
usleep(100000); /* 100000: sleep 100 ms */
|
usleep(100000); /* 100000: sleep 100 ms */
|
||||||
|
EXIT:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,4 +298,235 @@ LITE_TEST_CASE(PthreadFuncTestSuite, testPthread005, Function | MediumTest | Lev
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static pthread_cond_t g_pthread_cond;
|
||||||
|
static pthread_mutex_t g_pthread_mutex;
|
||||||
|
#define TEST_THREAD_COUNT 5
|
||||||
|
static void *pthread_cond_func001(void *arg)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
g_testCount++;
|
||||||
|
|
||||||
|
ret = pthread_mutex_lock(&g_pthread_mutex);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
ts.tv_sec += 60; /* 60: wait 1 minute */
|
||||||
|
|
||||||
|
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_mutex_unlock(&g_pthread_mutex);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
g_testCount++;
|
||||||
|
EXIT:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID *pthread_f06(void *argument)
|
||||||
|
{
|
||||||
|
int policy;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
struct sched_param schedParam = { 0 };
|
||||||
|
pthread_t thread[TEST_THREAD_COUNT];
|
||||||
|
|
||||||
|
g_testCount = 0;
|
||||||
|
|
||||||
|
ret = pthread_attr_init(&attr);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
schedParam.sched_priority -= 1;
|
||||||
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
||||||
|
ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
|
||||||
|
|
||||||
|
ret = pthread_mutex_lock(&g_pthread_mutex);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_cond_broadcast(&g_pthread_cond);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_mutex_unlock(&g_pthread_mutex);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
||||||
|
ret = pthread_join(thread[i], NULL);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXIT:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_006
|
||||||
|
* @tc.name : event operation for deatch
|
||||||
|
* @tc.desc : [C- SOFTWARE -0200]
|
||||||
|
*/
|
||||||
|
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread006, Function | MediumTest | Level1)
|
||||||
|
{
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_t newTh;
|
||||||
|
struct sched_param schedParam = { 0 };
|
||||||
|
UINT32 ret;
|
||||||
|
|
||||||
|
ret = pthread_mutex_init(&g_pthread_mutex, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_cond_init(&g_pthread_cond, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_attr_init(&attr);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
schedParam.sched_priority = TASK_PRIO_TEST - 1;
|
||||||
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_create(&newTh, &attr, pthread_f06, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_join(newTh, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *pthread_cond_func002(void *arg)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
g_testCount++;
|
||||||
|
|
||||||
|
ret = pthread_mutex_lock(&g_pthread_mutex);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
ts.tv_sec += 60; /* 60: wait 1 minute */
|
||||||
|
|
||||||
|
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_mutex_unlock(&g_pthread_mutex);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
g_testCount++;
|
||||||
|
|
||||||
|
EXIT:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID *pthread_f07(void *argument)
|
||||||
|
{
|
||||||
|
int policy;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
struct sched_param schedParam = { 0 };
|
||||||
|
pthread_t thread[TEST_THREAD_COUNT];
|
||||||
|
|
||||||
|
g_testCount = 0;
|
||||||
|
|
||||||
|
ret = pthread_attr_init(&attr);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
schedParam.sched_priority -= 1;
|
||||||
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
||||||
|
ret = pthread_create(&thread[i], &attr, pthread_cond_func002, NULL);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_THREAD_COUNT; i++) {
|
||||||
|
ret = pthread_join(thread[i], NULL);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
|
||||||
|
|
||||||
|
EXIT:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_007
|
||||||
|
* @tc.name : event operation for deatch
|
||||||
|
* @tc.desc : [C- SOFTWARE -0200]
|
||||||
|
*/
|
||||||
|
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread007, Function | MediumTest | Level1)
|
||||||
|
{
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_t newTh;
|
||||||
|
struct sched_param schedParam = { 0 };
|
||||||
|
UINT32 ret;
|
||||||
|
|
||||||
|
ret = pthread_mutex_init(&g_pthread_mutex, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_cond_init(&g_pthread_cond, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_attr_init(&attr);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_attr_setstacksize(&attr, OS_TSK_TEST_STACK_SIZE);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
schedParam.sched_priority = TASK_PRIO_TEST - 1;
|
||||||
|
ret = pthread_attr_setschedparam(&attr, &schedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_create(&newTh, &attr, pthread_f07, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_join(newTh, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
};
|
||||||
|
|
||||||
RUN_TEST_SUITE(PthreadFuncTestSuite);
|
RUN_TEST_SUITE(PthreadFuncTestSuite);
|
||||||
|
|
Loading…
Reference in New Issue