提交 c3a34f1b 编写于 作者: C Caoruihong

Description: add posix api for liteos_m

Reviewed-by: likailong

Change-Id: I4f83c38d201ce6efe214509958c346aa9e542155
上级 13355bb6
Root directory "//" refers to "/vendor/hisi/hi3861/hi3861".
We use header files from musl ("//platform/os/Huawei_LiteOS/components/lib/libc/musl/include").
Some posix apis are already defined in different places:
errno is defined in //build/libs/libc_base.o
malloc and free are defined in //build/libs/libc_base.o
pthread_mutex_* are defined in //build/libs/hi3861/release/no_mesh/liblitekernel_flash.a
semaphore is defined in //build/libs/hi3861/release/no_mesh/liblitekernel_flash.a
usleep is defined in //build/libs/hi3861/release/no_mesh/liblitekernel_flash.a
clock_* are defined in //build/libs/liblitekernel_base.o
printf is defined in //build/libs/liblitekernel_base.o
fcntl and socket apis are defined in //build/libs/liblwip.a
** DO NOT EDIT FILES HERE **
These header files are copied from musl ("//third_party/musl") except `libc.h'.
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
#ifndef VERSION_H_
#define VERSION_H_
#ifdef __cplusplus
extern "C" {
#endif
const char *libc_get_version_string(void);
int libc_get_version(void);
#ifdef __cplusplus
}
#endif
#endif // VERSION_H_
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
#ifndef LIBC_H_
#define LIBC_H_
#ifdef __cplusplus
extern "C" {
#endif
const char *libc_get_version_string(void);
int libc_get_version(void);
#ifdef __cplusplus
}
#endif
#endif // LIBC_H_
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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 <errno.h>
#include "los_interrupt.h"
#include "los_task.h"
/* the specific errno get or set in interrupt service routine */
static int g_isrErrno;
int *__errno_location(void)
{
LosTaskCB *runTask = NULL;
if (OS_INT_INACTIVE) {
runTask = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
return &runTask->errorNo;
} else {
return &g_isrErrno;
}
}
......@@ -33,21 +33,151 @@
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "lwip/sockets.h"
#include <stdlib.h>
#include <securec.h>
#include "hks_client.h"
#define RANDOM_DEV_FD LWIP_CONFIG_NUM_SOCKETS
#ifdef LOSCFG_NET_LWIP_SACK
#include "lwip/lwipopts.h"
#define CONFIG_NSOCKET_DESCRIPTORS LWIP_CONFIG_NUM_SOCKETS
#else
#define CONFIG_NSOCKET_DESCRIPTORS 0
#endif
#define CONFIG_NFILE_DESCRIPTORS 1 /* only for random currently */
#define RANDOM_DEV_FD CONFIG_NSOCKET_DESCRIPTORS
#define RANDOM_DEV_PATH "/dev/random"
#define FREE_AND_SET_NULL(ptr) do { \
free(ptr); \
ptr = NULL; \
} while (0)
/**
* @brief Get canonical form of a given path based on cwd(Current working directory).
*
* @param cwd Indicates the current working directory.
* @param path Indicates the path to be canonicalization.
* @param buf Indicates the pointer to the buffer where the result will be return.
* @param bufSize Indicates the size of the buffer.
* @return Returns the length of the canonical path.
*
* @attention if path is an absolute path, cwd is ignored. if cwd if not specified, it is assumed to be root('/').
* if the buffer is not big enough the result will be truncated, but the return value will always be the
* length of the canonical path.
*/
static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, size_t bufSize)
{
if (!path) {
path = "";
}
if (!cwd || path[0] == '/') {
cwd = "";
}
size_t tmpLen = strlen(cwd) + strlen(path) + 4; // three '/' and one '\0'
char *tmpBuf = (char *)malloc(tmpLen);
if (tmpBuf == NULL) {
return 0;
}
if (-1 == sprintf_s(tmpBuf, tmpLen, "/%s/%s/", cwd, path)) {
free(tmpBuf);
return 0;
}
char *p;
/* replace /./ to / */
while ((p = strstr(tmpBuf, "/./")) != NULL) {
if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + 2, tmpLen - (p - tmpBuf) - 2)) {
free(tmpBuf);
return 0;
}
}
/* replace // to / */
while ((p = strstr(tmpBuf, "//")) != NULL) {
if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + 1, tmpLen - (p - tmpBuf) - 1)) {
free(tmpBuf);
return 0;
}
}
/* handle /../ (e.g., replace /aa/bb/../ to /aa/) */
while ((p = strstr(tmpBuf, "/../")) != NULL) {
char *start = p;
while (start > tmpBuf && *--start != '/') {
}
if (EOK != memmove_s(start, tmpLen - (start - tmpBuf), p + 3, tmpLen - (p - tmpBuf) - 3)) {
free(tmpBuf);
return 0;
}
}
size_t totalLen = strlen(tmpBuf);
/* strip the last / */
if (totalLen > 1 && tmpBuf[totalLen - 1] == '/') {
tmpBuf[--totalLen] = 0;
}
if (!buf || bufSize == 0) {
free(tmpBuf);
return totalLen;
}
if (EOK != memcpy_s(buf, bufSize, tmpBuf, (totalLen + 1 > bufSize) ? bufSize : totalLen + 1)) {
free(tmpBuf);
return 0;
}
buf[bufSize - 1] = 0;
free(tmpBuf);
return totalLen;
}
int open(const char *file, int oflag, ...)
{
if (strcmp(file, RANDOM_DEV_PATH) == 0) {
if (oflag != O_RDONLY) {
errno = EINVAL;
unsigned flags = O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_LARGEFILE | O_TRUNC | O_EXCL | O_DIRECTORY;
if ((unsigned)oflag & ~flags) {
errno = EINVAL;
return -1;
}
size_t pathLen = strlen(file) + 1;
char *canonicalPath = (char *)malloc(pathLen);
if (!canonicalPath) {
errno = ENOMEM;
return -1;
}
if (GetCanonicalPath(NULL, file, canonicalPath, pathLen) == 0) {
FREE_AND_SET_NULL(canonicalPath);
errno = ENOMEM;
return -1;
}
if (strcmp(canonicalPath, RANDOM_DEV_PATH) == 0) {
FREE_AND_SET_NULL(canonicalPath);
if ((O_ACCMODE & (unsigned)oflag) != O_RDONLY) {
errno = EPERM;
return -1;
}
if ((unsigned)oflag & O_DIRECTORY) {
errno = ENOTDIR;
return -1;
}
return RANDOM_DEV_FD;
}
if (strcmp(canonicalPath, "/") == 0 || strcmp(canonicalPath, "/dev") == 0) {
FREE_AND_SET_NULL(canonicalPath);
if ((unsigned)oflag & O_DIRECTORY) {
errno = EPERM;
return -1;
}
errno = EISDIR;
return -1;
}
FREE_AND_SET_NULL(canonicalPath);
errno = ENOENT;
return -1;
}
......@@ -57,7 +187,13 @@ int close(int fd)
if (fd == RANDOM_DEV_FD) {
return 0;
}
return closesocket(fd);
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return closesocket(fd);
}
#endif
errno = EBADF;
return -1;
}
ssize_t read(int fd, void *buf, size_t nbytes)
......@@ -80,7 +216,13 @@ ssize_t read(int fd, void *buf, size_t nbytes)
}
return (ssize_t)nbytes;
}
return recv(fd, buf, nbytes, 0);
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return recv(fd, buf, nbytes, 0);
}
#endif
errno = EBADF;
return -1;
}
ssize_t write(int fd, const void *buf, size_t nbytes)
......@@ -89,5 +231,11 @@ ssize_t write(int fd, const void *buf, size_t nbytes)
errno = EBADF; /* "/dev/random" is readonly */
return -1;
}
return send(fd, buf, nbytes, 0);
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return send(fd, buf, nbytes, 0);
}
#endif
errno = EBADF;
return -1;
}
......@@ -29,7 +29,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <version.h>
#include <libc.h>
#include "libc_config.h"
/**
* get libc version string.
......
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
#ifndef LIBC_CONFIG_H_
#define LIBC_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef LIBC_VERSION_STR
#define LIBC_VERSION_STR "1.0.0-LiteOS_M"
#endif
#ifndef LIBC_VERSION_NUM
#define LIBC_VERSION_NUM 0x00010000
#endif
#ifdef __cplusplus
}
#endif
#endif // LIBC_CONFIG_H_
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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 "securec.h"
#include "los_config.h"
#include "los_memory.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cpluscplus */
#endif /* __cpluscplus */
void *calloc(size_t nitems, size_t size)
{
size_t real_size;
void *ptr = NULL;
if (nitems == 0 || size == 0) {
return NULL;
}
real_size = (size_t)(nitems * size);
ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, real_size);
if (ptr != NULL) {
(void)memset_s(ptr, real_size, 0, real_size);
}
return ptr;
}
void free(void *ptr)
{
if (ptr == NULL) {
return;
}
LOS_MemFree(OS_SYS_MEM_ADDR, ptr);
}
void *malloc(size_t size)
{
if (size == 0) {
return NULL;
}
return LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
}
void *zalloc(size_t size)
{
void *ptr = NULL;
if (size == 0) {
return NULL;
}
ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
if (ptr != NULL) {
(void)memset_s(ptr, size, 0, size);
}
return ptr;
}
void *memalign(size_t boundary, size_t size)
{
if (size == 0) {
return NULL;
}
return LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, boundary);
}
void *realloc(void *ptr, size_t size)
{
if (ptr == NULL) {
return malloc(size);
}
if (size == 0) {
free(ptr);
return NULL;
}
return LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size);
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */
......@@ -29,43 +29,42 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pthread_impl.h"
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <securec.h>
#include "los_config.h"
#include "los_task.h"
#include "los_task_pri.h"
#define PTHREAD_NAMELEN 16
/* this is just an assertion: LOS_TASK_ARG_NUM >= 4 */
typedef char NULNAM[-!((LOS_TASK_ARG_NUM * 4) >= PTHREAD_NAMELEN)];
typedef struct {
void *(*startRoutine)(void *);
void *param;
char name[PTHREAD_NAMELEN];
}PthreadData;
static void *_pthread_entry(UINT32 param1, UINT32 param2, UINT32 param3, UINT32 param4)
static void *PthreadEntry(UINT32 param)
{
void *(*startRoutine)(void *) = (void *)(UINTPTR)param1;
void *param = (void *)(UINTPTR)param2;
(void)param3;
(void)param4;
int ret;
LosTaskCB *tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
char *tmp = tcb->taskName;
tcb->taskName = (char *)tcb->args; /* args are reused as task name */
ret = strcpy_s(tcb->taskName, PTHREAD_NAMELEN, tmp);
if (ret != 0) {
free(tmp);
return NULL;
}
free(tmp);
PthreadData *pthreadData = (PthreadData *)(UINTPTR)param;
void *(*startRoutine)(void *) = pthreadData->startRoutine;
void *ret = startRoutine(pthreadData->param);
free(pthreadData);
return ret;
}
return startRoutine(param);
static inline int IsPthread(pthread_t thread)
{
return ((UINT32)thread <= LOSCFG_BASE_CORE_TSK_LIMIT) &&
(OS_TCB_FROM_TID((UINT32)thread)->taskEntry == PthreadEntry);
}
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*startRoutine)(void *), void *arg)
{
TSK_INIT_PARAM_S taskInitParam = {0};
PthreadData *pthreadData = NULL;
UINT32 taskID;
if ((thread == NULL) || (startRoutine == NULL)) {
......@@ -87,17 +86,17 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
taskInitParam.usTaskPrio = (UINT16)attr->schedparam.sched_priority;
}
taskInitParam.pcName = malloc(PTHREAD_NAMELEN);
if (taskInitParam.pcName == NULL) {
pthreadData = (PthreadData *)malloc(sizeof(PthreadData));
if (pthreadData == NULL) {
return ENOMEM;
}
taskInitParam.pfnTaskEntry = _pthread_entry;
taskInitParam.auwArgs[0] = (UINT32)(UINTPTR)startRoutine;
taskInitParam.auwArgs[1] = (UINT32)(UINTPTR)arg;
taskInitParam.pcName = pthreadData->name;
taskInitParam.pfnTaskEntry = PthreadEntry;
taskInitParam.uwArg = (UINT32)(UINTPTR)pthreadData;
if (LOS_TaskCreate(&taskID, &taskInitParam) != LOS_OK) {
free(taskInitParam.pcName);
free(pthreadData);
return EINVAL;
}
......@@ -105,12 +104,13 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
(void)sprintf_s(taskInitParam.pcName, PTHREAD_NAMELEN, "pthread%u", taskID);
*thread = (pthread_t)taskID;
return ENOERR;
return 0;
}
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param)
{
if ((param == NULL) || (param->sched_priority > OS_TASK_PRIORITY_LOWEST)) {
if ((param == NULL) || (param->sched_priority < OS_TASK_PRIORITY_HIGHEST) ||
(param->sched_priority >= OS_TASK_PRIORITY_LOWEST) || !IsPthread(thread)) {
return EINVAL;
}
......@@ -123,14 +123,14 @@ int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param
return EINVAL;
}
return ENOERR;
return 0;
}
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
{
UINT32 prio;
if ((policy == NULL) || (param == NULL)) {
if ((policy == NULL) || (param == NULL) || !IsPthread(thread)) {
return EINVAL;
}
......@@ -141,7 +141,7 @@ int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *par
*policy = SCHED_RR;
param->sched_priority = prio;
return ENOERR;
return 0;
}
pthread_t pthread_self(void)
......@@ -151,36 +151,21 @@ pthread_t pthread_self(void)
int pthread_cancel(pthread_t thread)
{
(void)thread;
return ENOSYS;
}
static void *void_task(UINT32 param1, UINT32 param2, UINT32 param3, UINT32 param4)
{
(void)param1;
(void)param2;
(void)param3;
(void)param4;
return 0;
}
static void cleanup_task_resource(void)
{
TSK_INIT_PARAM_S taskInitParam = {0};
UINT32 taskID;
taskInitParam.pcName = "void";
taskInitParam.pfnTaskEntry = void_task;
taskInitParam.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE;
if (!IsPthread(thread)) {
return EINVAL;
}
(void)LOS_TaskCreate(&taskID, &taskInitParam);
return ENOSYS;
}
int pthread_join(pthread_t thread, void **retval)
{
UINT32 taskStatus;
if (!IsPthread(thread)) {
return EINVAL;
}
if (retval) {
/* retrieve thread exit code is not supported currently */
return ENOTSUP;
......@@ -194,26 +179,30 @@ int pthread_join(pthread_t thread, void **retval)
usleep(10000);
}
cleanup_task_resource();
return 0;
}
int pthread_detach(pthread_t thread)
{
(void)thread;
if (!IsPthread(thread)) {
return EINVAL;
}
return ENOSYS;
}
void pthread_exit(void *retVal)
{
(void)retVal;
LosTaskCB *tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
free((PthreadData *)(UINTPTR)tcb->arg);
(void)LOS_TaskDelete(LOS_CurTaskIDGet());
}
int pthread_setname_np(pthread_t thread, const char *name)
{
char *taskName = LOS_TaskNameGet((UINT32)thread);
if (taskName == NULL) {
if (taskName == NULL || !IsPthread(thread)) {
return EINVAL;
}
if (strnlen(name, PTHREAD_NAMELEN) >= PTHREAD_NAMELEN) {
......@@ -228,7 +217,7 @@ int pthread_getname_np(pthread_t thread, char *buf, size_t buflen)
int ret;
const char *name = LOS_TaskNameGet((UINT32)thread);
if (name == NULL) {
if (name == NULL || !IsPthread(thread)) {
return EINVAL;
}
if (buflen > strlen(name)) {
......
......@@ -29,11 +29,10 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pthread_impl.h"
#include <errno.h>
#include <pthread.h>
#define PTHREAD_STACK_MIN LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE
#include <limits.h>
#include "los_config.h"
int pthread_attr_init(pthread_attr_t *attr)
{
......@@ -51,7 +50,7 @@ int pthread_attr_init(pthread_attr_t *attr)
attr->stacksize_set = 1;
attr->stacksize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
return ENOERR;
return 0;
}
int pthread_attr_destroy(pthread_attr_t *attr)
......@@ -61,14 +60,14 @@ int pthread_attr_destroy(pthread_attr_t *attr)
}
/* Nothing to do here... */
return ENOERR;
return 0;
}
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachState)
{
if ((attr != NULL) && ((detachState == PTHREAD_CREATE_JOINABLE) || (detachState == PTHREAD_CREATE_DETACHED))) {
attr->detachstate = (UINT32)detachState;
return ENOERR;
return 0;
}
return EINVAL;
......@@ -82,7 +81,7 @@ int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachState)
*detachState = (int)attr->detachstate;
return ENOERR;
return 0;
}
int pthread_attr_setscope(pthread_attr_t *attr, int scope)
......@@ -93,7 +92,7 @@ int pthread_attr_setscope(pthread_attr_t *attr, int scope)
if (scope == PTHREAD_SCOPE_PROCESS) {
attr->scope = (unsigned int)scope;
return ENOERR;
return 0;
}
if (scope == PTHREAD_SCOPE_SYSTEM) {
......@@ -111,14 +110,14 @@ int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
*scope = (int)attr->scope;
return ENOERR;
return 0;
}
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
{
if ((attr != NULL) && ((inherit == PTHREAD_INHERIT_SCHED) || (inherit == PTHREAD_EXPLICIT_SCHED))) {
attr->inheritsched = (UINT32)inherit;
return ENOERR;
return 0;
}
return EINVAL;
......@@ -132,14 +131,14 @@ int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
*inherit = (int)attr->inheritsched;
return ENOERR;
return 0;
}
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
{
if ((attr != NULL) && (policy == SCHED_RR)) {
attr->schedpolicy = SCHED_RR;
return ENOERR;
return 0;
}
return EINVAL;
......@@ -153,20 +152,21 @@ int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
*policy = (int)attr->schedpolicy;
return ENOERR;
return 0;
}
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
{
if ((attr == NULL) || (param == NULL)) {
return EINVAL;
} else if ((param->sched_priority < 0) || (param->sched_priority > OS_TASK_PRIORITY_LOWEST)) {
} else if ((param->sched_priority < LOS_TASK_PRIORITY_HIGHEST) ||
(param->sched_priority >= LOS_TASK_PRIORITY_LOWEST)) {
return ENOTSUP;
}
attr->schedparam = *param;
return ENOERR;
return 0;
}
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
......@@ -177,7 +177,7 @@ int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *p
*param = attr->schedparam;
return ENOERR;
return 0;
}
/*
......@@ -194,14 +194,14 @@ int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackAddr)
attr->stackaddr_set = 1;
attr->stackaddr = stackAddr;
return ENOERR;
return 0;
}
int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackAddr)
{
if (((attr != NULL) && (stackAddr != NULL)) && attr->stackaddr_set) {
*stackAddr = attr->stackaddr;
return ENOERR;
return 0;
}
return EINVAL; /* Stack address not set, return EINVAL. */
......@@ -217,7 +217,7 @@ int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stackSize)
attr->stacksize_set = 1;
attr->stacksize = stackSize;
return ENOERR;
return 0;
}
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
......@@ -229,5 +229,5 @@ int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
*stackSize = attr->stacksize;
return ENOERR;
return 0;
}
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
#ifndef PTHREAD_IMPL_H_
#define PTHREAD_IMPL_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct __pthread_attr_s pthread_attr_t;
#define __DEFINED_pthread_attr_t
#ifdef __cplusplus
}
#endif
#include <pthread.h>
#include <sched.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct __pthread_attr_s {
unsigned int detachstate;
unsigned int schedpolicy;
struct sched_param schedparam;
unsigned int inheritsched;
unsigned int scope;
unsigned int stackaddr_set;
void* stackaddr;
unsigned int stacksize_set;
size_t stacksize;
} pthread_attr_t;
#ifdef __cplusplus
}
#endif
#endif // PTHREAD_IMPL_H_
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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>
#include <time.h>
#include "los_compiler.h"
#include "los_mux.h"
#include "errno.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_SYS_NS_PER_MSECOND 1000000
#define OS_SYS_NS_PER_SECOND 1000000000
static inline int MapError(UINT32 err)
{
switch (err) {
case LOS_OK:
return 0;
case LOS_ERRNO_MUX_PEND_INTERR:
return EPERM;
case LOS_ERRNO_MUX_PEND_IN_LOCK:
return EDEADLK;
case LOS_ERRNO_MUX_PENDED:
case LOS_ERRNO_MUX_UNAVAILABLE:
return EBUSY;
case LOS_ERRNO_MUX_TIMEOUT:
return ETIMEDOUT;
case LOS_ERRNO_MUX_ALL_BUSY:
return EAGAIN;
case LOS_ERRNO_MUX_INVALID:
default:
return EINVAL;
}
}
/* Initialize mutex. If mutexAttr is NULL, use default attributes. */
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr)
{
UINT32 muxHandle;
UINT32 ret;
if (mutexAttr != NULL) {
return EOPNOTSUPP;
}
ret = LOS_MuxCreate(&muxHandle);
if (ret != LOS_OK) {
return MapError(ret);
}
mutex->magic = _MUX_MAGIC;
mutex->handle = muxHandle;
return 0;
}
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
ret = LOS_MuxDelete(mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
mutex->handle = _MUX_INVALID_HANDLE;
return 0;
}
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)) {
return EINVAL;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
}
ret = clock_gettime(CLOCK_REALTIME, &curTime);
if (ret != LOS_OK) {
return EINVAL;
}
timeoutNs = (absTimeout->tv_sec - curTime.tv_sec) * OS_SYS_NS_PER_SECOND + (absTimeout->tv_nsec - curTime.tv_nsec);
if (timeoutNs <= 0) {
return ETIMEDOUT;
}
timeout = (timeoutNs + (OS_SYS_NS_PER_MSECOND - 1)) / OS_SYS_NS_PER_MSECOND;
ret = LOS_MuxPend(mutex->handle, timeout);
return MapError(ret);
}
/* Lock mutex, waiting for it if necessary. */
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
}
ret = LOS_MuxPend(mutex->handle, LOS_WAIT_FOREVER);
return MapError(ret);
}
int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
}
ret = LOS_MuxPend(mutex->handle, 0);
return MapError(ret);
}
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
ret = LOS_MuxPost(mutex->handle);
return MapError(ret);
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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 <semaphore.h>
#include <errno.h>
#include "los_sem.h"
#define _SEM_MAGIC 0xEBCFDEA1
#define s_magic __val[0]
#define s_handle __val[1]
static inline int MapError(UINT32 err)
{
switch (err) {
case LOS_OK:
return 0;
case LOS_ERRNO_SEM_INVALID:
case LOS_ERRNO_SEM_UNAVAILABLE:
return EINVAL;
case LOS_ERRNO_SEM_ALL_BUSY:
return ENOSPC;
case LOS_ERRNO_SEM_OVERFLOW:
return ENOMEM;
case LOS_ERRNO_SEM_PENDED:
return EBUSY;
case LOS_ERRNO_SEM_PEND_IN_LOCK:
return EPERM;
case LOS_ERRNO_SEM_PEND_INTERR:
return EINTR;
case LOS_ERRNO_SEM_TIMEOUT:
return ETIMEDOUT;
default:
return EINVAL;
}
}
int sem_init(sem_t *sem, int shared, unsigned int value)
{
UINT32 semHandle = 0;
UINT32 ret;
(VOID)shared;
if ((sem == NULL) || (value >= OS_SEM_COUNTING_MAX_COUNT)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemCreate(value, &semHandle);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
sem->s_magic = _SEM_MAGIC;
sem->s_handle = (int)semHandle;
return 0;
}
int sem_destroy(sem_t *sem)
{
UINT32 ret;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemDelete((UINT32)sem->s_handle);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
return 0;
}
int sem_wait(sem_t *sem)
{
UINT32 ret;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemPend((UINT32)sem->s_handle, LOS_WAIT_FOREVER);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
return 0;
}
int sem_post(sem_t *sem)
{
UINT32 ret;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemPost((UINT32)sem->s_handle);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
return 0;
}
......@@ -29,12 +29,16 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <time.h>
#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <los_swtmr.h>
#include <los_swtmr_pri.h>
#include "los_debug.h"
#include "los_task.h"
#include "los_swtmr.h"
#include "los_timer.h"
#include "los_context.h"
#ifndef STATIC
#define STATIC static
......@@ -45,11 +49,8 @@
#define OS_SYS_US_PER_SECOND 1000000
#define OS_SYS_MS_PER_SECOND 1000
STATIC INLINE BOOL ValidTimerID(UINT16 swtmrID)
{
/* check timer id */
return (swtmrID < LOSCFG_BASE_CORE_SWTMR_LIMIT);
}
/* accumulative time delta from discontinuous modify */
STATIC struct timespec g_accDeltaFromSet;
/* internal functions */
STATIC INLINE BOOL ValidTimeSpec(const struct timespec *tp)
......@@ -87,19 +88,38 @@ STATIC INLINE VOID OsTick2TimeSpec(struct timespec *tp, UINT32 tick)
tp->tv_nsec = (long)(ns % OS_SYS_NS_PER_SECOND);
}
int nanosleep(const struct timespec *req, struct timespec *rem)
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
UINT64 us = (UINT64)req->tv_sec * OS_SYS_US_PER_SECOND + (req->tv_nsec + OS_SYS_NS_PER_US - 1) / OS_SYS_NS_PER_US;
if (us > 0xFFFFFFFFU) {
UINT64 nseconds;
UINT64 tick;
UINT32 ret;
const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
if (!ValidTimeSpec(rqtp)) {
errno = EINVAL;
return -1;
}
nseconds = (UINT64)rqtp->tv_sec * OS_SYS_NS_PER_SECOND + rqtp->tv_nsec;
tick = (nseconds + nsPerTick - 1) / nsPerTick; // Round up for ticks
if (tick >= UINT32_MAX) {
errno = EINVAL;
return -1;
}
if (usleep(us) == 0) {
if (rem) {
rem->tv_sec = rem->tv_nsec = 0;
/* PS: skip the first tick because it is NOT a full tick. */
ret = LOS_TaskDelay(tick ? (UINT32)(tick + 1) : 0);
if (ret == LOS_OK || ret == LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK) {
if (rmtp) {
rmtp->tv_sec = rmtp->tv_nsec = 0;
}
return 0;
}
/* sleep in interrupt context or in task sched lock state */
errno = EPERM;
return -1;
}
......@@ -119,7 +139,11 @@ int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *rest
}
ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)evp->sigev_notify_function,
&swtmrID, (UINT32)(UINTPTR)evp->sigev_value.sival_ptr);
&swtmrID, (UINT32)(UINTPTR)evp->sigev_value.sival_ptr
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
, OS_SWTMR_ROUSES_IGNORE, OS_SWTMR_ALIGN_INSENSITIVE
#endif
);
if (ret != LOS_OK) {
errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL;
return -1;
......@@ -132,12 +156,6 @@ int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *rest
int timer_delete(timer_t timerID)
{
UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
if (!ValidTimerID(swtmrID)) {
errno = EINVAL;
return -1;
}
if (LOS_SwtmrDelete(swtmrID) != LOS_OK) {
errno = EINVAL;
return -1;
......@@ -150,6 +168,7 @@ int timer_settime(timer_t timerID, int flags,
const struct itimerspec *restrict value,
struct itimerspec *restrict oldValue)
{
UINTPTR intSave;
UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
SWTMR_CTRL_S *swtmr = NULL;
UINT32 interval, expiry, ret;
......@@ -160,7 +179,7 @@ int timer_settime(timer_t timerID, int flags,
return -1;
}
if (value == NULL || !ValidTimerID(swtmrID)) {
if (value == NULL) {
errno = EINVAL;
return -1;
}
......@@ -189,13 +208,11 @@ int timer_settime(timer_t timerID, int flags,
return -1;
}
intSave = LOS_IntLock();
swtmr = OS_SWT_FROM_SID(swtmrID);
ret = LOS_SwtmrModify(swtmrID, expiry, (interval ? LOS_SWTMR_MODE_PERIOD : LOS_SWTMR_MODE_NO_SELFDELETE),
swtmr->pfnHandler, swtmr->uwArg);
if (ret != LOS_OK) {
errno = EINVAL;
return -1;
}
swtmr->ucMode = (interval ? LOS_SWTMR_MODE_PERIOD : LOS_SWTMR_MODE_NO_SELFDELETE);
swtmr->uwInterval = interval;
LOS_IntRestore(intSave);
if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) {
/*
......@@ -221,7 +238,7 @@ int timer_gettime(timer_t timerID, struct itimerspec *value)
UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
UINT32 ret;
if ((value == NULL) || !ValidTimerID(swtmrID)) {
if (value == NULL) {
errno = EINVAL;
return -1;
}
......@@ -242,13 +259,168 @@ int timer_gettime(timer_t timerID, struct itimerspec *value)
int timer_getoverrun(timer_t timerID)
{
UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
(void)timerID;
errno = ENOSYS;
return -1;
}
STATIC VOID OsGetHwTime(struct timespec *hwTime)
{
UINT64 nowNsec;
UINT32 countHigh = 0;
UINT32 countLow = 0;
HalGetCpuCycle(&countHigh, &countLow);
nowNsec = (((UINT64)countHigh * OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK) << 32) +
((((UINT64)countHigh * OS_SYS_NS_PER_SECOND % OS_SYS_CLOCK) << 32) / OS_SYS_CLOCK) +
((UINT64)countLow * OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK);
hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND;
hwTime->tv_nsec = nowNsec % OS_SYS_NS_PER_SECOND;
}
if (!ValidTimerID(swtmrID)) {
STATIC VOID OsGetRealTime(struct timespec *realTime)
{
UINTPTR intSave;
struct timespec hwTime = {0};
OsGetHwTime(&hwTime);
intSave = LOS_IntLock();
realTime->tv_nsec = hwTime.tv_nsec + g_accDeltaFromSet.tv_nsec;
realTime->tv_sec = hwTime.tv_sec + g_accDeltaFromSet.tv_sec + (realTime->tv_nsec >= OS_SYS_NS_PER_SECOND);
realTime->tv_nsec %= OS_SYS_NS_PER_SECOND;
LOS_IntRestore(intSave);
}
STATIC VOID OsSetRealTime(const struct timespec *realTime)
{
UINTPTR intSave;
struct timespec hwTime = {0};
OsGetHwTime(&hwTime);
intSave = LOS_IntLock();
g_accDeltaFromSet.tv_nsec = realTime->tv_nsec - hwTime.tv_nsec;
g_accDeltaFromSet.tv_sec = realTime->tv_sec - hwTime.tv_sec - (g_accDeltaFromSet.tv_nsec < 0);
g_accDeltaFromSet.tv_nsec = (g_accDeltaFromSet.tv_nsec + OS_SYS_NS_PER_SECOND) % OS_SYS_NS_PER_SECOND;
LOS_IntRestore(intSave);
}
int clock_settime(clockid_t clockID, const struct timespec *tp)
{
if (!ValidTimeSpec(tp)) {
errno = EINVAL;
return -1;
}
errno = ENOSYS;
return -1;
switch (clockID) {
case CLOCK_REALTIME:
/* we only support the realtime clock currently */
OsSetRealTime(tp);
return 0;
case CLOCK_MONOTONIC_COARSE:
case CLOCK_REALTIME_COARSE:
case CLOCK_MONOTONIC_RAW:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
case CLOCK_THREAD_CPUTIME_ID:
errno = ENOTSUP;
return -1;
case CLOCK_MONOTONIC:
default:
errno = EINVAL;
return -1;
}
}
int clock_gettime(clockid_t clockID, struct timespec *tp)
{
if (tp == NULL) {
errno = EINVAL;
return -1;
}
switch (clockID) {
case CLOCK_MONOTONIC_RAW:
case CLOCK_MONOTONIC:
case CLOCK_MONOTONIC_COARSE:
OsGetHwTime(tp);
return 0;
case CLOCK_REALTIME:
case CLOCK_REALTIME_COARSE:
OsGetRealTime(tp);
return 0;
case CLOCK_THREAD_CPUTIME_ID:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
errno = ENOTSUP;
return -1;
default:
errno = EINVAL;
return -1;
}
}
int clock_getres(clockid_t clockID, struct timespec *tp)
{
if (tp == NULL) {
errno = EINVAL;
return -1;
}
switch (clockID) {
case CLOCK_MONOTONIC_RAW:
case CLOCK_MONOTONIC:
case CLOCK_REALTIME:
case CLOCK_MONOTONIC_COARSE:
case CLOCK_REALTIME_COARSE:
tp->tv_nsec = OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK;
tp->tv_sec = 0;
return 0;
case CLOCK_THREAD_CPUTIME_ID:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
errno = ENOTSUP;
return -1;
default:
errno = EINVAL;
return -1;
}
}
int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
{
switch (clk) {
case CLOCK_REALTIME:
if (flags == 0) {
/* we only support the realtime clock currently */
return nanosleep(req, rem);
}
/* fallthrough */
case CLOCK_MONOTONIC_COARSE:
case CLOCK_REALTIME_COARSE:
case CLOCK_MONOTONIC_RAW:
case CLOCK_MONOTONIC:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
if (flags == 0 || flags == TIMER_ABSTIME) {
return ENOTSUP;
}
/* fallthrough */
case CLOCK_THREAD_CPUTIME_ID:
default:
return EINVAL;
}
}
......@@ -1611,6 +1611,7 @@ typedef struct {
UINT32 eventMask; /**< Event mask */
UINT32 eventMode; /**< Event mode */
VOID *msg; /**< Memory allocated to queues */
INT32 errorNo;
} LosTaskCB;
typedef struct {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册