未验证 提交 df0ed8d2 编写于 作者: O openharmony_ci 提交者: Gitee

!588 【liteos_m】posix接口融合,接口规范兼容性修改

Merge pull request !588 from LiteOS/master
......@@ -29,6 +29,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include "securec.h"
#include "los_config.h"
#include "los_memory.h"
......@@ -39,7 +40,7 @@ void *calloc(size_t nitems, size_t size)
size_t real_size;
void *ptr = NULL;
if (nitems == 0 || size == 0) {
if ((nitems == 0) || (size == 0) || (nitems > (UINT32_MAX / size))) {
return NULL;
}
......
......@@ -40,7 +40,6 @@ kernel_module(module_name) {
"porting/src/network/ntohl.c",
"porting/src/network/ntohs.c",
"porting/src/other_adapt.c",
"porting/src/pthread.c",
"porting/src/time.c",
]
configs += [ "$LITEOSTOPDIR:warn_config" ]
......
......@@ -57,6 +57,7 @@
#undef _PTHREAD_ONCE_INIT
#undef PTHREAD_STACK_MIN
#undef PTHREAD_MUTEX_DEFAULT
#include "los_config.h"
#define PTHREAD_STACK_MIN LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE
......@@ -76,17 +77,18 @@ typedef struct {
} pthread_attr_t;
#include "los_list.h"
typedef struct { unsigned int magic; unsigned int handle; } pthread_mutex_t;
typedef struct { unsigned type; } pthread_mutexattr_t;
typedef struct { unsigned int magic; unsigned int handle; pthread_mutexattr_t stAttr;} pthread_mutex_t;
#define _MUX_MAGIC 0xEBCFDEA0
#define _MUX_INVALID_HANDLE 0xEEEEEEEF
#define PTHREAD_MUTEX_DEFAULT 0
#define _PTHREAD_MUTEX_INITIALIZER { _MUX_MAGIC, _MUX_INVALID_HANDLE }
#define PTHREAD_MUTEXATTR_INITIALIZER { PTHREAD_MUTEX_RECURSIVE }
#define _PTHREAD_MUTEX_INITIALIZER { _MUX_MAGIC, _MUX_INVALID_HANDLE, PTHREAD_MUTEXATTR_INITIALIZER }
#ifdef _GNU_SOURCE
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { _MUX_MAGIC, _MUX_INVALID_HANDLE }
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { _MUX_MAGIC, _MUX_INVALID_HANDLE, PTHREAD_MUTEXATTR_INITIALIZER }
#endif
#include "los_event.h"
......
......@@ -49,6 +49,7 @@
#define _POSIX_TIMEOUTS
#define _POSIX_THREAD_PRIORITY_SCHEDULING
#define _UNIX98_THREAD_MUTEX_ATTRIBUTES
#define _POSIX_THREAD_PROCESS_SHARED
#include_next <sys/features.h>
......
/*
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <pthread.h>
int pthread_equal(pthread_t __t1, pthread_t __t2)
{
return (int)(__t1 == __t2);
}
......@@ -312,7 +312,7 @@ OUT:
int mq_close(mqd_t personal)
{
INT32 ret = 0;
INT32 ret = -1;
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
struct mqpersonal *tmp = NULL;
......@@ -425,7 +425,7 @@ int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr
return 0;
}
int mq_getsetattr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
static int MqGetSetAttr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
{
if (new == NULL) {
return OsMqGetAttr(mqd, old);
......@@ -439,7 +439,7 @@ int mq_getattr(mqd_t mqd, struct mq_attr *attr)
errno = EBADF;
return -1;
}
return mq_getsetattr(mqd, 0, attr);
return MqGetSetAttr(mqd, NULL, attr);
}
int mq_setattr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
......@@ -452,7 +452,7 @@ int mq_setattr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
errno = EINVAL;
return -1;
}
return mq_getsetattr(mqd, new, old);
return MqGetSetAttr(mqd, new, old);
}
int mq_unlink(const char *mqName)
......@@ -472,7 +472,9 @@ int mq_unlink(const char *mqName)
}
if (mqueueCB->mq_personal != NULL) {
errno = EINTR;
mqueueCB->unlinkflag = TRUE;
goto ERROUT_UNLOCK;
} else {
ret = DoMqueueDelete(mqueueCB);
}
......
......@@ -37,12 +37,14 @@
#include <limits.h>
#include "los_config.h"
#include "los_task.h"
#include "los_debug.h"
#define PTHREAD_DEFAULT_NAME "pthread"
#define PTHREAD_DEFAULT_NAME_LEN 8
#define PTHREAD_NAMELEN 16
#define PTHREAD_KEY_UNUSED 0
#define PTHREAD_KEY_USED 1
#define PTHREAD_TASK_INVAILD 0
typedef void (*PthreadKeyDtor)(void *);
typedef struct {
......@@ -59,6 +61,9 @@ typedef struct {
char name[PTHREAD_NAMELEN];
uintptr_t *key;
LOS_DL_LIST threadList;
unsigned char cancelState;
unsigned char cancelType;
unsigned char canceled;
} PthreadData;
static void PthreadExitKeyDtor(PthreadData *pthreadData);
......@@ -69,6 +74,7 @@ static void *PthreadEntry(UINT32 param)
void *(*startRoutine)(void *) = pthreadData->startRoutine;
void *ret = startRoutine(pthreadData->param);
pthread_exit(ret);
return ret;
}
......@@ -121,6 +127,9 @@ static int PthreadCreateAttrInit(const pthread_attr_t *attr, void *(*startRoutin
return error;
}
pthreadData->cancelState = PTHREAD_CANCEL_ENABLE;
pthreadData->cancelType = PTHREAD_CANCEL_DEFERRED;
pthreadData->canceled = 0;
pthreadData->startRoutine = startRoutine;
pthreadData->param = arg;
pthreadData->key = NULL;
......@@ -130,6 +139,23 @@ static int PthreadCreateAttrInit(const pthread_attr_t *attr, void *(*startRoutin
if (threadAttr->detachstate != PTHREAD_CREATE_DETACHED) {
taskInitParam->uwResved = LOS_TASK_ATTR_JOINABLE;
}
return 0;
}
static int CheckForCancel(void)
{
UINT32 intSave;
LosTaskCB *tcb = NULL;
intSave = LOS_IntLock();
tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
PthreadData *pthreadData = (PthreadData *)(UINTPTR)tcb->arg;
if ((pthreadData->canceled) && (pthreadData->cancelState == PTHREAD_CANCEL_ENABLE)) {
LOS_IntRestore(intSave);
return 1;
}
LOS_IntRestore(intSave);
return 0;
}
......@@ -167,6 +193,7 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
(void)LOS_TaskResume(taskID);
*thread = (pthread_t)taskID;
return 0;
}
......@@ -189,6 +216,94 @@ int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param
return 0;
}
int pthread_setschedprio(pthread_t thread, int prio)
{
if (LOS_TaskPriSet((UINT32)thread, (UINT16)prio) != LOS_OK) {
return EINVAL;
}
return 0;
}
int pthread_once(pthread_once_t *onceControl, void (*initRoutine)(void))
{
UINT32 intSave;
pthread_once_t old;
if ((onceControl == NULL) || (initRoutine == NULL)) {
return EINVAL;
}
intSave = LOS_IntLock();
old = *onceControl;
*onceControl = 1;
LOS_IntRestore(intSave);
if (!old) {
initRoutine();
}
return 0;
}
int pthread_equal(pthread_t thread1, pthread_t thread2)
{
return (int)(thread1 == thread2);
}
int pthread_setcancelstate(int state, int *oldState)
{
UINT32 intSave;
LosTaskCB *tcb = NULL;
PthreadData *pthreadData = NULL;
if ((state != PTHREAD_CANCEL_ENABLE) && (state != PTHREAD_CANCEL_DISABLE)) {
return EINVAL;
}
intSave = LOS_IntLock();
tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
pthreadData = (PthreadData *)(UINTPTR)tcb->arg;
if (pthreadData == NULL) {
LOS_IntRestore(intSave);
return EINVAL;
}
if (oldState != NULL) {
*oldState = pthreadData->cancelState;
}
pthreadData->cancelState = (UINT8)state;
LOS_IntRestore(intSave);
return 0;
}
int pthread_setcanceltype(int type, int *oldType)
{
UINT32 intSave;
LosTaskCB *tcb = NULL;
PthreadData *pthreadData = NULL;
if ((type != PTHREAD_CANCEL_ASYNCHRONOUS) && (type != PTHREAD_CANCEL_DEFERRED)) {
return EINVAL;
}
intSave = LOS_IntLock();
tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
pthreadData = (PthreadData *)(UINTPTR)tcb->arg;
if (pthreadData == NULL) {
LOS_IntRestore(intSave);
return EINVAL;
}
if (oldType != NULL) {
*oldType = pthreadData->cancelType;
}
pthreadData->cancelType = (UINT8)type;
LOS_IntRestore(intSave);
return 0;
}
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
{
UINT32 prio;
......@@ -204,6 +319,7 @@ int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *par
*policy = SCHED_RR;
param->sched_priority = prio;
return 0;
}
......@@ -212,21 +328,81 @@ pthread_t pthread_self(void)
return (pthread_t)LOS_CurTaskIDGet();
}
STATIC UINT32 DoPthreadCancel(LosTaskCB *task)
{
UINT32 ret = LOS_OK;
PthreadData *pthreadData = NULL;
LOS_TaskLock();
pthreadData = (PthreadData *)(UINTPTR)task->arg;
pthreadData->canceled = 0;
if ((task->taskStatus == PTHREAD_TASK_INVAILD) || (LOS_TaskSuspend(task->taskID) != LOS_OK)) {
ret = LOS_NOK;
goto OUT;
}
free((VOID *)(UINTPTR)task->arg);
task->arg = (UINT32)(UINTPTR)NULL;
(void)LOS_TaskDelete(task->taskID);
OUT:
LOS_TaskUnlock();
return ret;
}
int pthread_cancel(pthread_t thread)
{
UINT32 intSave;
LosTaskCB *tcb = NULL;
PthreadData *pthreadData = NULL;
if (!IsPthread(thread)) {
return EINVAL;
}
intSave = LOS_IntLock();
tcb = OS_TCB_FROM_TID((UINT32)thread);
pthreadData = (PthreadData *)(UINTPTR)tcb->arg;
pthreadData->canceled = 1;
if ((pthreadData->cancelState == PTHREAD_CANCEL_ENABLE) &&
(pthreadData->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS)) {
/*
* If the thread has cancellation enabled, and it is in
* asynchronous mode, suspend it and set corresponding thread's status.
* We also release the thread out of any current wait to make it wake up.
*/
if (DoPthreadCancel(tcb) == LOS_NOK) {
LOS_IntRestore(intSave);
return ESRCH;
}
}
LOS_IntRestore(intSave);
return 0;
}
return ENOSYS;
void pthread_testcancel(void)
{
if (CheckForCancel()) {
/*
* If we have cancellation enabled, and there is a cancellation
* pending, then go ahead and do the deed.
* Exit now with special retVal. pthread_exit() calls the
* cancellation handlers implicitly.
*/
pthread_exit((void *)PTHREAD_CANCELED);
}
}
int pthread_join(pthread_t thread, void **retval)
{
UINTPTR result;
UINT32 ret = LOS_TaskJoin((UINT32)thread, &result);
if (ret == LOS_ERRNO_TSK_NOT_JOIN_SELF) {
return EDEADLK;
} else if ((ret == LOS_ERRNO_TSK_NOT_CREATED) ||
(ret == LOS_ERRNO_TSK_OPERATE_IDLE) ||
(ret == LOS_ERRNO_TSK_ID_INVALID) ||
(ret == LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED)) {
return ESRCH;
} else if (ret != LOS_OK) {
return EINVAL;
}
......@@ -234,6 +410,7 @@ int pthread_join(pthread_t thread, void **retval)
if (retval != NULL) {
*retval = (VOID *)result;
}
return 0;
}
......@@ -256,7 +433,10 @@ void pthread_exit(void *retVal)
LosTaskCB *tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
tcb->joinRetval = (UINTPTR)retVal;
PthreadData *pthreadData = (PthreadData *)(UINTPTR)tcb->arg;
if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) {
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
}
if (pthreadData->key != NULL) {
PthreadExitKeyDtor(pthreadData);
}
......@@ -298,6 +478,7 @@ int pthread_setname_np(pthread_t thread, const char *name)
return EINVAL;
}
LOS_IntRestore(intSave);
return 0;
}
......@@ -315,6 +496,7 @@ int pthread_getname_np(pthread_t thread, char *buf, size_t buflen)
return 0;
}
}
return ERANGE;
}
......@@ -373,6 +555,7 @@ int pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
LOS_IntRestore(intSave);
*k = count;
return 0;
}
......@@ -406,6 +589,7 @@ int pthread_key_delete(pthread_key_t k)
g_pthreadKeyData[k].flag = PTHREAD_KEY_UNUSED;
g_pthreadkeyCount--;
LOS_IntRestore(intSave);
return 0;
}
......@@ -446,6 +630,7 @@ int pthread_setspecific(pthread_key_t k, const void *x)
pthreadData->key[k] = (uintptr_t)x;
LOS_IntRestore(intSave);
return 0;
}
......@@ -473,6 +658,7 @@ void *pthread_getspecific(pthread_key_t k)
key = (void *)pthreadData->key[k];
LOS_IntRestore(intSave);
return key;
}
......@@ -29,10 +29,12 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pthread.h"
#include <errno.h>
#include <securec.h>
#include <limits.h>
#include "pthread.h"
#include "los_config.h"
#include "los_debug.h"
int pthread_attr_init(pthread_attr_t *attr)
{
......@@ -44,7 +46,7 @@ int pthread_attr_init(pthread_attr_t *attr)
attr->schedpolicy = SCHED_RR;
attr->schedparam.sched_priority = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
attr->inheritsched = PTHREAD_INHERIT_SCHED;
attr->scope = PTHREAD_SCOPE_PROCESS;
attr->scope = PTHREAD_SCOPE_SYSTEM;
attr->stackaddr_set = 0;
attr->stackaddr = NULL;
attr->stacksize_set = 1;
......@@ -59,7 +61,8 @@ int pthread_attr_destroy(pthread_attr_t *attr)
return EINVAL;
}
/* Nothing to do here... */
(void)memset_s(attr, sizeof(pthread_attr_t), 0, sizeof(pthread_attr_t));
return 0;
}
......@@ -90,12 +93,12 @@ int pthread_attr_setscope(pthread_attr_t *attr, int scope)
return EINVAL;
}
if (scope == PTHREAD_SCOPE_PROCESS) {
if (scope == PTHREAD_SCOPE_SYSTEM) {
attr->scope = (unsigned int)scope;
return 0;
}
if (scope == PTHREAD_SCOPE_SYSTEM) {
if (scope == PTHREAD_SCOPE_PROCESS) {
return ENOTSUP;
}
......@@ -220,6 +223,28 @@ int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stackSize)
return 0;
}
int pthread_attr_setstack(pthread_attr_t *attr, void *stackAddr, size_t stackSize)
{
(void)attr;
(void)stackAddr;
(void)stackSize;
PRINT_ERR("%s: Don't support the pthread stack func currently!\n", __FUNCTION__);
errno = ENOSYS;
return -1;
}
int pthread_attr_getstack(const pthread_attr_t *attr, void **stackAddr, size_t *stackSize)
{
(void)attr;
(void)stackAddr;
(void)stackSize;
PRINT_ERR("%s: Don't support the pthread stack func currently!\n", __FUNCTION__);
errno = ENOSYS;
return -1;
}
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
{
/* Reject attempts to get a stack size when one has not been set. */
......
......@@ -29,7 +29,6 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "time_internal.h"
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
......@@ -37,9 +36,11 @@
#include <securec.h>
#include "los_config.h"
#include "los_task.h"
#include <los_swtmr.h>
#include "los_swtmr.h"
#include "time_internal.h"
#include "los_atomic.h"
#include "los_event.h"
#include "los_mux.h"
typedef struct {
volatile INT32 *realValue;
......@@ -54,6 +55,31 @@ typedef struct {
#define COND_FLAGS_MASK 0x0003U
#define COND_COUNTER_MASK (~COND_FLAGS_MASK)
int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *shared)
{
if ((attr == NULL) || (shared == NULL)) {
return EINVAL;
}
*shared = PTHREAD_PROCESS_PRIVATE;
return 0;
}
int pthread_condattr_setpshared(pthread_condattr_t *attr, int shared)
{
(VOID)attr;
if ((shared != PTHREAD_PROCESS_PRIVATE) && (shared != PTHREAD_PROCESS_SHARED)) {
return EINVAL;
}
if (shared != PTHREAD_PROCESS_PRIVATE) {
return ENOSYS;
}
return 0;
}
int pthread_condattr_destroy(pthread_condattr_t *attr)
{
if (attr == NULL) {
......@@ -61,6 +87,19 @@ int pthread_condattr_destroy(pthread_condattr_t *attr)
}
(VOID)memset_s(attr, sizeof(pthread_condattr_t), 0, sizeof(pthread_condattr_t));
attr->clock = INT32_MAX;
return 0;
}
int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clock)
{
if ((attr == NULL) || (clock == NULL)) {
return -1;
}
*clock = attr->clock;
return 0;
}
......@@ -71,6 +110,7 @@ int pthread_condattr_init(pthread_condattr_t *attr)
}
attr->clock = CLOCK_REALTIME;
return 0;
}
......@@ -86,6 +126,7 @@ int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clk)
}
attr->clock = clk;
return 0;
}
......@@ -95,6 +136,7 @@ STATIC INLINE INT32 CondInitCheck(const pthread_cond_t *cond)
(cond->event.stEventList.pstNext == NULL)) {
return 1;
}
return 0;
}
......@@ -149,6 +191,7 @@ int pthread_cond_destroy(pthread_cond_t *cond)
}
free(cond->mutex);
cond->mutex = NULL;
return 0;
}
......@@ -222,6 +265,7 @@ STATIC INT32 ProcessReturnVal(pthread_cond_t *cond, INT32 val)
ret = EINVAL;
break;
}
return ret;
}
......@@ -230,15 +274,17 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
{
INT32 ret;
UINT64 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) || (ts == NULL)) {
LosMuxCB *muxPosted = NULL;
pthread_testcancel();
if ((cond == NULL) || (mutex == NULL) || (ts == NULL) || (mutex->magic != _MUX_MAGIC)) {
return EINVAL;
}
muxPosted = GET_MUX(mutex->handle);
if ((mutex->stAttr.type == PTHREAD_MUTEX_ERRORCHECK) && (g_losTask.runTask != muxPosted->owner)) {
return EPERM;
}
if (CondInitCheck(cond)) {
ret = pthread_cond_init(cond, NULL);
if (ret != 0) {
......@@ -250,17 +296,11 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
cond->count++;
(VOID)pthread_mutex_unlock(cond->mutex);
if (!ValidTimeSpec(ts)) {
return EINVAL;
ret = OsGetTickTimeFromNow(ts, cond->clock, &absTicks);
if (ret != 0) {
return ret;
}
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;
}
......@@ -277,6 +317,8 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
}
ret = ProcessReturnVal(cond, ret);
pthread_testcancel();
return ret;
}
......
......@@ -35,8 +35,12 @@
#include "los_compiler.h"
#include "los_mux.h"
#include "errno.h"
#include "los_mux.h"
#include "los_debug.h"
#include "los_hook.h"
#include "los_sched.h"
#define MUTEXATTR_TYPE_MASK 0x0FU
#define OS_SYS_NS_PER_MSECOND 1000000
#define OS_SYS_NS_PER_SECOND 1000000000
......@@ -68,7 +72,28 @@ int pthread_mutexattr_init(pthread_mutexattr_t *mutexAttr)
return EINVAL;
}
mutexAttr->type = PTHREAD_MUTEX_RECURSIVE;
mutexAttr->type = PTHREAD_MUTEX_DEFAULT;
return 0;
}
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *outType)
{
INT32 type;
if ((attr == NULL) || (outType == NULL)) {
return EINVAL;
}
type = (INT32)(attr->type & MUTEXATTR_TYPE_MASK);
if ((type != PTHREAD_MUTEX_NORMAL) &&
(type != PTHREAD_MUTEX_RECURSIVE) &&
(type != PTHREAD_MUTEX_ERRORCHECK)) {
return EINVAL;
}
*outType = type;
return 0;
}
......@@ -83,12 +108,8 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *mutexAttr, int type)
((unsigned)type != PTHREAD_MUTEX_ERRORCHECK)) {
return EINVAL;
}
mutexAttr->type = (UINT8)((mutexAttr->type & ~MUTEXATTR_TYPE_MASK) | (UINT32)type);
if ((unsigned)type != PTHREAD_MUTEX_RECURSIVE) {
return EOPNOTSUPP;
}
mutexAttr->type = PTHREAD_MUTEX_RECURSIVE;
return 0;
}
......@@ -99,17 +120,25 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t *mutexAttr)
}
(VOID)memset_s(mutexAttr, sizeof(pthread_mutexattr_t), 0, sizeof(pthread_mutexattr_t));
return 0;
}
/* Initialize mutex. If mutexAttr is NULL, use default attributes. */
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr)
{
pthread_mutexattr_t useAttr;
UINT32 muxHandle;
UINT32 ret;
if ((mutexAttr != NULL) && (mutexAttr->type != PTHREAD_MUTEX_RECURSIVE)) {
return EOPNOTSUPP;
if (mutex == NULL) {
return EINVAL;
}
if (mutexAttr == NULL) {
(VOID)pthread_mutexattr_init(&useAttr);
} else {
useAttr = *mutexAttr;
}
ret = LOS_MuxCreate(&muxHandle);
......@@ -117,6 +146,7 @@ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexA
return MapError(ret);
}
mutex->stAttr = useAttr;
mutex->magic = _MUX_MAGIC;
mutex->handle = muxHandle;
......@@ -126,7 +156,7 @@ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexA
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
if ((mutex == NULL) || (mutex->magic != _MUX_MAGIC)) {
return EINVAL;
}
ret = LOS_MuxDelete(mutex->handle);
......@@ -135,16 +165,172 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex)
}
mutex->handle = _MUX_INVALID_HANDLE;
mutex->magic = 0;
return 0;
}
STATIC UINT32 CheckMutexAttr(const pthread_mutexattr_t *attr)
{
if ((attr->type != PTHREAD_MUTEX_NORMAL) &&
(attr->type != PTHREAD_MUTEX_RECURSIVE) &&
(attr->type != PTHREAD_MUTEX_ERRORCHECK)) {
return LOS_NOK;
}
return LOS_OK;
}
STATIC UINT32 MuxPreCheck(const pthread_mutex_t *mutex, const LosTaskCB *runTask)
{
if ((mutex == NULL) || (mutex->magic != _MUX_MAGIC) ||
((mutex->handle != _MUX_INVALID_HANDLE) && (mutex->handle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT))) {
return EINVAL;
}
if (OS_INT_ACTIVE) {
return EPERM;
}
/* DO NOT recommend to use blocking API in system tasks */
if ((runTask != NULL) && (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK)) {
PRINT_DEBUG("Warning: DO NOT recommend to use %s in system tasks.\n", __FUNCTION__);
}
if (CheckMutexAttr(&mutex->stAttr) != LOS_OK) {
return EINVAL;
}
return 0;
}
STATIC UINT32 MuxPendForPosix(pthread_mutex_t *mutex, UINT32 timeout)
{
UINT32 intSave;
LosMuxCB *muxPended = NULL;
UINT32 retErr;
LosTaskCB *runningTask = NULL;
UINT32 muxHandle = mutex->handle;
muxPended = GET_MUX(muxHandle);
intSave = LOS_IntLock();
if (muxPended->muxStat == OS_MUX_UNUSED) {
LOS_IntRestore(intSave);
OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
}
runningTask = (LosTaskCB *)g_losTask.runTask;
if (muxPended->muxCount == 0) {
muxPended->muxCount++;
muxPended->owner = runningTask;
muxPended->priority = runningTask->priority;
LOS_IntRestore(intSave);
OsHookCall(LOS_HOOK_TYPE_MUX_PEND, muxPended, timeout);
return LOS_OK;
}
if ((muxPended->owner == runningTask) && (mutex->stAttr.type == PTHREAD_MUTEX_RECURSIVE)) {
muxPended->muxCount++;
LOS_IntRestore(intSave);
OsHookCall(LOS_HOOK_TYPE_MUX_PEND, muxPended, timeout);
return LOS_OK;
}
if (!timeout) {
LOS_IntRestore(intSave);
OS_RETURN_ERROR(LOS_ERRNO_MUX_UNAVAILABLE);
}
runningTask->taskMux = (VOID *)muxPended;
if (muxPended->owner->priority > runningTask->priority) {
(VOID)OsSchedModifyTaskSchedParam(muxPended->owner, runningTask->priority);
}
OsSchedTaskWait(&muxPended->muxList, timeout);
LOS_IntRestore(intSave);
OsHookCall(LOS_HOOK_TYPE_MUX_PEND, muxPended, timeout);
LOS_Schedule();
intSave = LOS_IntLock();
if (runningTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {
runningTask->taskStatus &= (~OS_TASK_STATUS_TIMEOUT);
retErr = LOS_ERRNO_MUX_TIMEOUT;
LOS_IntRestore(intSave);
OS_RETURN_ERROR(retErr);
}
LOS_IntRestore(intSave);
return LOS_OK;
}
STATIC UINT32 MuxPostForPosix(pthread_mutex_t *mutex)
{
UINT32 intSave;
LosMuxCB *muxPosted = NULL;
LosTaskCB *resumedTask = NULL;
LosTaskCB *runningTask = NULL;
UINT32 muxHandle = mutex->handle;
muxPosted = GET_MUX(muxHandle);
intSave = LOS_IntLock();
if (muxPosted->muxStat == OS_MUX_UNUSED) {
LOS_IntRestore(intSave);
OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
}
runningTask = (LosTaskCB *)g_losTask.runTask;
if ((muxPosted->muxCount == 0) || (muxPosted->owner != runningTask)) {
LOS_IntRestore(intSave);
OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
}
if ((--(muxPosted->muxCount) != 0) && (mutex->stAttr.type == PTHREAD_MUTEX_RECURSIVE)) {
LOS_IntRestore(intSave);
OsHookCall(LOS_HOOK_TYPE_MUX_POST, muxPosted);
return LOS_OK;
}
if ((muxPosted->owner->priority) != muxPosted->priority) {
(VOID)OsSchedModifyTaskSchedParam(muxPosted->owner, muxPosted->priority);
}
if (!LOS_ListEmpty(&muxPosted->muxList)) {
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(muxPosted->muxList)));
muxPosted->muxCount = 1;
muxPosted->owner = resumedTask;
muxPosted->priority = resumedTask->priority;
resumedTask->taskMux = NULL;
OsSchedTaskWake(resumedTask);
LOS_IntRestore(intSave);
OsHookCall(LOS_HOOK_TYPE_MUX_POST, muxPosted);
LOS_Schedule();
} else {
muxPosted->owner = NULL;
LOS_IntRestore(intSave);
}
return LOS_OK;
}
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *absTimeout)
{
UINT32 ret;
UINT32 timeout;
UINT64 timeoutNs;
struct timespec curTime = {0};
if ((mutex->magic != _MUX_MAGIC) || (absTimeout->tv_nsec < 0) || (absTimeout->tv_nsec >= OS_SYS_NS_PER_SECOND)) {
LosMuxCB *muxPended = NULL;
ret = MuxPreCheck(mutex, OS_TCB_FROM_TID(LOS_CurTaskIDGet()));
if (ret != 0) {
return (INT32)ret;
}
if ((absTimeout == NULL) || (absTimeout->tv_nsec < 0) || (absTimeout->tv_nsec >= OS_SYS_NS_PER_SECOND)) {
return EINVAL;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
......@@ -152,6 +338,13 @@ int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *absTi
if (ret != LOS_OK) {
return MapError(ret);
}
} else {
muxPended = GET_MUX(mutex->handle);
if ((mutex->stAttr.type == PTHREAD_MUTEX_ERRORCHECK) &&
(muxPended->muxCount != 0) &&
(muxPended->owner == OS_TCB_FROM_TID(LOS_CurTaskIDGet()))) {
return EDEADLK;
}
}
ret = clock_gettime(CLOCK_REALTIME, &curTime);
if (ret != LOS_OK) {
......@@ -162,7 +355,8 @@ int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *absTi
return ETIMEDOUT;
}
timeout = (timeoutNs + (OS_SYS_NS_PER_MSECOND - 1)) / OS_SYS_NS_PER_MSECOND;
ret = LOS_MuxPend(mutex->handle, timeout);
ret = MuxPendForPosix(mutex, timeout);
return MapError(ret);
}
......@@ -170,42 +364,72 @@ int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *absTi
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
LosMuxCB *muxPended = NULL;
LosTaskCB *runTask = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
ret = MuxPreCheck(mutex, runTask);
if (ret != 0) {
return (INT32)ret;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
} else {
muxPended = GET_MUX(mutex->handle);
if ((mutex->stAttr.type == PTHREAD_MUTEX_ERRORCHECK) &&
(muxPended->muxCount != 0) &&
(muxPended->owner == runTask)) {
return EDEADLK;
}
}
ret = LOS_MuxPend(mutex->handle, LOS_WAIT_FOREVER);
ret = MuxPendForPosix(mutex, LOS_WAIT_FOREVER);
return MapError(ret);
}
int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
LosMuxCB *muxPended = NULL;
ret = MuxPreCheck(mutex, OS_TCB_FROM_TID(LOS_CurTaskIDGet()));
if (ret != 0) {
return (INT32)ret;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
} else {
muxPended = GET_MUX(mutex->handle);
if ((mutex->stAttr.type != PTHREAD_MUTEX_RECURSIVE) && (muxPended->muxCount != 0)) {
return EBUSY;
}
}
ret = LOS_MuxPend(mutex->handle, 0);
ret = MuxPendForPosix(mutex, 0);
return MapError(ret);
}
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
ret = MuxPreCheck(mutex, OS_TCB_FROM_TID(LOS_CurTaskIDGet()));
if (ret != 0) {
return (INT32)ret;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
return EINVAL;
}
ret = LOS_MuxPost(mutex->handle);
ret = MuxPostForPosix(mutex);
return MapError(ret);
}
......@@ -102,6 +102,7 @@ int sem_destroy(sem_t *sem)
errno = MapError(ret);
return -1;
}
return 0;
}
......@@ -119,6 +120,7 @@ int sem_wait(sem_t *sem)
errno = MapError(ret);
return -1;
}
return 0;
}
......@@ -140,38 +142,37 @@ int sem_post(sem_t *sem)
return 0;
}
static long long GetTickTimeFromNow(const struct timespec *absTimeSpec)
int sem_trywait(sem_t *sem)
{
struct timespec tsNow = { 0 };
long long ns;
long long tick;
UINT32 ret;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
clock_gettime(CLOCK_REALTIME, &tsNow);
ns = (absTimeSpec->tv_sec - tsNow.tv_sec) * OS_SYS_NS_PER_SECOND + (absTimeSpec->tv_nsec - tsNow.tv_nsec);
ret = LOS_SemPend((UINT32)sem->s_handle, LOS_NO_WAIT);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
/* Round up for ticks */
tick = (ns * LOSCFG_BASE_CORE_TICK_PER_SECOND + (OS_SYS_NS_PER_SECOND - 1)) / OS_SYS_NS_PER_SECOND;
return tick;
return 0;
}
int sem_timedwait(sem_t *sem, const struct timespec *timeout)
{
UINT32 ret;
long long tickCnt;
UINT64 tickCnt;
if ((sem == NULL) || (sem->s_magic != (int)_SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
if (!ValidTimeSpec(timeout)) {
errno = EINVAL;
return -1;
}
tickCnt = GetTickTimeFromNow(timeout);
if (tickCnt < 0) {
errno = ETIMEDOUT;
ret = OsGetTickTimeFromNow(timeout, CLOCK_REALTIME, &tickCnt);
if (ret != 0) {
errno = (INT32)ret;
return -1;
}
......@@ -192,7 +193,7 @@ int sem_getvalue(sem_t *sem, int *currVal)
{
UINT32 ret;
if ((sem == NULL) || (currVal == NULL)) {
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)|| (currVal == NULL)) {
errno = EINVAL;
return -1;
}
......
......@@ -43,6 +43,9 @@
#include "los_tick.h"
#include "los_context.h"
#include "los_interrupt.h"
#include "sys/times.h"
#define DELAYTIMER_MAX 0x7FFFFFFFF
/* accumulative time delta from discontinuous modify */
STATIC struct timespec g_accDeltaFromSet;
......@@ -96,7 +99,7 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
}
/* sleep in interrupt context or in task sched lock state */
errno = EPERM;
errno = EINTR;
return -1;
}
......@@ -105,12 +108,12 @@ int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *rest
UINT32 ret;
UINT32 swtmrID;
if (!timerID || (clockID != CLOCK_REALTIME)) {
if (!timerID || (clockID != CLOCK_REALTIME) || !evp) {
errno = EINVAL;
return -1;
}
if (!evp || evp->sigev_notify != SIGEV_THREAD || evp->sigev_notify_attributes) {
if ((evp->sigev_notify != SIGEV_THREAD) || evp->sigev_notify_attributes) {
errno = ENOTSUP;
return -1;
}
......@@ -152,7 +155,7 @@ int timer_settime(timer_t timerID, int flags,
if (flags != 0) {
/* flags not supported currently */
errno = ENOSYS;
errno = ENOTSUP;
return -1;
}
......@@ -190,6 +193,7 @@ int timer_settime(timer_t timerID, int flags,
swtmr->ucMode = (interval ? LOS_SWTMR_MODE_PERIOD : LOS_SWTMR_MODE_NO_SELFDELETE);
swtmr->uwInterval = (interval ? interval : expiry);
swtmr->ucOverrun = 0;
LOS_IntRestore(intSave);
if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) {
......@@ -229,7 +233,9 @@ int timer_gettime(timer_t timerID, struct itimerspec *value)
errno = EINVAL;
return -1;
}
if (ret == LOS_ERRNO_SWTMR_NOT_STARTED) {
tick = 0;
}
OsTick2TimeSpec(&value->it_value, tick);
OsTick2TimeSpec(&value->it_interval, (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ? 0 : swtmr->uwInterval);
return 0;
......@@ -237,10 +243,13 @@ int timer_gettime(timer_t timerID, struct itimerspec *value)
int timer_getoverrun(timer_t timerID)
{
(void)timerID;
SWTMR_CTRL_S *swtmr = NULL;
swtmr = OS_SWT_FROM_SID((UINT32)(UINTPTR)timerID);
errno = ENOSYS;
return -1;
if ((swtmr->ucOverrun) >= (UINT8)DELAYTIMER_MAX) {
return (INT32)DELAYTIMER_MAX;
}
return (int)swtmr->ucOverrun;
}
STATIC VOID OsGetHwTime(struct timespec *hwTime)
......@@ -696,3 +705,17 @@ unsigned sleep(unsigned seconds)
specTime.tv_nsec = (long)(nanoseconds % OS_SYS_NS_PER_SECOND);
return nanosleep(&specTime, NULL);
}
clock_t times(struct tms *tms)
{
clock_t clockTick = (clock_t)LOS_TickCountGet();
if (tms != NULL) {
tms->tms_cstime = clockTick;
tms->tms_cutime = clockTick;
tms->tms_stime = clockTick;
tms->tms_utime = clockTick;
}
return clockTick;
}
......@@ -111,5 +111,27 @@ STATIC INLINE VOID OsTick2TimeSpec(struct timespec *tp, UINT32 tick)
tp->tv_sec = (time_t)(ns / OS_SYS_NS_PER_SECOND);
tp->tv_nsec = (long)(ns % OS_SYS_NS_PER_SECOND);
}
STATIC INLINE INT32 OsGetTickTimeFromNow(const struct timespec *ts, clockid_t clockId, UINT64 *absTicks)
{
struct timespec tp;
UINT64 nseconds;
UINT64 currTime;
const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
if (!ValidTimeSpec(ts)) {
return EINVAL;
}
clock_gettime(clockId, &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;
return 0;
}
#endif
......@@ -271,6 +271,7 @@ typedef struct tagSwTmrCtrl {
struct tagSwTmrCtrl *pstNext; /* Pointer to the next software timer */
UINT8 ucState; /* Software timer state */
UINT8 ucMode; /* Software timer mode */
UINT8 ucOverrun; /* Times that a software timer repeats timing */
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
UINT8 ucRouses; /* wake up enable */
UINT8 ucSensitive; /* align enable */
......
......@@ -273,6 +273,7 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr)
OsDeleteSortLink(&swtmr->stSortList);
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
swtmr->ucOverrun = 0;
OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle());
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned = 0;
......@@ -289,6 +290,7 @@ STATIC VOID OsSwtmrTimeoutHandle(UINT64 currTime, SWTMR_CTRL_S *swtmr)
(VOID)LOS_QueueWriteCopy(g_swtmrHandlerQueue, &swtmrHandler, sizeof(SwtmrHandlerItem), LOS_NO_WAIT);
if (swtmr->ucMode == LOS_SWTMR_MODE_PERIOD) {
swtmr->ucOverrun++;
OsSwtmrStart(currTime, swtmr);
} else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) {
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
......@@ -492,6 +494,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
swtmr->ucSensitive = sensitive;
#endif
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
swtmr->ucOverrun = 0;
*swtmrId = swtmr->usTimerID;
SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME);
OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
......
......@@ -41,6 +41,9 @@
#define TASK_PRIO_TEST LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO
#define OS_TSK_TEST_STACK_SIZE 0x1000
#define PTHREAD_TASK_DELAY 10
static INT32 g_pthreadSem = 0;
static UINT32 g_testCount;
/**
......@@ -251,7 +254,7 @@ LITE_TEST_CASE(PthreadFuncTestSuite, testPthread004, Function | MediumTest | Lev
ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
ret = pthread_join(newTh, NULL);
ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
ICUNIT_ASSERT_EQUAL(ret, ESRCH, ret);
return LOS_OK;
};
......@@ -645,4 +648,343 @@ LITE_TEST_CASE(PthreadFuncTestSuite, testPthread008, Function | MediumTest | Lev
return LOS_OK;
};
static VOID *pthread_prio_f01(void *argument)
{
g_testCount++;
ICUNIT_ASSERT_EQUAL(g_testCount, (UINT32)argument, g_testCount);
return NULL;
}
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_009
* @tc.name : event operation for set priority
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread009, Function | MediumTest | Level1)
{
pthread_attr_t attr;
pthread_t thread[TEST_THREAD_COUNT];
struct sched_param schedParam = { 0 };
UINT32 ret;
UINT32 i = 0;
g_testCount = 0;
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);
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_create(&thread[i], &attr, pthread_prio_f01, TEST_THREAD_COUNT - i);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_setschedprio(thread[i], TASK_PRIO_TEST + TEST_THREAD_COUNT - i);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_join(thread[i], NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
return LOS_OK;
};
static VOID pthread_once_f01(void)
{
g_testCount++;
ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
}
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_010
* @tc.name : event operation for pthread_once
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread010, Function | MediumTest | Level1)
{
pthread_attr_t attr;
pthread_t thread[TEST_THREAD_COUNT];
struct sched_param schedParam = { 0 };
UINT32 ret;
UINT32 i = 0;
pthread_once_t onceControl = 0;
g_testCount = 0;
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);
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_once(&onceControl, pthread_once_f01);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
return LOS_OK;
};
static VOID *pthread_cancel_f01(void *argument)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
while (1) {
g_testCount++;
ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
LOS_TaskDelay(PTHREAD_TASK_DELAY);
}
return NULL;
}
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_011
* @tc.name : event operation for pthread_cancel
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread011, Function | MediumTest | Level1)
{
pthread_attr_t attr;
pthread_t thread;
struct sched_param schedParam = { 0 };
UINT32 ret;
pthread_once_t onceControl = 0;
g_testCount = 0;
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(&thread, &attr, pthread_cancel_f01, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_cancel(thread);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
return LOS_OK;
};
static VOID *pthread_testcancel_f01(void *argument)
{
INT32 ret = 0;
ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
ICUNIT_TRACK_EQUAL(ret, 0, ret);
ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
g_testCount = 1;
g_pthreadSem = 1;
while (g_pthreadSem == 1) {
LOS_TaskDelay(PTHREAD_TASK_DELAY);
}
LOS_TaskDelay(PTHREAD_TASK_DELAY);
pthread_testcancel();
g_testCount = -1;
return NULL;
}
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_012
* @tc.name : event operation for testcancel
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread012, Function | MediumTest | Level1)
{
pthread_attr_t attr;
pthread_t thread;
struct sched_param schedParam = { 0 };
UINT32 ret;
pthread_once_t onceControl = 0;
g_testCount = 0;
g_pthreadSem = 0;
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(&thread, &attr, pthread_testcancel_f01, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
while (g_pthreadSem == 0) {
LOS_TaskDelay(PTHREAD_TASK_DELAY);
}
ret = pthread_cancel(thread);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
g_pthreadSem = 0;
ret = pthread_join(thread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(g_testCount, 1, g_testCount);
return LOS_OK;
};
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_013
* @tc.name : event operation for set/get clock
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread013, Function | MediumTest | Level1)
{
INT32 ret;
clockid_t clk;
const int invalidClock = -100;
pthread_condattr_t condattr;
ret = pthread_condattr_init(&condattr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_condattr_getclock(&condattr, &clk);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(clk, 0, clk);
ret = pthread_condattr_setclock(&condattr, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_condattr_getclock(&condattr, &clk);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(clk, 0, clk);
struct timespec ts = {0};
ret = clock_getres(CLOCK_MONOTONIC, &ts);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_condattr_getclock(&condattr, &clk);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(clk, CLOCK_MONOTONIC, clk);
ret = pthread_condattr_setclock(&condattr, invalidClock);
ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
return 0;
}
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_014
* @tc.name : event operation for setpshared
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread014, Function | MediumTest | Level1)
{
INT32 ret;
pthread_condattr_t attr;
/* Initialize a cond attributes object */
ret = pthread_condattr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
/* Set 'pshared' to INVALID_PSHARED_VALUE. */
ret = pthread_condattr_setpshared(&attr, (-100));
ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
/* Destroy the cond attributes object */
ret = pthread_condattr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
}
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_015
* @tc.name : event operation for getpshared
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread015, Function | MediumTest | Level1)
{
INT32 ret;
INT32 pshared;
pthread_condattr_t attr;
/* Initialize a cond attributes object */
ret = pthread_condattr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
/* Set 'pshared' to INVALID_PSHARED_VALUE. */
ret = pthread_condattr_getpshared(&attr, &pshared);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(pshared, PTHREAD_PROCESS_PRIVATE, pshared);
/* Destroy the cond attributes object */
ret = pthread_condattr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
}
/**
* @tc.number : SUB_KERNEL_PTHREAD_OPERATION_016
* @tc.name : event operation for get/set mutex attr
* @tc.desc : [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PthreadFuncTestSuite, testPthread016, Function | MediumTest | Level1)
{
pthread_mutexattr_t mutex_attr;
int mutex_type;
int ret;
pthread_mutexattr_init(&mutex_attr);
ret = pthread_mutexattr_settype(NULL, PTHREAD_MUTEX_ERRORCHECK);
if (ret == 0)
{
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutexattr_gettype(&mutex_attr, &mutex_type);
if (mutex_type != PTHREAD_MUTEX_ERRORCHECK) {
ICUNIT_ASSERT_EQUAL(mutex_type, 0, mutex_type);
}
ret = pthread_mutexattr_gettype(NULL, &mutex_type);
if (ret == 0) {
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
mutex_attr.type = 3;
ret = pthread_mutexattr_gettype(&mutex_attr, &mutex_type);
if (ret == 0) {
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
}
return LOS_OK;
}
RUN_TEST_SUITE(PthreadFuncTestSuite);
......@@ -214,6 +214,33 @@ LITE_TEST_CASE(PosixSemaphoreFuncTestSuite, testIpcSem_Timedwait003, Function |
TEST_ASSERT_EQUAL_INT(errno, EINVAL);
}
/* *
* @tc.number SUB_KERNEL_IPC_SEM_TIMEDWAIT_004
* @tc.name sem_trywait get semaphore success
* @tc.desc [C- SOFTWARE -0200]
*/
LITE_TEST_CASE(PosixSemaphoreFuncTestSuite, testIpcSem_Trywait004, Function | MediumTest | Level3)
{
sem_t sem;
int val;
int ret;
ret = sem_init(&sem, 0, 1);
TEST_ASSERT_EQUAL_INT(0, ret);
ret = sem_trywait(&sem);
TEST_ASSERT_EQUAL_INT(0, ret);
ret = sem_getvalue(&sem, &val);
TEST_ASSERT_EQUAL_INT(0, ret);
if (val <= 0) {
sem_destroy(&sem);
return LOS_OK;
} else {
TEST_ASSERT_EQUAL_INT(0, ret);
}
}
RUN_TEST_SUITE(PosixSemaphoreFuncTestSuite);
......@@ -223,6 +250,7 @@ void PosixSemaphoreFuncTest()
RUN_ONE_TESTCASE(testIpcSem_Timedwait001);
RUN_ONE_TESTCASE(testIpcSem_Timedwait002);
RUN_ONE_TESTCASE(testIpcSem_Timedwait003);
RUN_ONE_TESTCASE(testIpcSem_Trywait004);
return;
}
\ No newline at end of file
......@@ -265,13 +265,13 @@ LITE_TEST_CASE(PosixStdlibStrtolTest, testStdlibStrtol011, Function | MediumTest
char nPtr[] = "12 1.5";
char *endPtr = NULL;
long ret = strtol(nPtr, &endPtr, 65);
if (ret == 67) {
if (ret == 0) {
LOG("[DEMO] posix stdlib test case 11:strtol(base=65) ret:%ld, %s, endPtr:%s ok.\n", ret, endPtr, endPtr);
} else {
LOG("[DEMO] posix stdlib test case 11:strtol(base=65) ret:%ld, %s fail.\n", ret, endPtr);
}
TEST_ASSERT_EQUAL_INT32(67, ret);
TEST_ASSERT_EQUAL_STRING(endPtr, " 1.5");
TEST_ASSERT_EQUAL_INT32(0, ret);
TEST_ASSERT_EQUAL_STRING(endPtr, "12 1.5");
}
LITE_TEST_CASE(PosixStdlibStrtolTest, testStdlibStrtol012, Function | MediumTest | Level1)
......
......@@ -191,13 +191,13 @@ LITE_TEST_CASE(PosixStdlibStrtoulTest, testStdlibStrtoul007, Function | MediumTe
char nPtr[] = " 12.34";
char *endPtr = NULL;
unsigned long ret = strtoul(nPtr, &endPtr, 65);
if (ret == 67UL) {
if (ret == 0UL) {
LOG("[DEMO] posix stdlib test case 7:strtoul(base=65) ret:%lu,%s, endPtr:%s ok.\n", ret, nPtr, endPtr);
} else {
LOG("[DEMO] posix stdlib test case 7:strtoul(base=65) ret:%lu,%s fail.\n", ret, endPtr);
}
TEST_ASSERT_EQUAL_UINT32(67UL, ret);
TEST_ASSERT_EQUAL_STRING(endPtr, ".34");
TEST_ASSERT_EQUAL_UINT32(0UL, ret);
TEST_ASSERT_EQUAL_STRING(endPtr, " 12.34");
}
/* *
......
......@@ -153,13 +153,13 @@ LITE_TEST_CASE(PosixStdlibStrtoullTest, testStdlibStrtoull005, Function | Medium
char nPtr[] = " 1.6";
char *endPtr = NULL;
unsigned long long ret = strtoull(nPtr, &endPtr, 65);
if (ret == 1ULL) {
if (ret == 0ULL) {
LOG("[DEMO] posix stdlib test case 5:strtoull(base=65) ret:%llu,%s, endPtr:%s ok.\n", ret, nPtr, endPtr);
} else {
LOG("[DEMO] posix stdlib test case 5:strtoull(base=65) ret:%llu,%s fail.\n", ret, nPtr);
}
TEST_ASSERT_TRUE(ret == 1ULL);
TEST_ASSERT_EQUAL_STRING(endPtr, ".6");
TEST_ASSERT_TRUE(ret == 0ULL);
TEST_ASSERT_EQUAL_STRING(endPtr, " 1.6");
}
/* *
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册